首页 文章

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

提问于
浏览
2

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

我正在使用dc.js来绘制从我大学的蜂箱收集的数据 . 我正在将每个数据库更改的新数据推送到图表中(使用Meteor的魔力) . When the database is over 5000 records or so, rerendering the lines gets really slow. 所以我想在渲染之前使用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(). I can't find where this is happening in the dc.js source 的数据,但这是我需要干预的地方 . 我想找到这个方法,并在我正在制作的 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 回答

  • 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元素的数据 . 在我进行更改之前,此数组已设置了数据集,因此它仍在使用旧的预简化数据 .

相关问题