简体   繁体   中英

JavaScript D3 bar chart data will not update when new source is selected from drop down filter

so I am still really new to building visualizations in D3 using JavaScript and I seem to be really stuck with this problem. I have 4 csv data sets as shown below and I am trying to build a bar chart with a drop down filter that allows the user to select which data source they want to use. Ideally when the user selects either DataSet0.csv or DataSet1.csv I would like the bar chart to display the values from the 'Value1' field in the respective data sets, and when the user selects DataSet2.csv or Dataset3.csv I'd want the user to see values from the 'Value2' field in their respective data sets. That last part would just be a bonus though, for now I just really need to figure the filters out. I posted all of the code I have for this below. When I run it on a web browser I can select an initial data set from the drop down menu and it works fine. However, when I select another data-set from the drop down menu, it gets overlapped by the one previously existing chart. Thank you all for taking the time to help on this in advance! It's greatly appreciated!

DataSet0.csv

Letter,Value1,Value2
I,9968,8863
F,9938,9204
E,9875,8578
D,9859,9074
G,9856,9432
J,9778,9095
A,9729,8747
C,9695,8610
H,9609,8969
B,9508,9395

DataSet1.csv

Letter,Value1,Value2
I,1510,1495
E,1521,1312
C,1624,1370
H,1669,1031
A,1685,1256
D,1773,1178
J,1910,1129
B,1981,1331
F,1982,1032
G,1986,1463

DataSet2.csv

Letter,Value1,Value2
B,9516,9421
I,9537,9140
C,9772,9070
F,9527,9060
H,9747,8959
E,9992,8948
J,9576,8770
D,9748,8735
G,9963,8680
A,9557,8628

DataSet3.csv

Letter,Value1,Value2
I,1708,1016
H,1604,1096
G,1689,1106
D,1657,1115
F,1709,1131
C,1588,1221
A,1939,1309
J,1600,1332
B,1815,1344
E,1651,1478

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<style>

.bar {
  fill: steelblue;
}

.bar:hover {
  fill: brown;
}

.axis {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.x.axis path {
  display: none;
}

select {
  position: absolute;
  top: 10px
}

</style>
<body>
<select id="flter" name="flter" onchange="updateData(this.id)">
  <option value=""></option>
  <option value="DataSet0.csv">DataSet0</option>
  <option value="DataSet1.csv">DataSet1</option>
  <option value="DataSet2.csv">DataSet2</option>
  <option value="DataSet3.csv">DataSet3</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>

var margin = {top: 60, right: 60, bottom: 90, left: 120},
    width = 960 - margin.left - margin.right,
    height = 700 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(10, "$");

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.csv(fileName, type, function(error, data) {
  if (error) throw error;

  x.domain(data.map(function(d) { return d.Letter; }));
  y.domain([(d3.min(data, function(d) { return d.Value1; }) - 50), d3.max(data, function(d) { return d.Value1; })]);

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .selectAll("text")
       .style("text-anchor", "end")
       .attr("dx", "-.8em")
       .attr("dy", ".15em")
       .attr("transform", "rotate(-15)" );

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis)
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .style("text-anchor", "end")
      .text("Value1");

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.Letter); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.Value1); })
      .attr("height", function(d) { return height - y(d.Value1); });
});

function updateData(s){
    var s = document.getElementById(s);
    var fileName = s.value;
    d3.csv(fileName, type, function(error, data) {
        if (error) throw error;

        x.domain(data.map(function(d) { return d.Letter; }));
        y.domain([(d3.min(data, function(d) { return d.Value1; }) - 50), d3.max(data, function(d) { return d.Value1; })]);



        svg.append("g")
         .attr("class", "x axis")
         .attr("transform", "translate(0," + height + ")")
         .call(xAxis)
         .selectAll("text")
           .style("text-anchor", "end")
           .attr("dx", "-.8em")
           .attr("dy", ".15em")
           .attr("transform", "rotate(-15)" );

        svg.append("g")
           .attr("class", "y axis")
           .call(yAxis)
         .append("text")
           .attr("transform", "rotate(-90)")
           .attr("y", 6)
           .attr("dy", ".71em")
           .style("text-anchor", "end")
           .text("Value1");

        svg.selectAll(".bar")
           .data(data)
        .enter().append("rect")
           .attr("class", "bar")
           .attr("x", function(d) { return x(d.Letter); })
           .attr("width", x.rangeBand())
           .attr("y", function(d) { return y(d.Value1); })
           .attr("height", function(d) { return height - y(d.Value1); });
});
}

function type(d) {
  d.Value1 = +d.Value1;
  return d;
}
</script>
</body>
</html>

Use the general update pattern (carefully work through the three parts of the linked example and think about it for a bit. It's important if you want to understand d3)...

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<style>

  .bar {
    fill: steelblue;
  }

  .bar:hover {
    fill: brown;
  }

  .axis {
    font: 10px sans-serif;
  }

  .axis path,
  .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }

  .x.axis path {
    display: none;
  }

  select {
    position: absolute;
    top: 10px
  }

</style>
<body>
<select id="flter" name="flter" onchange="updateData(this.id)">
  <option value=""></option>
  <option value="DataSet0.csv">DataSet0</option>
  <option value="DataSet1.csv">DataSet1</option>
  <option value="DataSet2.csv">DataSet2</option>
  <option value="DataSet3.csv">DataSet3</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>

  var margin = {top: 60, right: 60, bottom: 90, left: 120},
    width = 960 - margin.left - margin.right,
    height = 700 - margin.top - margin.bottom,
    svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var x = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1, 0),
    xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom"),
    gX = svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")");

  var y = d3.scale.linear()
    .range([height, 0]),
    yAxis = d3.svg.axis()
      .scale(y)
      .orient("left")
      .ticks(10, "$"),
    gY = svg.append("g")
      .attr("class", "y axis");

  function updateData(s){
    var s = document.getElementById(s);

    var fileName = s.value;

    d3.csv(fileName, type, function(error, data) {
      if (error) throw error;

      x.domain(data.map(function(d) { return d.Letter; }));
      y.domain([(d3.min(data, function(d) { return d.Value1; }) - 50), d3.max(data, function(d) { return d.Value1; })]);

      gX.call(xAxis)
        .selectAll("text")
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform", "rotate(-15)" );

      gY.call(yAxis)
        // only add title once
        .selectAll(".title")
        .data(["Value1"])
        .enter().append("text").attr("class", "title")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text(function(d){
          return d
        });

      // GENERAL UPDATE PATTERN
      // UPDATE
      var bars = svg.selectAll(".bar")
        .data(data);
      // ENTER
      bars.enter().insert("rect", ".axis")
        .attr("class", "bar");
      // UPDATE+ENTER (calling enter() merges enter into update)
      bars.attr("x", function(d) { return x(d.Letter); })
        .attr("width", x.rangeBand())
        .attr("y", function(d) { return y(d.Value1); })
        .attr("height", function(d) { return height - y(d.Value1); });
      // EXIT
      bars.exit().remove();

    });
    function type(d) {
      d.Value1 = +d.Value1;
      return d;
    }
  }

</script>
</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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