2013-12-06 3 views
2

Я пытаюсь обновить линейный граф, и он не выдает никаких ошибок, но он также не обновляет график.обновление линейного графика в d3 не работает

я удалить точку и добавить новый с увеличивающейся скоростью и увеличиваются срок created_at на второй (пытаясь следовать http://bl.ocks.org/benjchristensen/1148374)

function redrawWithoutAnimation() { 

    for (var i in chart_data) { 
     linedata = chart_data[i]; 
     //delete first element of array 
     linedata.points.reverse().shift(); 
     //create a new point 
     rate = linedata.points[0].rate + 1; 
     created_at = linedata.points[0].created_at + 6000; 
     new_point = {}; 
     new_point.rate = rate; 
     new_point.created_at = created_at; 
     linedata.points.push(new_point); 
     console.log(linedata); 

    } 

    // static update without animation 
    svg.selectAll("path") 
     .data([linedata.points]); // set the new data 
    line(linedata.points); // apply the new data values 
} 

redrawWithoutAnimation(); 
setInterval(function() { 
    redrawWithoutAnimation(); 
}, 8000); 

вот мой код http://jsfiddle.net/yr2Nw/8/

ответ

2

Работа скрипку: http://jsfiddle.net/reblace/GsaGb/1

Там же несколько вопросов здесь ...

Во-первых, вы были обновляя все данные chart_data в цикле for, но вне цикла, вы пытались обновить строку, все еще сохраненную в переменной linedata после выполнения цикла. Вы должны стараться избегать наличия переменных с большим объемом, чем им нужно. Это может привести к ошибкам, как это одна:

svg.selectAll("path").data([linedata.points]); 
line(linedata.points); 

Вместо этого вы должны использовать данные D3 присоединения воссоединиться новые данные всех дорожек сразу декларативно, как так:

linesGroup.selectAll("path") 
    .data(chart_data) 
    .attr("d", function(d){ return line(d.points); }); 

Что делание, что код является он выбирает пути и затем соединяет каждый из них с элементами chart_data, а затем привязывает соответствующий генератор строк к атрибуту «d» для соответствующего пути.

Затем вам необходимо обновить ось x и ось y, иначе график будет просто снимать обратную область. Этот код обновляет домены, а затем подмены осей к элементам DOM, таким образом они перерисовывать:

xAxis.scale().domain([ 
    d3.min(chart_data, function (c) { return d3.min(c.points, function (v) { return v.created_at; }); }), 
    d3.max(chart_data, function (c) { return d3.max(c.points, function (v) { return v.created_at; }); }) 
]); 

yAxis.scale().domain([ 
    0, 
    d3.max(chart_data, function (c) { return d3.max(c.points, function (v) { return v.rate; }); }) 
]); 

svg.select(".x.axis").call(xAxis); 
svg.select(".y.axis").call(yAxis); 

Были несколько других ошибок я установил их в Fiddle. Например, вам нужно рассчитать время для новой точки на основе последнего элемента в массиве, а не первого, иначе линия не сможет правильно интерполировать, так как его уже не непрерывная функция ... и это немного больше лаконичный способ сделать ваши обновления строки:

for (var i=0; i<chart_data.length; i++) { 
    linedata = chart_data[i]; 
    //delete first element of array 
    var removedPoint = linedata.points.shift(); 

    //create a new point 
    var lastpoint = linedata.points[linedata.points.length-1]; 
    var new_point = { 
     rate: removedPoint.rate, 
     created_at: lastpoint.created_at + 6000 
    }; 
    linedata.points.push(new_point); 
} 

Также обратите внимание, что вы не должны использовать для (вар в) петлю для массивов, это итерация свойств в объекте.

Есть еще некоторые проблемы, но я думаю, что это должно помочь вам преодолеть препятствие, на которое вы застряли. В любом случае, это выглядит здорово в действии!

+1

Отличный @reblace ... fenac должен дать вам фонтан для вас ... – sam

+0

СПАСИБО ВАМ ТАК, очень полезно !! – fenec

2

Fine фенака .. У вас очень много проблем, так как ваши данные не соответствуют вашим требованиям.

согласно http://bl.ocks.org/benjchristensen/1148374 Данные по оси x должны быть ()(массив данных))

Ваши данные что-то вроде этого

[objects,object,object], где каждый объект содержит один элемент XAxis значения .. так толкания и перемещение не возможно ..

попытка изменить формат данные (linedata.points) в массив (данные []) и попробовать его, что он работает ..

Вам просто нужно поместить все ценности в linedata.points в данный массиве [] и используйте это data[] to animate your line..

С вашего многострочным .. вам нужно создать 2D array и должны передать их соответствующим образом ...

Приветствие ..

Я обновил вашего jsfiddle

setInterval(function() { 
    console.log(linedata.points); 
    var v = linedata.points.shift(); // remove the first element of the array 
linedata.points.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end) 
    redrawWithoutAnimation(); 
}, 3000); 

http://jsfiddle.net/yr2Nw/9/

Но все же это не будет работать, пока вы не сделаете эту работу ...

Личные Предложение: Сначала попробуйте с одной линии графа затем со сквозными для многострочного ...

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