d3.js条形图将新数据添加到条形图上,

尼古拉

请参见下面的代码。数据是随机从googlesheets产生,当获得随机数据按钮被选择时,数据被从谷歌片检索。选择新表格按钮后,将显示条形图。

但是,如果显示第一个值的第一个条形图为5,并且当数据更新且该值应为1时,条形图看起来像6。

我不想删除矩形,因为我确实想进行一些过渡以显示条形的增加和减少。我目前正在使用:http : //d3js.org/d3.v3.min.js

<body>
<div id="change">
  <input type="button" 
    style = "margin-right: 450px;"
    value="New Table" 
    onclick="test()" />
</div>         

<div id="option">
  <input type="button" 
    style = "margin-right: 450px;"
    value="Different Random Data" 
    onclick="remove()"  />
</div>


<div id="table"></div>
<div id="myclonediv"></div>

<script>
  updateCode()
  var canvas = d3.select("body").append("svg")
    //width and height
    .attr("width", 300)
    .attr("height", 1000);

  function test() {
    var source = document.getElementById('table');
    var destination = document.getElementById('myclonediv');
    var copy = source.cloneNode(true);
    copy.setAttribute('id', 'myclonediv');
    destination.parentNode.replaceChild(copy, destination);

    //d3.selectAll("rect").remove();
    //d3.selectAll("text").remove();

    createGraph()
  }

  function createGraph() {
    d3.csv(googlesheets, function(data) {

      //create container - canvas

      //svg = d3.select("svg")

      //add bars  - rectangle 
      canvas.selectAll('svg')
        .data(data)
        .enter()
        .append('rect')
        //width - d will reference data, d.age - from csv file * 10 so bars are bigger
        .attr("width", function(d) { return d.Random * 10})
        //was 50 now 48 to allow space between bars
        .attr("height", 48)
        // y function of the index, for each element
        .attr("y", function(d, i) { return i *50})
        //colour blue
        .attr("fill", "blue");

        //.transition()
        //.delay(function(d,i){return i *300;})
        //.duration(100000)
        //.attr("opacity", 1)

        //var newData = parsedCSV.replace(',', '');
        //var test = parsedCSV.substring(parsedCSV.indexOf(",") + 1);

      //text = d3.select("text")
      //add text to each bar - repeat before
      canvas.selectAll("svg")
        .data(data)
        .enter()
        .append("text")
        //white text
          .attr("fill", "red")
          //same position on each bar -- + 24 is half of 48 in height -- now middle of bar
          .attr("y", function(d,i) { return i *50+24})
          //what text - d.name
          .text(function(d) { return d.Random; }) 

    }); 


  }

  function remove() {
    var tableCode = d3.select("#table");
    tableCode.selectAll("*").remove();
    updateCode()
  }


  function updateCode() {
    var tabulate = function (data,columns) {                      
       var table = d3.select('#table').append('table')
       var thead = table.append('thead')
       var tbody = table.append('tbody')

       thead.append('tr')
         .selectAll('th')
         .data(columns)
         .enter()
         .append('th')
           .text(function (d) { return d })

       var rows = tbody.selectAll('tr')
         .data(data)
         .enter()
         .append('tr');

       var cells = rows.selectAll('td')
         .data(function(row) {
            return columns.map(function (column) {
                return { column: column, value: row[column] }
            })
         })
         .enter()
         .append('td')
         .text(function (d) { return d.value })

      return table;
   };

   d3.csv(googlesheets,function (data) {
     var columns = ['Test','Random']
     tabulate(data,columns);                
   });
 }  
</script>

</body>

如果我取消注释,此代码将完美工作

d3.selectAll("rect").remove();
d3.selectAll("text").remove();

但是正如我想显示的,当数据更新时,条形会增加和减少。

谢谢

旅鼠

我已经尝试简化问题并在适当的地方添加注释:

<body>

  <!-- only one button now. just to update the graph -->
  <div id="change">
    <input type="button" 
      style = "margin-right: 450px;"
      value="Update Graph" 
      onclick="updateGraph()" />
  </div>

  <script>
    // Create an svg element and append it to the page body
    // This svg element is now available via the canvas variable
    var canvas = d3.select("body").append("svg")
      //width and height
      .attr("width", 300)
      .attr("height", 1000)

    // Initialise the graph immediately when the screen loads
    createGraph();

    // I wasn't sure what data you were getting from the googledocs,
    // so instead of reading data from a csv file, the data is here
    // being generated on demand using this function.

    // generates a dataset of 5 objects
    function createRandomData() {
      var data = [];

      for(var i = 0; i < 5; i++) {
        data.push({
          // Generate random number from 3 to 10
          Random: Math.floor(Math.random() * 8) + 3
        });
      }
      return data;
    }

    function createGraph() {

      // generate graph data
      var data = createRandomData();

      // add bars  - rectangle 
      // In your original post, you were trying to select the svg
      // element, but what you need to do is select the rect elements
      // **even though they don't yet exist**.

      // Select all of the rect elements
      canvas.selectAll('rect')
        // There are 5 objects in the dataset, so there should be 5 rect elements
        .data(data)
        // Enter returns a selection for every data object 
        // that doesn't have a matching rect element on the page 
        // (in this case all 5 of them)
        .enter()
        // For each match returned by enter() append a rect
        .append('rect')
          // width - d will reference data, d.age - from csv file * 10 so bars are bigger
          .attr("width", function(d) { return d.Random * 10})
          // was 50 now 48 to allow space between bars
          .attr("height", 48)
          // y function of the index, for each element
          .attr("y", function(d, i) { return i * 50})
          // colour of blue is now also in proportion to value
          .attr("fill", function(d) { return "rgb(0,0," + d.Random * 20 + ")"; } );

      // Select all the text elements (none exist yet)
      canvas.selectAll("text")
        .data(data)
        // For each data item that doesn't yet have a text element
        // append a new one
        .enter()
          .append("text")
          .attr("fill", "white")
          // labels positioned along the x axis at the end of the bar
          .attr("x", function(d) { return (d.Random * 10) - 20; })
          // same position on each bar -- + 24 is half of 48 in height -- now middle of bar
          .attr("y", function(d,i) { return i * 50 + 24})
          .text(function(d) { return d.Random; });
    }

    // Clicking the button will trigger this function
    function updateGraph() {

      // generate new data
      var data = createRandomData();

      // update bars

      // This time when the rects are selected, there are a matching
      // number of existing rect elements and data items. So no need to call
      // enter() to create new elements.
      // Instead, the data values in the existing rects are updated,
      // and a transition is made over the specified duration
      // to the new values.
      canvas.selectAll('rect')
        .data(data)
        .transition()
        .duration(500)
          //width - d will reference data, d.age - from csv file * 10 so bars are bigger
          .attr("width", function(d) { return d.Random * 10})
          //colour blue
          .attr("fill", function(d) { return "rgb(0,0," + d.Random * 20 + ")"; });

      // update labels
      canvas.selectAll("text")
        .data(data)
        .transition()
        .duration(500)
          .attr("fill", "white")
          // labels positioned along the x axis at the end of the bar
          .attr("x", function(d) { return (d.Random * 10) - 20; })
          // same position on each bar -- + 24 is half of 48 in height -- now middle of bar
          .attr("y", function(d,i) { return i * 50 + 24})
          .text(function(d) { return d.Random; });
    }

  </script>

</body>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章