d3.js - dc.js 绘制嵌套数据数组图表

标签 d3.js dc.js crossfilter

问题描述

我有一个大型数据数组,其结构类似于以下内容,并寻求创建一个图表,该图表将按创建变更集的小时显示时间记录的变更集。

[ // array of records
    {
        id: 1,
        name: 'some record',
        in_datetime: '2019-10-24T08:15:00.000000',
        out_datetime: '2019-10-24T10:15:00.000000',
        hours: 2,
        tasks: ["some task name", "another task"],
        changesets: [ //array of changesets within a record
            {
                id: 1001,
                created_at: '2019-10-24T09:37:00.000000'
            },
            ...
        ]
    },
    ...
]

无论我如何尝试创建维度/写入缩减函数,我都无法从数据表中获取正确的值。

const changeReduceAdd = (p, v) => {
    v.changesets.forEach(change => {
        let cHour = timeBand[change.created_hour]
        if (showByChanges) {
            p[cHour] = (p[cHour] || 0) + (change.num_changes || 0)
        } else {
            p[cHour] = (p[cHour] || 0) + 1 //this is 1 changeset
        }
    })
    return p
}

const changeReduceRemove = (p, v) => {
    v.changesets.forEach(change => {
        let cHour = timeBand[change.created_hour]
        if (showByChanges) {
            p[cHour] = (p[cHour] || 0) - (change.num_changes || 0)
        } else {
            p[cHour] = (p[cHour] || 0) - 1 //this is 1 changeset
        }
    })
    return p
}

const changeReduceInit = () => {
    return {}
}

//next create the array dimension of changesets by hour
//goal: show changesets or num_changes grouped by their created_hour
let changeDim = ndx.dimension(r => r.changesets.map(c => timeBand[c.created_hour]), true)
let changeGroup = changeDim.group().reduce(changeReduceAdd, changeReduceRemove, changeReduceInit)
let changeChart = dc.barChart('#changeset-hour-chart')
    .dimension(changeDim)
    .keyAccessor(d => d.key)
    .valueAccessor(d => d.value[d.key])
    .group(changeGroup)

jsfiddle and debugging notes

我遇到的主要问题是我想要变更集/创建时间图表,但在我尝试过的每个维度中,其中键显示正确的值都明显高于预期。

“8AM”类别中的值给出值 5,而实际上只有 3 个我标记为 created_hour: 8 的变更集:

wrong histogram

最佳答案

“标签维度”问题有很多解决方案,您恰好选择了其中最好的两个。

要么

  1. 自定义减少,或
  2. 维度构造函数的数组/标签标志参数

就可以了。

将这两种技术结合起来会给你带来麻烦。我并没有试图弄清楚究竟发生了什么,但你以某种方式对小时数进行了求和。

简单的解决方案:使用内置标签维度功能

使用标签/维度标志和默认reduceCount:

let changeDim = ndx.dimension(r => r.changesets.map(c => timeBand[c.created_hour]), true)
let changeGroup = changeDim.group(); // no reduce, defaults to reduceCount
let changeChart = dc.barChart('#changeset-hour-chart')
    .dimension(changeDim)
    .keyAccessor(d => d.key)
    .valueAccessor(d => d.value) // no [d.key], value is count
    .group(changeGroup)

correct histogram

fork of your fiddle

手册,1.4 之前的组所有版本

您的代码中还有一个 groupAll 解决方案。在 crossfilter 1.4 中引入数组/标签维度之前,此解决方案是必要的。

出于好奇,我尝试启用它,一旦您从 groupAll 结果转换为组结果,它也会起作用:

function groupall_map_to_group(groupall) {
  return {
    all: () => Object.entries(groupall.value())
                     .map(([key,value])=>({key,value}))
  }
}

let changeGroup = ndx.groupAll().reduce(changeReduceAdd, changeReduceRemove, changeReduceInit)
let changeChart = dc.barChart('#changeset-hour-chart')
    .dimension({}) // filtering not implemented
    .keyAccessor(d => d.key)
    .valueAccessor(d => d.value) // [d.key]
    .group(groupall_map_to_group(changeGroup))
    .x(dc.d3.scaleBand().domain(timeBand))
    .xUnits(dc.units.ordinal)
    .elasticY(true)
    .render()

crossfilter 1.3 version

关于d3.js - dc.js 绘制嵌套数据数组图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58812375/

相关文章:

javascript - dc.js 数字显示小部件

javascript - 使用 DC.JS/Crossfilter 进行部分求和

javascript - d3.js 水柱图

javascript - 弹出表单来编辑形状位置和标签?

javascript - angular-dc 条形图未呈现

javascript - 无法从 dc.js 数据表中删除空箱

svg - 如何使 nvd3 在 Internet Explorer 8 中工作?

javascript - d3 饼图不会重新渲染

google-maps - Ember-data:在 Controller / View 中使用模型

d3.js - dc.js 气泡图颜色比例不起作用