Javascript 如何将json变量加载到D3中?

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

我是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,
        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);
    }
}