2

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

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

我已经开始使用 dc.js 扩展 dc.js simpleLineChart,它将继承现有的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);
}

simple.js 接受一个数据数组 atolerance和一个 boolean 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()andhighQuality()方法的折线图。见这里:http ://bl.ocks.org/elsherbini/5814788

4

1 回答 1

2

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

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

我把它改成

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

之前写的方式lineY,是在数组中查找y值,而不是使用绑定到group元素的数据。在我进行更改之前,这个数组有它的数据集,所以它仍然使用旧的、预简化的数据。

于 2013-06-22T01:50:59.557 回答