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

时间:2018-11-04 05:04:51

标签: javascript json d3.js

我是D3的新手。我有一个不错的example of a candlestick chart,可以从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);
    }
}

ajax调用返回良好的json数组数据,并将其转换为newData,该数据具有正确解析的日期,且字段名称小写为reqd。这是每个的摘要:

  

getQuoteHistory:data =“ [{\” Symbol \“:\” A \“,\” Date \“:\” 2018-06-28 \“,\” Open \“:\” 61.13 \“, \“ High \”:\“ 61.64 \”,\“ Low \”:\“ 60.42 \”,\“ Close \”:\“ 61.29 \”,\“ Volume \”:\“ 15641 \”},{ \“ Symbol \”:\“ A \”,\“ Date \”:\“ 2018-06-29 \”,\“ Open \”:\“ 61.68 \”,\“ High \”:\“ 62.47 \ “,\”低\“:\” 61.57 \“,\”关闭\“:\” 61.84 \“,\”音量\“:\” 18860 \“}}

     

getQuoteHistory:newData = [{“ date”:“ 2018-06-28T06:00:00.000Z”,“ open”:“ 61.13”,“ high”:“ 61.64”,“ low”:“ 60.42”, “ close”:“ 61.29”,“ volume”:“ 15641”},{“ date”:“ 2018-06-29T06:00:00.000Z”,“ open”:“ 61.68”,

现在失败发生在此行的绘制函数中:

svg.selectAll("g.candlestick").datum(data).call(candlestick);  

chrome javascript控制台显示“未定义svg”的地方。

但是它在html中定义:

    <svg></svg>

即使我将svg作为参数传递给draw方法,它也会显示“无法读取未定义的selectAll属性”。

有什么想法如何使它从json数组而不是csv文件工作?

2 个答案:

答案 0 :(得分:1)

您需要在svg中重新选择function draw(data),因为变量var svg是局部变量,仅在ajax调用的success函数中定义。< / p>

只需添加:

function draw(data) {
  var svg = d3.select("svg");
  // The rest of your function
}

答案 1 :(得分:0)

这是工作代码。感谢所有贡献者。我从你们每个人那里学到了要使它生效。

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内容。