D3图表刷新 - 执行顺序

时间:2014-01-04 06:05:51

标签: javascript php d3.js

编辑:嗨耶稣我已经更改了代码如下,但现在图表根本没有加载,错误是“未捕获语法错误 - 意外字符串”。我可能误解了你的建议。你能帮我纠正下面的代码吗。

更新代码:

function updateData(url, divid, complete) {
alert("Start for: "+divid);
    var margin = {top: 20, right: 0, bottom: 30, left: 30},
        width = 838 - margin.left - margin.right,
        height = 300 - margin.top - margin.bottom;

    var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);

    var y = d3.scale.linear()        
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(10);

    // Get the data again
    d3.json(url, function (error, data) {
        data.forEach(function (d) {
        alert(d.max_energy);
            d.max_energy = +d.max_energy;
        });

        // Scale the range of the data again 
        x.domain(data.map(function (d) {
            return d.xaxis;
        }));
        y.domain([0, d3.max(data, function (d) {
            return d.max_energy;
        })]);

        // Make the changes
        svg.selectAll(".bar") // change the bar
        .data(data) // Update the data within.
        // No `.enter()` and `.exit()` phase.
        .transition()
            .duration(750)
            .attr("x", function (d) {
            return x(d.xaxis);
        })
            .attr("y", function (d) {
            return y(d.max_energy);
        })
            .attr("height", function (d) {
            return height - y(d.max_energy);
        })
        if (complete) {
            complete();
        };
    }); 

alert("End for: "+divid);

};

更新的功能调用:

case "C120031":
    updateData( "/sma/sma-php/data.php?var=CDAY&id=C1200031", "#daychart", function() {
        updateData( "/sma/sma-php/data.php?var=CWEEK&id=C1200031", "#weekchart", function() {
            updateData( "/sma/sma-php/data.php?var=CMONTH&id=C1200031", "#monthchart", function() {
                updateData( "/sma/sma-php/data.php?var=CYEAR&id=C1200031", "#yearchart", fucntion() {
                    updateData( "/sma/sma-php/data.php?var=CLIFE&id=C1200031", "#lifechart" );
                });
            });
        });
    });
    break;

我有一个包含5个标签的页面,每个标签都有一个D3条形图,分别从MySql数据库中提取。我只在下面的代码中显示三个,以尽量减少这篇文章中的文字数量。

我还在页面上有一组可选择的字段,因此当用户点击其中一个字段时,图表应刷新与选择相关的数据。图表是通过服务器端脚本的JSON数据传输创建的。

问题是我无法让图表“刷新”,尽管我在执行时没有语法错误。奇怪的是,当我在代码中添加“警报”时,我看到的是:

所有查询调用都按编程顺序执行,但数据在所有查询执行结束时被解析回来......所以图表不会更新。

为了更好地解释,我的客户端代码:

function MenuSelect(divid){

switch(divid)
{
    case "C120031":

       alert("Calling Day");            <--------- alert message at start of main proc
       updateData( "/sma/sma-php/data.php?var=CDAY&id=C1200031", "#daychart" );

       alert("Calling Week");
       updateData( "/sma/sma-php/data.php?var=CWEEK&id=C1200031", "#weekchart" );

       alert("Calling Month");
       updateData( "/sma/sma-php/data.php?var=CMONTH&id=C1200031", "#monthchart" );

    break;

    case "C120048":
... MANY OTHER INSTANCES HERE ...
    break;

    default:
    };
};

function updateData(url, divid) {

alert("Start for: "+divid);             <--------- alert message at start of sub proc

    var margin = {top: 20, right: 0, bottom: 30, left: 30},
        width = 838 - margin.left - margin.right,
        height = 300 - margin.top - margin.bottom;

    var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);

    var y = d3.scale.linear()
        .range([height, 0]);

    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .ticks(10);

    // Get the data again
    d3.json(url, function (error, data) {
        data.forEach(function (d) {

            alert(d.max_energy);  <--------- alert message listing raw data 

            d.max_energy = +d.max_energy;
        });

        // Scale the range of the data again 
        x.domain(data.map(function (d) {
            return d.xaxis;
        }));
        y.domain([0, d3.max(data, function (d) {
            return d.max_energy;
        })]);

        // Make the changes
        svg.selectAll(".bar") // change the bar
        .data(data) // Update the data within.
        // No `.enter()` and `.exit()` phase.
        .transition()
            .duration(750)
            .attr("x", function (d) {
            return x(d.xaxis);
        })
            .attr("y", function (d) {
            return y(d.max_energy);
        })
            .attr("height", function (d) {
            return height - y(d.max_energy);
        })
    }); 

alert("End for: "+divid);              <--------- alert message at end of sub proc

};

执行期间报告的方式是:

首先它显示进入和退出“updateData”功能,如下所示。

"Calling Day"
"Start for #daychart"
"End for #daychart"
"Calling Week"
"Start for #weekchart"
"End for #weekchart"
"Calling Month"
"Start for #monthchart"
"End for #monthchart"

它列出了每个查询运行的所有数据,按顺序列出。

"0.000"
"1.345"
"1.679"

这告诉我“updateData”的执行没有等到完成(也就是它不等待从服务器获得响应),然后再继续执行“updateData”的下一次执行。

我错过了什么?我需要编写代码来顺序执行并等待服务器响应,然后再转到下一次执行。

顺便说一句,如果我让代码只执行一个“updateData”实例,它就会以类似的方式工作,从而在显示带有数据的警报之前发生启动和结束警报。

有趣的是,页面首先使用相同的服务器端程序(data.php)从MySQL中提取数据并加载到“创建图表”D3 js中,并且它完美且顺序地工作。也许我的“updateData”程序编码错了?我在检查/控制台中没有收到任何语法错误...

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

d3.json异步执行。也就是说,updateData调用将返回并在d3.json完成之前继续下一次调用。为了解决这个问题,您可以将回调传递给updateData函数并链接后续调用:

updateData("", "", function() {
    updateData("", "", function() {
        updateData("", "");
     });
});

updateData(url, vivid, complete) {
    d3.json(.., function(...) {
        //all other code 
        if (complete) {
            complete();
        }
    });
}

答案 1 :(得分:0)

从进一步的调查结果可知,来自代码执行的数据排序是正确的。我有一个不同的问题,为什么它不工作,因为重绘图表的代码是在D3.json回调函数...问题现在已经发展到无法转换轴也没有放置值标签酒吧。条形图数据正在转换OK。 I have a jsfiddle here展示了这个问题。 Muchas gracias!

// Get the data again
//      d3.json("http://10.0.0.13/sma/sma-php/inverterdata.php?var=PDAY&id=P100023", function (error, data) {
data.forEach(function (d) {
    d.max_energy = +d.max_energy;
});

// Scale the range of the data again 
x.domain(data.map(function (d) {
    console.log(d.xaxis);
    return d.xaxis;
}));
y.domain([0, d3.max(data, function (d) {
    return d.max_energy;
})]);

// Make the changes
svg.selectAll(".bar") // change the bar
.data(data) // Update the data within.
.transition().delay(function (d, i) {
    return i / data.length * 1000;
})
    .duration(500)
    .attr("x", function (d) {
    return x(d.xaxis);
})
    .attr("y", function (d) {
    return y(d.max_energy);
})
    .attr("width", x.rangeBand())
    .attr("height", function (d) {
    return height - y(d.max_energy);
});

//Update all labels
svg.selectAll("text")
    .data(data).transition()
    .delay(function (d, i) {
    return i / data.length * 1000;
})
    .duration(500)
    .text(function (d) {
    return parseFloat(Math.round(d.max_energy * 100) / 100).toFixed(1);
})
    .attr("x", function (d, i) {
    return x(i) + x.rangeBand() / 2;
})
    .attr("y", function (d) {
    return height - y(d.max_energy) + 24;
});

//});