dc.js将范围图表应用于多个图形 [英] Dc.js applying range Chart to multiple graphs
问题描述
最近两周我一直在使用dc.js,但是有一个问题似乎我无法弄清。
I have been working with dc.js for the last couple of weeks but there is one problem I just don't seem to be able to figure out.
我希望能够使用画笔过滤器基于单个图表更改四个不同图表的比例。类似于以下内容:
I want to be able to change the scales of four different charts based on a single chart with a brush filter. Something along the lines of:
priorityTotChart
.width(2*w/3).height(h/3)
.margins({top: 10, right: 50, bottom: 20, left: 40})
.dimension(dateDim)
.group(priorityTotal)
.centerBar(true)
.gap(1)
.x(d3.time.scale().domain([minDate,maxDate]))
.elasticY(true)
.brushOn(true);
var translate = 3;
priority1Chart.width(w/3)
.height(h/6)
.transitionDuration(300)
.margins({top: 10, right: 50, bottom: 25, left: 40})
.dimension(dateDim)
.group(priority1)
.mouseZoomable(false)
.x(d3.time.scale().domain([minDate,maxDate]))
.xUnits(d3.time.months)
.elasticY(true)
.brushOn(false)
.ordinalColors(["red"])
.rangeChart(priorityTotChart)
.yAxisLabel("Hits per day")
.renderArea(true)
.renderlet(function (chart) {
chart.selectAll("g._1").attr("transform", "translate(" + translate + ", 0)");
});
priority2Chart.width(w/3)
.height(h/6)
.transitionDuration(300)
.margins({top: 10, right: 50, bottom: 25, left: 40})
.dimension(dateDim)
.group(priority2)
.mouseZoomable(false)
.x(d3.time.scale().domain([minDate,maxDate]))
.xUnits(d3.time.months)
.elasticY(true)
.brushOn(false)
.ordinalColors(["orange"])
.rangeChart(priorityTotChart)
.yAxisLabel("Hits per day")
.renderArea(true)
.renderlet(function (chart) {
chart.selectAll("g._1").attr("transform", "translate(" + translate + ", 0)");
});
priority3Chart.width(w/3)
.height(h/6)
.transitionDuration(300)
.margins({top: 10, right: 50, bottom: 25, left: 40})
.dimension(dateDim)
.group(priority3)
.mouseZoomable(false)
.x(d3.time.scale().domain([minDate,maxDate]))
.xUnits(d3.time.months)
.elasticY(true)
.brushOn(false)
.ordinalColors(["blue"])
.rangeChart(priorityTotChart)
.yAxisLabel("Hits per day")
.renderArea(true)
.renderlet(function (chart) {
chart.selectAll("g._1").attr("transform", "translate(" + translate + ", 0)");
});
priority4Chart.width(w/3)
.height(h/6)
.transitionDuration(300)
.margins({top: 10, right: 50, bottom: 25, left: 40})
.dimension(dateDim)
.group(priority4)
.mouseZoomable(false)
.x(d3.time.scale().domain([minDate,maxDate]))
.xUnits(d3.time.months)
.elasticY(true)
.brushOn(false)
.ordinalColors(["green"])
.rangeChart(priorityTotChart)
.yAxisLabel("Hits per day")
.renderArea(true)
.renderlet(function (chart) {
chart.selectAll("g._1").attr("transform", "translate(" + translate + ", 0)");
});
但是,此方法似乎不起作用,仅是使用 .rangeChart(priorityTotChart)
将被更新。
However this method doesn't seem to work as only the last chart that uses .rangeChart(priorityTotChart)
will be updated.
我可以通过使每个图取决于上一个图的范围来解决此问题。例如,priority1Chart具有 .rangeChart(priorityTotChart)
,priority2Chart具有 .rangeChart(priority1Chart)
等,但是这种方法是非常慢。所以我希望有一种更好的方法来达到同样的效果?
I can get around this problem by making each graph depend on the range of the previous graph i.e. priority1Chart has .rangeChart(priorityTotChart)
, and priority2Chart has .rangeChart(priority1Chart)
etc., but this method is very slow. So I was hoping there was a better way to achieve the same effect?
预先感谢!
推荐答案
问您问题的另一种方法是,如何将多个焦点图附加到单个范围图上?
Another way of asking your question is, "how can I attach multiple focus charts to a single range chart?"
(至少,如果您只关心刷一下范围图以缩放焦点图,而不是相反)。
(At least, if you only care about brushing the range chart zooming the focus charts, not the other way around.)
考虑到这个新问题,请看一下axis.GridMixin.focusChart的实现:
Given this new question, take a look at the implementation of coordinateGridMixin.focusChart:
_chart.focusChart = function (c) {
if (!arguments.length) {
return _focusChart;
}
_focusChart = c;
_chart.on('filtered', function (chart) {
if (!chart.filter()) {
dc.events.trigger(function () {
_focusChart.x().domain(_focusChart.xOriginalDomain());
});
} else if (!rangesEqual(chart.filter(), _focusChart.filter())) {
dc.events.trigger(function () {
_focusChart.focus(chart.filter());
});
}
});
return _chart;
};
这里我们要做的就是制作一个包含多个焦点图的函数的新版本。由于此函数不访问任何内部数据,因此我们可以猴子补丁任何坐标网格图以添加功能:
All we need to do here is make a new version of the function that takes multiple focus charts. Since this function doesn't access any internal data, we can "monkey patch" any coordinate grid chart to add the functionality:
chart1.focusCharts = function (chartlist) {
if (!arguments.length) {
return this._focusCharts;
}
this._focusCharts = chartlist; // only needed to support the getter above
this.on('filtered', function (range_chart) {
if (!range_chart.filter()) {
dc.events.trigger(function () {
chartlist.forEach(function(focus_chart) {
focus_chart.x().domain(focus_chart.xOriginalDomain());
});
});
} else chartlist.forEach(function(focus_chart) {
if (!rangesEqual(range_chart.filter(), focus_chart.filter())) {
dc.events.trigger(function () {
focus_chart.focus(range_chart.filter());
});
}
});
});
return this;
};
我们还需要从coordinateGridMixin中复制rangeEqual辅助函数,以使其正常工作。
We also need to copy the rangesEqual helper function out of coordinateGridMixin in order to get this working.
我创建了一个示例并将其添加到dc.js示例中:
I created an example and added it to the dc.js examples:
http://dc-js.github.io/dc.js/examples/multi-focus .html
您可以在此处查看源代码:
You can see the source here:
https://github.com/dc-js/dc.js/ blob / master / web / examples / multi-focus.html
原生支持这会很不错,包括相反的case zoom->过滤器,确实需要更改dc.js内部。我添加了一个问题来跟踪这一想法: https://github.com/dc- js / dc.js / issues / 820
This would be nice to support natively, including the opposite case zoom -> filter, which does require changing dc.js internals. I added an issue to track the idea: https://github.com/dc-js/dc.js/issues/820
这篇关于dc.js将范围图表应用于多个图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!