扩展dc.js以添加“simpleLineChart”图表

时间:2013-06-18 18:48:40

标签: d3.js simplify crossfilter dc.js

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

我正在使用dc.js来绘制从我大学的蜂箱中收集的数据。我正在将每个数据库更改的新数据推送到图表中(使用Meteor的魔力)。 当数据库超过5000条记录时,重新渲染线条变得非常慢。所以我想在渲染之前使用simplify.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接受一个数据数组,tolerance和一个布尔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

1 个答案:

答案 0 :(得分:2)

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

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

我把它改成了

d

之前编写var lineY = function(d, dataIndex, groupIndex) { return _chart.y()(_chart.valueAccessor()(d)); }; 的方式是,它在数组中查找y值,而不是使用绑定到group元素的数据。在我进行更改之前,此数组已设置了数据集,因此它仍在使用旧的预简化数据。