добавить несколько графиков d3, nvd3, используя для цикла

0

Я пытаюсь создать несколько диаграмм, используя nvd3 и d3. У меня есть правильное количество div.

Если я удалю forloop, я получаю диаграмму в #chart1. Если я поставлю цикл for, тогда я получаю диаграмму ТОЛЬКО в #chart2.

Может ли кто-нибудь понять, почему?

for (var j = 1; j <= 2; j += 1) {
    var s = '#chart' + j.toString() + ' svg';
    console.log(s);

    nv.addGraph(function() {
        var chart = nv.models.lineChart();

        chart.xAxis.axisLabel('Time step').tickFormat(d3.format(',r'));
        chart.yAxis.axisLabel('eig(' + j.toString() + ')').tickFormat(d3.format('.02f'));
        d3.select(s).datum(function() {

            var sin = [], cos = [];
            for (var i = 0; i < 100; i++) {
                sin.push({
                    x : i,
                    y : Math.sin(i / 10)
                });
                cos.push({
                    x : i,
                    y : .5 * Math.cos(i / 10)
                });
            }

            result = [];
            result.push({
                values : sin,
                key : 'sin',

            });

            return result;
        }).transition().duration(500).call(chart);

        nv.utils.windowResize(chart.update);
        return chart;
    });
}
Теги:
d3.js
nvd3.js

2 ответа

2
Лучший ответ

Во-первых, не так просто использовать цикл for, как и у вас (Data Driven Documents). В d3 предпочтительнее выбрать все элементы, которые вы хотите, и использовать .each() так

d3.selectAll('.chart svg')
    .each(function(data){
        // Do what you would have done in the loop here
})

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

nv.addGraph(addMyChart(this))

См. Этот JSFiddle http://jsfiddle.net/a5BYP/

1

Наткнулся на это, когда я столкнулся с той же проблемой. Надеюсь, это поможет другому начинающему, как я.

nv.addGraph() выполняет функцию обратного вызова. Эта функция, которую вы передали, не выполняется немедленно, а вместо этого помещается в цикл событий и выполняется через некоторое время. Internal nv.addGraph на самом деле довольно прост и использует setTimeout.

Причина, по которой for-loop не работает, связана с тем, что Javascript просматривается. Это по той же причине, почему этот код печатает 5 5 раз вместо 0,1,2,3,4.

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i)
    }, 0)
} 

В JS, то var ключевое слово объявляет переменную в функции вшита сферы (он игнорирует блок сферы - for или, if фигурные скобки). Если вы поместите весь вышеприведенный код в $() то переменная i будет доступна везде внутри $().

Когда функция обратного вызова выполнена, она имеет доступ к родительской среде, где она была впервые объявлена.

Внутри функции обратного вызова он встречает i. Поскольку i не объявляется внутри функции обратного вызова, он идет на один уровень, чтобы искать i. Он находит i в функции вшита сферы, но i переменная уже была обновлена до 5, прежде чем функция обратного вызова даже запустить.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню