我创建了一个酒窝交互式图表的版本(见 dimplejs.org/advanced_examples_viewer.html?id=advanced_interactive_legends) 有两个系列:一个 PIE 系列和一个基于同一数据集的线系列。
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();
我在饼图之后渲染了线条系列,因此线条最终位于饼图段的顶部。 这允许访问行系列的鼠标悬停交互性。
当饼图段关闭然后打开时,它们最终会在返回时呈现在线段的顶部。 这可能是因为路径被添加到图表对象的末尾,而不是在线条系列之前插入。 最终,它们阻止了行系列的交互性。
我尝试了几种解决方案,包括:
- 尝试使用d3.prototype.moveToBack 代码(见 bl.ocks.org/eesur/4e0a69d57d3bfc8a82c2)
- 路径没有父节点或父节点没有子节点
- 尝试删除线条系列并使用chart.series.slice再次添加,或者使用chart.series = []仅删除两者
- 之后的图表一团糟,因为对象没有全部删除。
- 删除 pie.shapes 和/或 line.shapes 并没有多大帮助。
我可以通过隐藏所有行并将它们带回来将它们带回(添加顺序使行在顶部返回)。
我想跳入路径并使用jquery删除它们并将它们添加回来,这感觉就像一个完全的黑客。有人有更优雅的方式来处理这个问题吗?
在chart.addSeries中你需要做的是将每个系列添加到svg中单独的"g"元素中。目前,您的圆圈和线条都混合在同一个g元素中,因此最后附加的元素始终绘制在顶部。
例如所以
<g>
<path>
<circle>
<path>
<newly appended circle>
</g>
成为
<g>
<circle>
<newly appended circle>
</g>
<g>
<path>
<path>
</g>
然后,所有路径将始终在所有圆圈之后绘制,因为 svg 只是按上述顺序绘制元素
因此,事实证明,酒窝 2.1.6 将任意数量系列的所有系列元素添加到@mgraham指出的同一<g>
元素中。 功劳。 AlignAnalytics 酒窝存储库上的问题 #203 显示了其他人有同样的问题。 我分叉了它并为每个系列添加了组。 请参阅同一存储库上的拉取请求 #207。 希望他们能把它拉进来。
https://github.com/PMSI-AlignAlytics/dimple/pull/207