d3.js - 扩展 dc.js 以添加 "simpleLineChart"图表

标签 d3.js simplify crossfilter dc.js

编辑请参阅此处,了解我正在尝试执行的操作的非工作示例:http://bl.ocks.org/elsherbini/5814788

我正在使用 dc.js 绘制从我大学的 hive 收集的数据。我在每次数据库更改时将新数据推送到图表中(使用 Meteor 的魔力)。 当数据库超过 5000 条记录左右时,重新渲染线条会变得非常慢。所以我想在渲染之前使用 Simply.js 来预处理线条。要了解我在说什么,请访问 http://datacomb.meteor.com/ 。页面会在几秒钟后卡住,因此请注意。

我已经开始使用 simpleLineChart 扩展 dc.js,它将继承现有的 dc.lineChart 对象/函数。这是我到目前为止所拥有的:

dc.simpleLineChart = function(parent, chartGroup) {
    var _chart = dc.lineChart(),
        _tolerance = 1,
        _highQuality = false,
        _helperDataArray;

    _chart.tolerance = function (_) {
        if (!arguments.length) return _tolerance;
        _tolerance = _;
        return _chart;
    };

    _chart.highQuality = function (_) {
        if (!arguments.length) return _highQuality;
        _highQuality = _;
        return _chart;
    };

    return _chart.anchor(parent, chartGroup);
}

simplify.js 接受一个数据数组、一个容差 和一个 bool 值highQuality,并根据其简化算法返回一个元素较少的新数组。

dc.js 使用 crossfilter.js。 dc.js 图表与特定的交叉过滤器维度和组相关联。最终,它使用来自 someGroup().all() 的数据作为传递给 d3.svg.line() 的数据。 我不能找到 dc.js 源代码中发生这种情况的位置,但这是我需要干预的地方。我想找到这个方法,并在我正在制作的 dc.simpleLineChart 对象中覆盖它。

我在想类似的事情

_chart.theMethodINeedToOverride = function(){
    var helperDataArray = theChartGroup().all().map(function(d) { return {
        x: _chart.keyAccessor()(d), 
        y: _chart.valueAccessor()(d)};})

    var simplifiedData = simplify(helperDataArray, _tolerance, _highQuality)

    g.datum(simplifiedData); // I know I'm binding some data at some point
                             // I'm just not sure to what or when
}

任何人都可以帮助我确定我需要覆盖哪个方法,或者更好的是,告诉我如何做到这一点?

dc.js 来源:https://github.com/NickQiZhu/dc.js/blob/master/dc.js

编辑:

我想我可能已经找到了我需要重写的函数。原函数为

function createGrouping(stackedCssClass, group) {
    var g = _chart.chartBodyG().select("g." + stackedCssClass);

    if (g.empty())
        g = _chart.chartBodyG().append("g").attr("class", stackedCssClass);

    g.datum(group.all());

    return g;
}

我尝试像这样覆盖它

function createGrouping(stackedCssClass, group) {
    var g = _chart.chartBodyG().select("g." + stackedCssClass);

    if (g.empty())
        g = _chart.chartBodyG().append("g").attr("class", stackedCssClass);

    var helperDataArray = group().all().map(function(d) { return {
        x: _chart.keyAccessor()(d), 
        y: _chart.valueAccessor()(d)};})

    var simplifiedData = simplify(helperDataArray, _tolerance, _highQuality)

    g.datum(simplifiedData);

    return g;
}

但是,当我制作 simpleLineChart 时,它只是一个带有 tolerance()highQuality() 方法的折线图。参见这里:http://bl.ocks.org/elsherbini/5814788

最佳答案

嗯,我几乎做了我打算做的事情。 http://bl.ocks.org/elsherbini/5814788

关键是不仅要修改createGrouping函数,还要修改代码中的lineY函数。 (lineY 设置为告诉 d3.svg.line() 实例如何设置给定点 d 的 y 值)

我把它改成了

var lineY = function(d, dataIndex, groupIndex) {
    return _chart.y()(_chart.valueAccessor()(d));
};

之前编写lineY的方式是在数组中查找 y 值,而不是使用绑定(bind)到组元素的数据。该数组在我进行更改之前就已经拥有了数据集,因此它仍然使用旧的、简化前的数据。

关于d3.js - 扩展 dc.js 以添加 "simpleLineChart"图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17176562/

相关文章:

javascript - dc.js 百分比直方图 - 组的大小

javascript - 使用 JavaScript 或 jQuery 在 D3.js 中隐藏节点和子节点

mysql - ColdFusion DateDiff - 有更好的方法吗?

d3.js - dc.js过滤后修改时间刻度x轴

c++ - 有没有办法缩短这个while条件?

c# - 有什么理由不重构它,使其更简单吗?

javascript - 多个数据源导致 `invalid array width!` 错误

javascript - 自下而上动画 d3 图

javascript - 使用 d3.js 获取选中的单选按钮的值

javascript - d3js 不要先输入动画