简体   繁体   English

无法在D3.js中动态更新图形和坐标轴

[英]Not able to update the graph and axes both dynamically in D3.js

I am making a line chart using D3.js and my target is to dynamically update the graph(line path) as well as both the axes. 我正在使用D3.js制作折线图,我的目标是动态更新图形(折线路径)以及两个轴。 With the given code I am able to update the axis dyamically and update the line-path, but the issue is that previous line-path still shows on the chart. 使用给定的代码,我可以动态地更新轴并更新直线路径,但是问题是以前的直线路径仍显示在图表上。

How to remove the previous line-path? 如何删除先前的线路路径?

/*******************************   CHART PLOTTING FOR TWITTER SENTIMENT ************************/

/* implementation heavily influenced by http://bl.ocks.org/1166403 */ / *的实施受到http://bl.ocks.org/1166403的严重影响* /

    window.setInterval(refreshGraph, 3000);

    // while (true){
    //   plot();
    //   delay(5000);
    // }
    var data = [3, 6, 2, 7, 5, 2, 0, 3, 8, 9, 2, 5, 9, 3, 6, 3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 2, 7];

    // function plot(){
    // d3.json("/bigdata/v1/analytics/sentiment", function(d){
    // define dimensions of graph
    var m = [80, 80, 80, 80]; // margins
    var w = 1000 - m[1] - m[3]; // width
    var h = 400 - m[0] - m[2]; // height

    // create a simple data array that we'll plot with a line (this array represents only the Y values, X will just be the index location)

     // data = data.concat(d.values);
    // X scale will fit all values from data[] within pixels 0-w
    var x = d3.scale.linear().domain([0, data.length]).range([0, w]);
    // Y scale will fit values from 0-10 within pixels h-0 (Note the inverted domain for the y-scale: bigger is up!)
    var y = d3.scale.linear().domain(d3.extent(data)).range([h, 0]);
        // automatically determining max range can work something like this
        // var y = d3.scale.linear().domain([0, d3.max(data)]).range([h, 0]);

    // create a line function that can convert data[] into x and y points
    var line = d3.svg.line().interpolate("monotone")
        // assign the X function to plot our line as we wish
        .x(function(d,i) { 
            // verbose logging to show what's actually being done
            console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.');
            // return the X coordinate where we want to plot this datapoint
            return x(i); 
        })
        .y(function(d) { 
            // verbose logging to show what's actually being done
            console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale.");
            // return the Y coordinate where we want to plot this datapoint
            return y(d); 
        })

        // Add an SVG element with the desired dimensions and margin.
        //debugger;
        var graph = d3.select("#igraph").append("svg:svg")
              .attr("width", w + m[1] + m[3])
              .attr("height", h + m[0] + m[2])
            .append("svg:g")
              .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

        // create yAxis
        var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(true);
        // Add the x-axis.
        graph.append("svg:g")
              .attr("class", "x axis")
              .attr("transform", "translate(0," + h + ")")
              .call(xAxis);


        // create left yAxis
        var yAxisLeft = d3.svg.axis().scale(y).ticks(4).orient("left");
        // Add the y-axis to the left
        graph.append("svg:g")
              .attr("class", "y axis")
              .attr("transform", "translate(-25,0)")
              .call(yAxisLeft);

        // Add the line by appending an svg:path element with the data line we created above
        // do this AFTER the axes above so that the line is above the tick-lines
        graph.append("svg:path").attr("d", line(data));

      // });

 // to refresh the graph after interval of 3ms
function refreshGraph () {
  //debugger;
   d3.json("/bigdata/v1/analytics/sentiment", function(d){

  data = data.concat(d.values);
  /* var x = d3.scale.linear().domain([0, data.length]).range([0, w]);
  var y = d3.scale.linear().domain(d3.extent(data)).range([h, 0]);

//line.exit().remove
graph.selectAll(".xAxis")
    .transition()
    .duration(10)
    .call(xAxis);


graph.selectAll("line").data(data).enter()
 .append("svg:path")
 .attr("d", line(data))
 });
 */
  x.domain([0, data.length]);

 var t = graph.transition().duration(750);
 t.select(".x.axis").call(xAxis);

 graph.select("path.line").remove();

graph.selectAll("line").data(data).enter()
 .append("svg:path")
 .attr("d", line(data));


});
}
/*******************************   CHART PLOTTING FOR TWITTER SENTIMENT       ************************/

First, graph.select("path.line").remove() isn't removing anything, because there are no paths classed "line" in your view, since you're not assigning that class to the svg:path you're creating. 首先, graph.select("path.line").remove()不会删除任何内容,因为在您的视图中没有分类为"line"路径,因为您没有将该类分配给svg:path重新创建。 So, when you .append("svg:path") , you also need to run .classed('line', true) . 因此,当您.append("svg:path") ,还需要运行.classed('line', true)

Next, where you have graph.selectAll("line").data(data).enter() , you need to prefix "line" with a . 接下来,在具有graph.selectAll("line").data(data).enter() ,您需要在"line" graph.selectAll("line").data(data).enter()加上. , to make it select anything classed line . ,使其选择任何分类line

Finally — and this might not be a mistake, depending on how your API works — where you have data = data.concat(d.values) you're appending new data to the existing data, rather than replacing it. 最后,根据API的工作方式,这可能不是一个错误,在这里data = data.concat(d.values)是将新数据附加到现有数据上,而不是替换它们。 So if the API is returning the entire line data, then appending it to the existing data is inappropriate here. 因此,如果API返回整个行数据,则在此处将其附加到现有数据是不合适的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM