使用交叉过滤器和 dc.js 绘制平均值
Graphing average using crossfilter and dc.js
我试图在 x 轴是月份,y 轴是容量的折线图上绘制平均值。这是我尝试绘制图表的数据示例:
{month : "1", capacity: "48"}
{month : "1", capacity: "60"}
{month : "2", capacity: "67"}
{month : "2", capacity: "60"}
{month : "3", capacity: "66"}
{month : "3", capacity: "52"}
{month : "4", capacity: "63"}
{month : "4", capacity: "67"}
{month : "5", capacity: "80"}
{month : "5", capacity: "61"}
{month : "5", capacity: "66"}
{month : "6", capacity: "54"}
{month : "6", capacity: "69"}
所以我正在尝试获取每周的平均容量。出于某种原因,当我尝试使用 dc 绘制它时,这条线没有出现。我看到 x 和 y 轴上的数字,但图表是空白的。
这是我的代码,如有任何帮助,我们将不胜感激
let chart = dc.lineChart("#chart");
let ndx = crossfilter(<example data from above>);
let monthDimension = ndx.dimension(function (d) {
return d.month;
});
function reduceAdd(p, v) {
++p.count;
p.total += v.capacity;
p.average = p.total / p.count;
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.capacity;
p.average = p.count ? p.total / p.count : 0;
return p;
}
function reduceInitial() {
return { count: 0, total: 0, average: 0 };
}
let capacityGroup = monthDimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
chart.width(360)
.height(200)
.margins({ top: 20, right: 20, bottom: 50, left: 30 })
.mouseZoomable(false)
.x(d3.scale.linear().domain([0, 52]))
.renderHorizontalGridLines(true)
.brushOn(false)
.dimension(weekDimension)
.valueAccessor(function (d) {
return d.value.average;
})
.group(capacityGroup );
dc.renderAll('chart');
啊,可怕的“空白图表”。我们都遇到过。
幸运的是,浏览器控制台中有几个错误显示了部分方式。然后有一些变化我想你只需要通过经验来学习。
我进行了以下更改并得到了一张看起来正确的图表。
dc.renderAll()
通常不接受参数,除非您有多个图表组(通常是交叉过滤器的多个实例)。
d3.scale.linear()
是 D3@3 语法;对于 D3@6,我将其更改为 d3.scaleLinear()
。取决于您要使用哪个版本,但是如果您想使用 D3@3,则需要使用 dc@2。
weekDimension
未定义;我将它更改为 monthDimension
用于您的数据。
- (最细微的变化。)您输入的数据是字符串,不会自动转换为数字。如果您尝试“添加”字符串,它们会连接起来,您会得到很大的数字和奇怪的结果。
所以我在顶部添加了这个循环,将字符串转换为数字:
data.forEach(d => {
d.month = +d.month;
d.capacity = +d.capacity;
})
也可以即时转换,但我认为预先进行转换更有效、更稳健。
我试图在 x 轴是月份,y 轴是容量的折线图上绘制平均值。这是我尝试绘制图表的数据示例:
{month : "1", capacity: "48"}
{month : "1", capacity: "60"}
{month : "2", capacity: "67"}
{month : "2", capacity: "60"}
{month : "3", capacity: "66"}
{month : "3", capacity: "52"}
{month : "4", capacity: "63"}
{month : "4", capacity: "67"}
{month : "5", capacity: "80"}
{month : "5", capacity: "61"}
{month : "5", capacity: "66"}
{month : "6", capacity: "54"}
{month : "6", capacity: "69"}
所以我正在尝试获取每周的平均容量。出于某种原因,当我尝试使用 dc 绘制它时,这条线没有出现。我看到 x 和 y 轴上的数字,但图表是空白的。
这是我的代码,如有任何帮助,我们将不胜感激
let chart = dc.lineChart("#chart");
let ndx = crossfilter(<example data from above>);
let monthDimension = ndx.dimension(function (d) {
return d.month;
});
function reduceAdd(p, v) {
++p.count;
p.total += v.capacity;
p.average = p.total / p.count;
return p;
}
function reduceRemove(p, v) {
--p.count;
p.total -= v.capacity;
p.average = p.count ? p.total / p.count : 0;
return p;
}
function reduceInitial() {
return { count: 0, total: 0, average: 0 };
}
let capacityGroup = monthDimension.group().reduce(reduceAdd, reduceRemove, reduceInitial);
chart.width(360)
.height(200)
.margins({ top: 20, right: 20, bottom: 50, left: 30 })
.mouseZoomable(false)
.x(d3.scale.linear().domain([0, 52]))
.renderHorizontalGridLines(true)
.brushOn(false)
.dimension(weekDimension)
.valueAccessor(function (d) {
return d.value.average;
})
.group(capacityGroup );
dc.renderAll('chart');
啊,可怕的“空白图表”。我们都遇到过。
幸运的是,浏览器控制台中有几个错误显示了部分方式。然后有一些变化我想你只需要通过经验来学习。
我进行了以下更改并得到了一张看起来正确的图表。
dc.renderAll()
通常不接受参数,除非您有多个图表组(通常是交叉过滤器的多个实例)。d3.scale.linear()
是 D3@3 语法;对于 D3@6,我将其更改为d3.scaleLinear()
。取决于您要使用哪个版本,但是如果您想使用 D3@3,则需要使用 dc@2。weekDimension
未定义;我将它更改为monthDimension
用于您的数据。- (最细微的变化。)您输入的数据是字符串,不会自动转换为数字。如果您尝试“添加”字符串,它们会连接起来,您会得到很大的数字和奇怪的结果。
所以我在顶部添加了这个循环,将字符串转换为数字:
data.forEach(d => {
d.month = +d.month;
d.capacity = +d.capacity;
})
也可以即时转换,但我认为预先进行转换更有效、更稳健。