【问题标题】:d3.js bar chart new data adding onto bars,d3.js 条形图将新数据添加到条形图上,
【发布时间】:2018-05-09 20:27:50
【问题描述】:

请看下面的代码。 Data is randomly generated from googlesheets, when get random data button is selected, data is retrieved from the google sheets.选择新表格按钮时,将出现条形图。

但是如果出现第一个值的第一个柱状图是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();

但我想在数据更新时显示条形图的增加和减少。

谢谢

【问题讨论】:

    标签: javascript d3.js append bar-chart


    【解决方案1】:

    我尝试稍微简化一下问题,并在适当的地方添加 cmets:

    <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>
    

    【讨论】:

      猜你喜欢
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多