2016-03-08 2 views
0

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

function myFunc(data) { 
console.log(data); 
} 

d3.json('file.json', function (data) { 
var json = data; 
myFunc(json); 
} 

Я работаю с d3 в диаграммы рассеяния. Мое первое подключение просто добавляет две строки моей таблицы в оба массива. Каждая строка представляет точку. Когда я нажимаю на одну из этих точек, происходит соединение с базой данных, и ссылки на эту выбранную точку отображаются на графике в виде других точек. И они добавляются в массив baseData, а libraryData остается неизменным. Когда я нажимаю правой кнопкой мыши на одну из этих точек, эта точка добавляется в массив libraryData. Но, как указано в коде, экземпляры библиотекиData вне функции не были обновлены. Ниже мой код

var libraryData = []; 
var baseData = []; 


d3.json("connection4.php", function(error,dataJson) { 

dataJson.forEach(function(d) { 
    d.YEAR = +d.YEAR; 
    d.counter = +d.counter; 
    libraryData.push(d); 
    baseData.push(d); 
    }) 

var circles = svg.selectAll("circle") 
     .data(libraryData) // libraryData here remains unchanged even after librayData has been updated in the function below! 
     .enter() 
     .append("circle") 
     .attr("class", "dot") 
     .attr("r", 3.5) 
     .attr("cx", function(d) {return x(YearFn(d))}) 
     .attr("cy", function(d) {return y(Num_citationsFn(d))}) 
     .style("fill","blue") 
     .on("click", clickHandler) 

function clickHandler (d, i) { 

    d3.json("connection2.php?paperID="+d.ID, function(error, dataJson) { 

       dataJson.forEach(function(d) { 

        d.YEAR = +d.YEAR; 
        d.counter = +d.counter; 

       baseData.push(d); 

       }) 

var circles = svg.selectAll("circle") 
           .data(baseData) 
           .enter() 
           .append("circle") 
           .attr("class", "dot") 
           .attr("r", 3.5) 
           .attr("cx", function(d) {return x(YearFn(d))}) 
           .attr("cy", function(d) {return y(Num_citationsFn(d))}) 
           .style("fill", "red") 
           .on("contextmenu", rightClickHandler); 
}) 

function rightClickHandler (d, i) { 

    d3.json("connection6.php?paperID="+d.ID, function(error, dataJson) { 

       }) 

      d3.select(this) 
       .style("fill", "blue"); 

     libraryData.push(d); 
     console.log(libraryData);// updated 

    } 
console.log(libraryData)// not updated 

}); 

Я новичок в d3, и я был бы признателен за любую помощь и обратную связь заблаговременно!

ответ

1

Это не сфера, это вопрос времени

function rightClickHandler (d, i) { 

    d3.json("connection6.php?paperID="+d.ID, function(error, dataJson) { 

       }) 

      d3.select(this) 
       .style("fill", "blue"); 

     libraryData.push(d); 
     console.log("I bet I'm second", libraryData);// updated 

    } 
console.log("I bet I'm first", libraryData)// not updated 

}); 

function(error, dataJson) в вызове JSon выполняется только один раз JSON возвращается из вашей функции PHP, которая может занять некоторое время. Между тем, ваша программа выполняет второй вызов console.log сразу же, и перед тем, как функция в json-вызове добавила что-нибудь в libraryData.

Run выше с изменениями в console.log, чтобы увидеть

В принципе все, что вы хотите сделать, что зависит от данных библиотеки обновляемых должна быть вызвана внутри function(error, dataJson)

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