I'm trying to draw a chart with a series added, and an interactive legend, but I want the chart to load with data filtered down to only one option in the legend. This would look like this but with only one option selected in the legend at load time. Once the chart is drawn I have modified the legend logic to toggle between datasets like radio buttons. Here is the code drawing the chart:
var data = $rootScope._diskUtilization[$scope.myOption];
var svg = dimple.newSvg("#disk-utilization-chart-container", 1000, 500);
var chart = new dimple.chart(svg, data);
chart.setMargins(65,10,80,65);
var x = chart.addCategoryAxis("x", ["x", "opCode"]);
var y = chart.addMeasureAxis("y", "y");
y.tickFormat = "%";
var opCodes = chart.addSeries("opCode", dimple.plot.bar);
var myLegend = chart.addLegend(940, 5, 60, 100, "Right");
if (data[0] != null){
chart.draw();
} else {
alert("no data for this chart on this disk");
}
var cleanAxis = function (axis, oneInEvery) {
// This should have been called after draw, otherwise do nothing
if (axis.shapes.length > 0) {
// Leave the first label
var del = false;
// If there is an interval set
if (oneInEvery > 1) {
// Operate on all the axis text
axis.shapes.selectAll("text")
.each(function (d) {
// Remove all but the nth label
if (del % oneInEvery !== 0) {
this.remove();
// Find the corresponding tick line and remove
axis.shapes.selectAll("line").each(function (d2) {
if (d === d2) {
this.remove();
}
});
}
del += 1;
});
}
}
};
cleanAxis(x, 2);
x.titleShape.text("Trace Time (seconds)");
y.titleShape.text("Utilization (%)");
chart.legends = [];
var filterValues = dimple.getUniqueValues(data, "opCode");
chart.data = dimple.filterData(data, "opCode", filterValues[0]);
myLegend.shapes.selectAll("rect").style("opacity", 0.2);
d3.select("rect.dimple-legend.dimple-legend-key.dimple-"+filterValues[0].toLowerCase()).style("opacity", 0.8);
for(i=1;i<filterValues;i++){
d3.select("rect.dimple-legend.dimple-legend-key.dimple-"+filterValues[i].toLowerCase()).style("opacity", 0.2);
}
var newFilters = filterValues[0];
myLegend.shapes.selectAll("rect")
.on("click", function (e) {
// loop through all opCodes for this chart on this disk
filterValues.forEach(function (f) {
// if this is the clicked opCode raise opacity and filter on this value
if (f === e.aggField.slice(-1)[0]) {
newFilters = f;
d3.select("rect.dimple-legend.dimple-legend-key.dimple-"+f.toLowerCase()).style("opacity", 0.8);
// for all other opCodes lower the opacity of the legend-rect
} else {
d3.select("rect.dimple-legend.dimple-legend-key.dimple-"+f.toLowerCase()).style("opacity", 0.2);
}
});
// Filter the data
chart.data = dimple.filterData(data, "opCode", newFilters);
// Passing a duration parameter makes the chart animate. Without
// it there is no transition
chart.draw(1000);
// rebuild the axis labels every time you redraw a chart
x.titleShape.text("Trace Time (seconds)");
y.titleShape.text("Utilization (%)");
});
I've tried sticking in a filter on the data before drawing the chart, but then the legend is also filtered, and I lose the other options. Here's what I tried sticking in there:
chart.data = dimple.filterData(data, "opCode", filterValues[0]);
Thanks in advance for your help. And thanks again to John Kiernander for building such an awesome project.
For clarity, here is a reduced sample dataset:
[{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":0,"y":0.0556},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":133,"y":0.0043},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":265,"y":0.0057},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":4245,"y":0.0014},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":4377,"y":0.0013},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":6897,"y":0.0258},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":13131,"y":0.0036},
{"disk":0,"chartName":"Disk Utilization","opCode":"Read","x":13131,"y":0.0189},
{"disk":0,"chartName":"Disk Utilization","opCode":"Write","x":1592,"y":0.0565},
{"disk":0,"chartName":"Disk Utilization","opCode":"Write","x":3183,"y":0.0249},
{"disk":0,"chartName":"Disk Utilization","opCode":"Write","x":3316,"y":0.0049},
{"disk":0,"chartName":"Disk Utilization","opCode":"Write","x":12999,"y":0.0041},
{"disk":0,"chartName":"Disk Utilization","opCode":"Write","x":13131,"y":0.0043},
{"disk":0,"chartName":"Disk Utilization","opCode":"Write","x":13131,"y":0.0253},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":0,"y":0.0762},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":133,"y":0.0131},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":265,"y":0.0211},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":1592,"y":0.187},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":1724,"y":0.0607},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":1857,"y":0.022},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":11540,"y":0.1017},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":13131,"y":0.0078},
{"disk":0,"chartName":"Disk Utilization","opCode":"Readwrite","x":13131,"y":0.0593}]
I can't quite unpick your code to understand what's going wrong. Have you looked at this example:
http://dimplejs.org/advanced_examples_viewer.html?id=advanced_interactive_legends
There are comments to explain why everything is there. The key to avoiding the legend redrawing is the line
chart.legends = []
which I see you have, so I'm not sure if program flow is the problem.