dc.js - rangeChart 条在过滤掉后消失
dc.js - rangeChart bars disappearing when filtered out
我是 dc.js 的新手,正在尝试在 https://dc-js.github.io/dc.js/ 的演示中实现类似 "Monthly Index Abs Move" 图表的东西
(请参阅 https://dc-js.github.io/dc.js/docs/stock.html 处的文档来源)。
即。我正在尝试为 "zoom in" 视图实现一个折线图,为 "zoomed out" 视图(rangeChart)实现一个条形图。
我的问题是,当我过滤日期范围时(例如,通过使用 "brushOn" 条形图),过滤掉的条形消失了
该演示可以正常工作 - 日期范围外的条形图是灰色的,日期范围内的条形图是蓝色的 - 请参见屏幕截图。
我使用的是演示中使用的 css 文件,我使用的代码非常相似(请参见下面的代码),所以我不确定为什么会出现这种差异。
var maxDate = new Date(1985, 0, 1);
var minDate = new Date(2200, 12, 31);
events.forEach(function (d) {
d.created = new Date(d.created);
//d.last_modified = new Date(d.last_modified);
d.hour = d3.time.hour(d.created); // precaclculate for performance
d.day = d3.time.day(d.created);
if (d.created > maxDate) {
maxDate = d.created;
}
if (d.created < minDate) {
minDate = d.created;
}
});
var ndx = crossfilter(events);
var dateDimension = ndx.dimension(dc.pluck('created'));
var chatHourDim = ndx.dimension(dc.pluck('hour'));
var chatDayDim = ndx.dimension(dc.pluck('day'));
var chatsPerHourGroup = chatHourDim.group().reduceCount();
var chatsPerDayGroup = chatDayDim.group().reduceCount();
visitorsPerHour /* dc.lineChart('#visitors-count', 'chartGroup'); */
.renderArea(true)
.width(900)
.height(200)
.transitionDuration(10)
.margins({top: 30, right: 40, bottom: 25, left: 40})
.dimension(chatHourDim)
.mouseZoomable(true)
// Specify a “range chart” to link its brush extent with the zoom of the current “focus chart”.
.rangeChart(visitorsPerDay)
.x(d3.time.scale().domain([minDate, maxDate]))
.round(d3.time.hour.round)
.xUnits(d3.time.hours)
.elasticY(true)
.renderHorizontalGridLines(true)
.legend(dc.legend().x(650).y(10).itemHeight(13).gap(5))
.brushOn(false)
.group(chatsPerHourGroup, 'Chat events per hour')
.title(function (d) {
var value = d.value;
if (isNaN(value)) {
value = 0;
}
return dateFormat(d.key) + '\n' + value + " chat events";
});
// dc.barChart("visitors-count-per-day", 'chartGroup');
visitorsPerDay.width(900)
.height(40)
.margins({top: 0, right: 50, bottom: 20, left: 40})
.dimension(chatDayDim)
.group(chatsPerDayGroup)
// .centerBar(true)
.gap(1)
.brushOn(true)
.x(d3.time.scale().domain([minDate, maxDate]))
.round(d3.time.day.round)
.alwaysUseRounding(true)
.xUnits(d3.time.days);
dc.js 和 crossfilter 通常支持此功能的方式是 a crossfilter group does not observe its own dimension's filters。
股票示例中的范围图表示例对两个图表使用相同的维度 (moveMonths
)。因此,当焦点图表缩放到范围图表中的选定范围时,它会过滤所有其他图表(您想要的)的数据,但不会过滤范围图表。
如果您想对两个图表使用不同的尺寸,我可以找到几种解决方法。
使用虚假群组
也许最简单的做法是使用 fake group:
对数据进行快照并将范围图表与以后的过滤器断开连接
function snapshot_group(group) {
// will get evaluated immediately when the charts are initializing
var _all = group.all().map(function(kv) {
// don't just copy the array, copy the objects inside, because they may change
return {key: kv.key, value: kv.value};
});
return {
all: function() { return _all; }
};
}
visitorsPerDay
.group(snapshot_group(chatsPerDayGroup))
但是,范围图也不会响应其他图表上的过滤器,而您可能希望它响应。
同维度,不同分组
因此可以说,更正确的做法是对焦点图和范围图仅使用一个时间维度,尽管它会破坏您尝试对分箱进行的优化。一个组可以选择采用自己的访问器,该访问器采用维度键并生成自己的键,该键必须保留顺序。
看起来它可能正是为此目的而设计的:
var dateDimension = ndx.dimension(dc.pluck('created'));
var chatsPerHourGroup = dateDimension.group(function(d) {
return d3.time.hour(d);
}).reduceCount();
var chatsPerDayGroup = dateDimension.group(function(d) {
return d3.time.day(d);
}).reduceCount();
visitorsPerHour /* dc.lineChart('#visitors-count', 'chartGroup'); */
.dimension(dateDimension)
.group(chatsPerHourGroup, 'Chat events per hour')
visitorsPerDay.width(900)
.dimension(dateDimension)
.group(chatsPerDayGroup)
我不知道您是否会注意到速度变慢。是的,JavaScript 日期对象很慢,但这应该不是问题,除非您要转换数万或数十万个日期。通常 DOM 元素是 d3/dc 中的瓶颈,而不是 JavaScript 方面的任何东西。
我是 dc.js 的新手,正在尝试在 https://dc-js.github.io/dc.js/ 的演示中实现类似 "Monthly Index Abs Move" 图表的东西 (请参阅 https://dc-js.github.io/dc.js/docs/stock.html 处的文档来源)。
即。我正在尝试为 "zoom in" 视图实现一个折线图,为 "zoomed out" 视图(rangeChart)实现一个条形图。
我的问题是,当我过滤日期范围时(例如,通过使用 "brushOn" 条形图),过滤掉的条形消失了
该演示可以正常工作 - 日期范围外的条形图是灰色的,日期范围内的条形图是蓝色的 - 请参见屏幕截图。
我使用的是演示中使用的 css 文件,我使用的代码非常相似(请参见下面的代码),所以我不确定为什么会出现这种差异。
var maxDate = new Date(1985, 0, 1);
var minDate = new Date(2200, 12, 31);
events.forEach(function (d) {
d.created = new Date(d.created);
//d.last_modified = new Date(d.last_modified);
d.hour = d3.time.hour(d.created); // precaclculate for performance
d.day = d3.time.day(d.created);
if (d.created > maxDate) {
maxDate = d.created;
}
if (d.created < minDate) {
minDate = d.created;
}
});
var ndx = crossfilter(events);
var dateDimension = ndx.dimension(dc.pluck('created'));
var chatHourDim = ndx.dimension(dc.pluck('hour'));
var chatDayDim = ndx.dimension(dc.pluck('day'));
var chatsPerHourGroup = chatHourDim.group().reduceCount();
var chatsPerDayGroup = chatDayDim.group().reduceCount();
visitorsPerHour /* dc.lineChart('#visitors-count', 'chartGroup'); */
.renderArea(true)
.width(900)
.height(200)
.transitionDuration(10)
.margins({top: 30, right: 40, bottom: 25, left: 40})
.dimension(chatHourDim)
.mouseZoomable(true)
// Specify a “range chart” to link its brush extent with the zoom of the current “focus chart”.
.rangeChart(visitorsPerDay)
.x(d3.time.scale().domain([minDate, maxDate]))
.round(d3.time.hour.round)
.xUnits(d3.time.hours)
.elasticY(true)
.renderHorizontalGridLines(true)
.legend(dc.legend().x(650).y(10).itemHeight(13).gap(5))
.brushOn(false)
.group(chatsPerHourGroup, 'Chat events per hour')
.title(function (d) {
var value = d.value;
if (isNaN(value)) {
value = 0;
}
return dateFormat(d.key) + '\n' + value + " chat events";
});
// dc.barChart("visitors-count-per-day", 'chartGroup');
visitorsPerDay.width(900)
.height(40)
.margins({top: 0, right: 50, bottom: 20, left: 40})
.dimension(chatDayDim)
.group(chatsPerDayGroup)
// .centerBar(true)
.gap(1)
.brushOn(true)
.x(d3.time.scale().domain([minDate, maxDate]))
.round(d3.time.day.round)
.alwaysUseRounding(true)
.xUnits(d3.time.days);
dc.js 和 crossfilter 通常支持此功能的方式是 a crossfilter group does not observe its own dimension's filters。
股票示例中的范围图表示例对两个图表使用相同的维度 (moveMonths
)。因此,当焦点图表缩放到范围图表中的选定范围时,它会过滤所有其他图表(您想要的)的数据,但不会过滤范围图表。
如果您想对两个图表使用不同的尺寸,我可以找到几种解决方法。
使用虚假群组
也许最简单的做法是使用 fake group:
对数据进行快照并将范围图表与以后的过滤器断开连接function snapshot_group(group) {
// will get evaluated immediately when the charts are initializing
var _all = group.all().map(function(kv) {
// don't just copy the array, copy the objects inside, because they may change
return {key: kv.key, value: kv.value};
});
return {
all: function() { return _all; }
};
}
visitorsPerDay
.group(snapshot_group(chatsPerDayGroup))
但是,范围图也不会响应其他图表上的过滤器,而您可能希望它响应。
同维度,不同分组
因此可以说,更正确的做法是对焦点图和范围图仅使用一个时间维度,尽管它会破坏您尝试对分箱进行的优化。一个组可以选择采用自己的访问器,该访问器采用维度键并生成自己的键,该键必须保留顺序。
看起来它可能正是为此目的而设计的:
var dateDimension = ndx.dimension(dc.pluck('created'));
var chatsPerHourGroup = dateDimension.group(function(d) {
return d3.time.hour(d);
}).reduceCount();
var chatsPerDayGroup = dateDimension.group(function(d) {
return d3.time.day(d);
}).reduceCount();
visitorsPerHour /* dc.lineChart('#visitors-count', 'chartGroup'); */
.dimension(dateDimension)
.group(chatsPerHourGroup, 'Chat events per hour')
visitorsPerDay.width(900)
.dimension(dateDimension)
.group(chatsPerDayGroup)
我不知道您是否会注意到速度变慢。是的,JavaScript 日期对象很慢,但这应该不是问题,除非您要转换数万或数十万个日期。通常 DOM 元素是 d3/dc 中的瓶颈,而不是 JavaScript 方面的任何东西。