2013-06-18 3 views
2

редактировать Смотрите здесь для неработающего пример того, что я пытаюсь сделать: http://bl.ocks.org/elsherbini/5814788Расширение dc.js добавить графику «simpleLineChart»

Я использую dc.js для построения данных, собранных пчелиные ульи в моем университете. Я подталкиваю новые данные к графикам при каждой смене базы данных (используя магию Метеор). Когда база данных содержит более 5000 записей, рендеринг строк становится очень медленным. Поэтому я хочу использовать simplify.js для предварительной обработки строк перед рендерингом. Чтобы узнать, о чем я говорю, перейдите по ссылке http://datacomb.meteor.com/. Страница замерзает через пару секунд, поэтому будьте предупреждены.

Я начал расширять 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); 
} 

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, это просто LineChart с методом tolerance() и highQuality(). См. Здесь: http://bl.ocks.org/elsherbini/5814788

+0

По-прежнему считайте, что вы должны сфотографировать данные еще до построения графика! Диаграмма составляет всего пару сотен пикселей в ширину; нет никаких оснований для построения линейной диаграммы с тысячами точек. Растеризация svg для отображения на мониторе уже содержит данные. –

+0

Не уверен, что вы подразумеваете под «биннинг данных». Я думаю, что наивным решением было бы построить каждую n-ю точку, но это не удастся, когда набор данных станет действительно большим, потому что в конце концов будет что-то вроде 5 пунктов в день, и они не будут отражать форму линии до того, как она будет обязательно. И если вы имели в виду биннинг по частоте, я хочу получить линейную диаграмму, а не гистограмму. См. Http://mourner.github.io/simplify-js/, чтобы узнать, что я имею в виду. 70 000 единиц сократились до менее ста, сохраняя при этом форму. – elsherbini

+0

группа это день, час или какой-либо другой скользящий масштаб. Я предполагаю, что это тот же проект (http://stackoverflow.com/questions/16924767/simplifying-a-line-before-rendering-on-chart-in-d3)? Вместо того, чтобы пытаться нарисовать 70 000 строк, представляющих 5-минутные интервалы, найдите среднее дневное значение и график. –

ответ

2

Ну, я в значительной степени сделал то, что я намеревался сделать. http://bl.ocks.org/elsherbini/5814788

Ключ в том, чтобы не только изменить функцию createGrouping, но и lineY функции в коде.(lineY получает набор сказать экземпляру d3.svg.line(), как установить у значения заданной точки d)

Я изменил его

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

То, как lineY была написана до того, он смотрит вверх значение у в массиве, вместо использования данных, связанных с элементом группы. Этот массив имел свои данные перед тем, как я внес свои изменения, поэтому он все еще использовал старые, предварительно упрощенные данные.

 Смежные вопросы

  • Нет связанных вопросов^_^