编辑:嗨耶稣我已经更改了代码如下,但现在图表根本没有加载,错误是“未捕获语法错误 - 意外字符串”。我可能误解了你的建议。你能帮我纠正下面的代码吗。
更新代码:
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”程序编码错了?我在检查/控制台中没有收到任何语法错误...
非常感谢任何帮助。
答案 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;
});
//});