【发布时间】:2016-09-07 08:57:18
【问题描述】:
我在 d3 图表上显示以下数据:
[{
"Date": "2012",
"Total": 5340
}, {
"Date": "2013",
"Total": 4120
}, {
"Date": "2014",
"Total": 1259
}, {
"Date": "2015",
"Total": 3617
}, {
"Date": "2016",
"Total": 2005
}]
图表上还有一个画笔,因此用户可以通过拖动画笔专注于选择的年份。但是,画笔允许用户拖动第一年和去年之间的所有日期。
我想做的是让它与用户刷牙的岁月保持一致。
这是我的画笔事件代码:
var brush = d3.svg.brush()
.x(xScale2)
.on('brush', brushed);
function brushed() {
var min = d3.min(data.map(function (d) {
return d.total;
}));
var max = d3.max(data.map(function (d) {
return d.total;
}));
var extent = brush.extent();
if (!brush.empty()) {
// Snap to years
var newBrush = extent.map(d3.time.year.round);
if (newBrush[0] >= newBrush[1]) {// If empty when rounded, use floor & ceil instead.
newBrush[0] = d3.time.year.floor(extent[0]);
newBrush[1] = d3.time.year.ceil(extent[1]);
}
// update the extent
brush.extent([newBrush[0], newBrush[1]]);
extent = brush.extent();
xScale.domain(brush.empty() ? xScale2.domain() : extent);
yScale.domain([
d3.min(data.map(function (d) {
return (d.date >= extent[0] && d.date <= extent[1]) ? d.total : max;
})),
d3.max(data.map(function (d) {
return (d.date >= extent[0] && d.date <= extent[1]) ? d.total : min;
}))
]);
xScale.domain(brush.empty() ? xScale2.domain() : extent);
yScale.domain([
d3.min(data.map(function (d) {
return (d.date >= extent[0] && d.date <= extent[1]) ? d.total : max;
})),
d3.max(data.map(function (d) {
return (d.date >= extent[0] && d.date <= extent[1]) ? d.total : min;
}))
]);
}
totalChart.attr('d', totalLine); // update line
focus.select('.x.axis').call(xAxis); // update xAxis
focus.select('.y.axis').call(yAxis); // update yAxis
}
这是基于:https://bl.ocks.org/mbostock/6232620
所以想法是首先将年份四舍五入,然后在应用于域之前修改范围,并且应该使画笔捕捉...但是它不会捕捉...相反它使用户争取在岁月之间拖它。我希望它在用户开始拖动时实际捕捉到下一年。他们应该永远无法在这些年之间拖延。
【问题讨论】:
-
您只是希望它每年工作一次,还是希望它四舍五入到数据中存在的日期?
-
@SaeedAdelMehraban 在这个例子中只是每年一次,然后一旦它正确捕捉,我可以调整它以适用于我的其他日期格式。所以在短短几年内。
-
我已更新我的答案以使用 d3 v3。
-
@SaeedAdelMehraban 我注意到你在做 v3 时使用了 Brushend...这是因为你不能像 v4 那样让 snap 实时工作在 v3 上吗?
-
加入我的chat
标签: javascript d3.js