dimple.js: filter data, but not legend

2019-09-18 20:13发布

问题:

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}] 

回答1:

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.



标签: dimple.js