【问题标题】:Graphing average using crossfilter and dc.js使用 crossfilter 和 dc.js 绘制平均值
【发布时间】:2020-11-21 04:58:28
【问题描述】:

我试图在 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');

【问题讨论】:

    标签: javascript reduce dc.js linechart crossfilter


    【解决方案1】:

    啊,可怕的“空白图表”。我们都遇到过这种情况。

    幸运的是,浏览器控制台中出现了一些错误,这些错误显示了部分原因。然后有一些变化,我想你只需要从经验中学习。

    我做了以下更改,得到了一个看起来正确的图表。

    1. dc.renderAll() 通常不带参数,除非您有多个图表组(通常是交叉过滤器的多个实例)。
    2. d3.scale.linear() 是 D3@3 语法;对于 D3@6,我将其更改为 d3.scaleLinear()。使用哪个版本由您决定,但如果您想使用 D3@3,则需要使用 dc@2。
    3. weekDimension 未定义;我将其更改为 monthDimension 以获取您的数据。
    4. (最细微的变化。)您的输入数据是字符串,不会自动转换为数字。如果您尝试“添加”字符串,它们将连接起来,您会得到很大的数字和奇怪的结果。

    所以我在顶部添加了这个循环,将字符串转换为数字:

    data.forEach(d => {
      d.month = +d.month;
      d.capacity = +d.capacity;
    })
    

    也可以即时转换,但我认为预先进行转换更有效、更可靠。

    Fiddle link.

    【讨论】:

    • 你是一个救生员!将字符串转换为数字使其完美运行。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    相关资源
    最近更新 更多