линейный график d3 с логикой enter-update-exit

сегодня я создал простую гистограмму с логикой ввода-обновления-выхода - все работает нормально. Теперь я сделаю то же самое с линейной диаграммой - весь набор данных для диаграммы может измениться в любое время, поэтому я буду обновлять диаграмму плавно. Я не могу найти хороший пример с линейной диаграммой и логикой ввода-обновления-выхода (или я смотрю неправильно). В настоящее время я должен помнить, что если диаграмма вызывается в первый раз или данные для обновления (данные изменились) - это моя грязная версия:

   var channelGroup = d3.select(".ch1");

// init. Line Chart 
    if (firstLoad) {
    channelGroup
        .append('path')
        .attr("class", "line")
        .style("stroke", channel.Color)
        .transition()
        .ease("linear")
        .duration(animChart / 2)
        .attr('d', line(channel.DataRows));
}
// update Line Chart    
else {
    channelGroup
        .selectAll("path")
        .data([channel.DataRows])
        .transition()
        .ease("linear")
        .duration(animChart / 2)
        .attr("d", function (d) { return line(d); });
}  

Как я могу понять это в хорошем смысле?... thx!

1 ответов


вы смешиваете два разных подхода: один привязывает данные к строке, а другой просто передает данные функции line. Любой из них может работать (пока у вас есть только одна строка), но если вы хотите избавиться от своей конструкции if/else, вам все равно нужно будет отделить операторы, обрабатывающие ввод/добавление элемента, от операторов, обновляющих его.

1 (не связывайте данные, просто вызовите функция):

var linegraph = channelGroup.select('path');

if ( linegraph.empty() ) {
     //handle the entering data
     linegraph = channelGroup.append('path')
                      .attr("class", "line")
                      .style("stroke", channel.Color);
}

linegraph
        .transition()
        .ease("linear")
        .duration(animChart / 2)
        .attr('d', line(channel.DataRows));

2 (используйте соединение данных):

var linegraph = channelGroup.selectAll("path")
        .data([channel.DataRows]);

linegraph.enter().append('path')
                 .attr("class", "line");

linegraph
        .transition()
        .ease("linear")
        .duration(animChart / 2)
        .attr("d", line); //This is slightly more efficient than
                          //function (d) { return line(d); }
                          //and does the exact same thing.
                          //d3 sees that `line` is a function, and 
                          //therefore calls it with the data as the 
                          //first parameter.