I've created a version of the dimple interactive chart (see dimplejs.org/advanced_examples_viewer.html?id=advanced_interactive_legends) with two series: one pie series and one line series based on the same dataset.
jsfiddle: http://jsfiddle.net/jose_jimenez/1fvjvyvh/3/
var svg = dimple.newSvg("#chartContainer", 700, 500);
var mainSlicer = "classification";
var pies;
var lines;
//data here look for ------END OF DATA --------
var data = [{
"classification": "Undergraduate",
"residency": "Resident",
"year": 2006,
"head count": 14011
}, {
"classification": "Undergraduate",
"residency": "Domestic",
"year": 2006,
"head count": 6347
}, {
"classification": "Undergraduate",
"residency": "International",
"year": 2006,
"head count": 380
}, {
"classification": "Graduate",
"residency": "Resident",
"year": 2006,
"head count": 2693
}, {
"classification": "Graduate",
"residency": "Domestic",
"year": 2006,
"head count": 2075
}, {
"classification": "Graduate",
"residency": "International",
"year": 2006,
"head count": 1309
}, {
"classification": "Professional",
"residency": "Resident",
"year": 2006,
"head count": 1374
}, {
"classification": "Professional",
"residency": "Domestic",
"year": 2006,
"head count": 612
}, {
"classification": "Professional",
"residency": "International",
"year": 2006,
"head count": 14
}, {
"classification": "Postgraduate",
"residency": "Resident",
"year": 2006,
"head count": 825
}, {
"classification": "Postgraduate",
"residency": "Domestic",
"year": 2006,
"head count": 38
}, {
"classification": "Postgraduate",
"residency": "International",
"year": 2006,
"head count": 301
}, {
"classification": "Undergraduate",
"residency": "Resident",
"year": 2007,
"head count": 13808
}, {
"classification": "Undergraduate",
"residency": "Domestic",
"year": 2007,
"head count": 6695
}, {
"classification": "Undergraduate",
"residency": "International",
"year": 2007,
"head count": 404
}, {
"classification": "Graduate",
"residency": "Resident",
"year": 2007,
"head count": 2848
}, {
"classification": "Graduate",
"residency": "Domestic",
"year": 2007,
"head count": 2127
}, {
"classification": "Graduate",
"residency": "International",
"year": 2007,
"head count": 1246
}, {
"classification": "Professional",
"residency": "Resident",
"year": 2007,
"head count": 1338
}, {
"classification": "Professional",
"residency": "Domestic",
"year": 2007,
"head count": 642
}, {
"classification": "Professional",
"residency": "International",
"year": 2007,
"head count": 16
}, {
"classification": "Postgraduate",
"residency": "Resident",
"year": 2007,
"head count": 930
}, {
"classification": "Postgraduate",
"residency": "Domestic",
"year": 2007,
"head count": 53
}, {
"classification": "Postgraduate",
"residency": "International",
"year": 2007,
"head count": 302
}, {
"classification": "Undergraduate",
"residency": "Resident",
"year": 2008,
"head count": 13192
}, {
"classification": "Undergraduate",
"residency": "Domestic",
"year": 2008,
"head count": 7055
}, {
"classification": "Undergraduate",
"residency": "International",
"year": 2008,
"head count": 576
}, {
"classification": "Graduate",
"residency": "Resident",
"year": 2008,
"head count": 2932
}, {
"classification": "Graduate",
"residency": "Domestic",
"year": 2008,
"head count": 2164
}, {
"classification": "Graduate",
"residency": "International",
"year": 2008,
"head count": 1247
}, {
"classification": "Professional",
"residency": "Resident",
"year": 2008,
"head count": 1288
}, {
"classification": "Professional",
"residency": "Domestic",
"year": 2008,
"head count": 687
}, {
"classification": "Professional",
"residency": "International",
"year": 2008,
"head count": 22
}, {
"classification": "Postgraduate",
"residency": "Resident",
"year": 2008,
"head count": 994
}, {
"classification": "Postgraduate",
"residency": "Domestic",
"year": 2008,
"head count": 58
}, {
"classification": "Postgraduate",
"residency": "International",
"year": 2008,
"head count": 346
}];
// ------END OF DATA --------
function addSeries(chart) {
pies = chart.addSeries(slicer, dimple.plot.pie);
lines = chart.addSeries("classification", dimple.plot.line);
lines.lineMarkers = true;
lines.lineWeight = 5;
pies.radius = 20;
}
function createChart() {
data_attributes = Object.getOwnPropertyNames(data[0]);
['year', 'head count', mainSlicer].forEach(function(f) {
data_attributes.splice(data_attributes.indexOf(f), 1);
});
slicer = data_attributes[0];
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 500, 400)
var x = myChart.addCategoryAxis("x", ["year", mainSlicer]);
x.addOrderRule("year");
myChart.addMeasureAxis("y", "head count");
myChart.addMeasureAxis("p", "head count");
addSeries(myChart);
var myClassificationLegend = myChart.addLegend(550, 200, 150, 400, "left", lines);
var mySlicerLegend = myChart.addLegend(550, 300, 150, 400, "left", pies);
myChart.draw();
myChart.legends = [];
svg.selectAll("title_text")
.data(["Click legend to", "show/hide segments:"])
.enter()
.append("text")
.attr("x", 550)
.attr("y", function(d, i) {
return 160 + i * 14;
})
.style("font-family", "sans-serif")
.style("font-size", "10px")
.style('font-weight', 'bold')
.style("color", "Black")
.text(function(d) {
return d;
});
var classFilterValues = dimple.getUniqueValues(data, mainSlicer);
var slicerFilterValues = dimple.getUniqueValues(data, slicer);
var hiddenValues = [];
legendBits = myClassificationLegend.shapes;
legendBits[0] = legendBits[0]
.concat(mySlicerLegend.shapes[0]);
legendBits.selectAll('rect')
// Add a click event to each rectangle
.on("click", function(e) {
// This indicates whether the item is already visible or not
var hide = false;
var newClassificationFilters = [];
var newSlicerFilters = [];
var currentValue = e.aggField.slice(-1)[0];
// If the filters contain the clicked shape hide it
var whereIsIt = hiddenValues.indexOf(currentValue);
if (whereIsIt > -1) {
//it is hidden and needs to be shown.
hide = false;
hiddenValues.splice(whereIsIt, 1);
} else {
//it needs to be hidden
hide = true;
hiddenValues.push(currentValue);
}
classFilterValues.forEach(function(f) {
if (hiddenValues.indexOf(f) < 0) {
newClassificationFilters.push(f);
}
});
slicerFilterValues.forEach(function(f) {
if (hiddenValues.indexOf(f) < 0) {
newSlicerFilters.push(f);
}
});
// Hide the shape or show it
if (hide) {
d3.select(this).style("opacity", 0.2);
} else {
d3.select(this).style("opacity", 0.8);
}
// Filter the data
myChart.data = dimple.filterData(dimple.filterData(data, 'classification', newClassificationFilters), slicer, newSlicerFilters);
// Passing a duration parameter makes the chart animate. Without
// it there is no transition
myChart.draw(800, false);
});
}
function moveLegend(legend, offset) {
$(legend).find('text,rect').attr('y', parseInt($(f).find('text').attr('y')) + offset);
}
createChart();
I've rendered the line series after the pies so the lines end up on top of the pie segments. This allows for the mouseover interactivity of the line series to be accessed.
When the pie segments are toggled off and then on, they end up rendering on top of the line segment when they come back. This is likely because the paths are added to the end of the chart object and not interjected before the line series. Eventually they block the line series interactivity.
I've tried several solutions including:
I can bring them back by hiding all the lines and bringing them back (the order of addition makes the lines come back at the top).
I feel like jumping into the paths and using jquery to remove them and add them back which would feel like a total hack. Anyone have a more elegant way to handle this?
What you need to do inside chart.addSeries is add each series to a separate 'g' element within the svg. At the moment your circles and lines are all mixed up in the same g element, so the last appended elements are always drawn on top.
e.g. so
<g>
<path>
<circle>
<path>
<newly appended circle>
</g>
becomes
<g>
<circle>
<newly appended circle>
</g>
<g>
<path>
<path>
</g>
All paths will then always be drawn after all the circles as svg just draws the elements in the order above