Javascript 如何将json变量加载到D3中?
我是D3的新手。我有一个从csv文件加载数据的好程序。我得到了这个例子,但现在我想做同样的事情,除了从返回json数据的ajax调用加载数据。我不知道怎么做 在阅读了一些评论之后,我的第二次尝试是:Javascript 如何将json变量加载到D3中?,javascript,json,d3.js,Javascript,Json,D3.js,我是D3的新手。我有一个从csv文件加载数据的好程序。我得到了这个例子,但现在我想做同样的事情,除了从返回json数据的ajax调用加载数据。我不知道怎么做 在阅读了一些评论之后,我的第二次尝试是: function showChart() { var margin = {top: 20, right: 20, bottom: 30, left: 50}, width = $(window).width()*0.6 - margin.left - margin.right
function showChart() {
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = $(window).width()*0.6 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%Y-%m-%d");
var x = techan.scale.financetime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var candlestick = techan.plot.candlestick()
.xScale(x)
.yScale(y);
var xAxis = d3.axisBottom().scale(x);
var yAxis = d3.axisLeft().scale(y);
$.ajax("http://www.mycom.net/getQuoteHistory.php?symbol='A'", {
success: function(data) {
console.log("getQuoteHistory:data="+JSON.stringify(data));
var accessor = candlestick.accessor();
data = JSON.parse(data);
var newData = [];
for (var i=0; i<data.length; i++) {
var o = data[i];
var newObj = {};
newObj.date = parseDate(o.Date);
newObj.open = o.Open;
newObj.high = o.High;
newObj.low = o.Low;
newObj.close = o.Close;
newObj.volume = o.Volume;
newData.push(newObj);
}
console.log("getQuoteHistory:newData="+JSON.stringify(newData));
var svg = d3.select("svg")
.data(newData)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g").attr("class", "candlestick");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
svg.append("g")
.attr("class", "y axis")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price ($)");
// Data to display initially
draw(newData.slice(0, newData.length-20));
// Only want this button to be active if the data has loaded
d3.select("button").on("click", function() {
draw(newData);
}).style("display", "inline");
},
error: function() {
console.log("something went wrong in ajax call");
}
});
function draw(data) {
x.domain(data.map(candlestick.accessor().d));
y.domain(techan.scale.plot.ohlc(data, candlestick.accessor()).domain());
svg.selectAll("g.candlestick").datum(data).call(candlestick);
svg.selectAll("g.x.axis").call(xAxis);
svg.selectAll("g.y.axis").call(yAxis);
}
}
chrome javascript控制台显示“svg未定义”
但它是在html中定义的:
<svg></svg>
即使我将svg作为参数传递给draw方法,它也会说“无法读取属性selectAll of undefined”
您知道如何通过json数组而不是csv文件来实现这一点吗?您需要在
函数绘制(数据)
中重新选择svg
,因为您的变量var svg
是一个局部变量,它仅在ajax调用的success
函数中定义
只需添加:
function draw(data) {
var svg = d3.select("svg");
// The rest of your function
}
这是工作代码。感谢所有的贡献者。我从你们每个人身上学到了如何让这一切顺利进行
function showChart(symbol) {
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = $(window).width()*0.6 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%Y-%m-%d");
var x = techan.scale.financetime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var candlestick = techan.plot.candlestick()
.xScale(x)
.yScale(y);
var xAxis = d3.axisBottom().scale(x);
var yAxis = d3.axisLeft().scale(y);
$.ajax("http://www.mycom.net/getQuoteHistory.php?symbol='" +symbol +"'", {
success: function(data) {
console.log("getQuoteHistory:data="+JSON.stringify(data));
var accessor = candlestick.accessor();
data = JSON.parse(data);
data = data.slice(0, 200).map(function(d) {
return {
date: parseDate(d.Date),
open: +d.Open,
high: +d.High,
low: +d.Low,
close: +d.Close,
volume: +d.Volume
};
}).sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); });
console.log("getQuoteHistory:newData="+JSON.stringify(data));
var svg = d3.select("svg")
.data(data)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g").attr("class", "candlestick");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
svg.append("g")
.attr("class", "y axis")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price ($)");
draw(data,svg);
},
error: function() {
console.log("something went wrong in ajax call");
}
});
function draw(data,svg) {
x.domain(data.map(candlestick.accessor().d));
y.domain(techan.scale.plot.ohlc(data, candlestick.accessor()).domain());
svg.selectAll("g.candlestick").datum(data).call(candlestick);
svg.selectAll("g.x.axis").call(xAxis);
svg.selectAll("g.y.axis").call(yAxis);
}
}
可能有一种方法可以使用d3.json()实现这一点,并避免额外的ajax内容。您似乎正在使用jquery获取数据。你不需要!如果是json文件,请使用
d3.json
,如果是csv文件,请使用d3.csv
获取远程数据。另外,请显示您在记录数据时看到的内容。错误可能是告诉您数据
不是数组。请确保JSON记录中的字段相同,否则candlestick.accessor()
将找不到数据。我在timeParse中使用了小写的“y”而不是大写的“y”。还需要使用data=json.parse(data)将传入的json解析为javascript。现在问题已更改为编辑版本。@jrook:如何使用d3.json(…?据我所知,它需要一个文件。我没有文件,我有一个变量。我尝试了你的建议,它确实结束了错误,但产生了一个新的错误:“错误:属性d:预期数,…700742432895511 NaN l 10.4671616…”我正在考虑为您的答案打分,但是上面的@rioV8注释让我担心它可能不是正确的答案。您的svg变量必须在绘图(数据)中定义函数。在您的代码中,它是未定义的。@rioV8也是正确的:您可以在父作用域中定义它,将它作为参数传递,或在draw函数中重新选择它。但是第二条错误消息与数据本身或缩放方法有关,因为错误消息中有一个NaN。
function showChart(symbol) {
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = $(window).width()*0.6 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%Y-%m-%d");
var x = techan.scale.financetime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
var candlestick = techan.plot.candlestick()
.xScale(x)
.yScale(y);
var xAxis = d3.axisBottom().scale(x);
var yAxis = d3.axisLeft().scale(y);
$.ajax("http://www.mycom.net/getQuoteHistory.php?symbol='" +symbol +"'", {
success: function(data) {
console.log("getQuoteHistory:data="+JSON.stringify(data));
var accessor = candlestick.accessor();
data = JSON.parse(data);
data = data.slice(0, 200).map(function(d) {
return {
date: parseDate(d.Date),
open: +d.Open,
high: +d.High,
low: +d.Low,
close: +d.Close,
volume: +d.Volume
};
}).sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); });
console.log("getQuoteHistory:newData="+JSON.stringify(data));
var svg = d3.select("svg")
.data(data)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g").attr("class", "candlestick");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
svg.append("g")
.attr("class", "y axis")
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Price ($)");
draw(data,svg);
},
error: function() {
console.log("something went wrong in ajax call");
}
});
function draw(data,svg) {
x.domain(data.map(candlestick.accessor().d));
y.domain(techan.scale.plot.ohlc(data, candlestick.accessor()).domain());
svg.selectAll("g.candlestick").datum(data).call(candlestick);
svg.selectAll("g.x.axis").call(xAxis);
svg.selectAll("g.y.axis").call(yAxis);
}
}