user3821345
user3821345

Reputation: 648

Using d3.filter in an update function

I am drawing a bar chart based on data for two different regions "lombardy" and "emiglia".

Below is an outtake of my code. First I draw the chart, by filtering on the region "lombardy". Now I would like to update the bars via a transition to use "d.value" from "emiglia".

g.select(".gdp").selectAll(".gdp-rect")
  .data(data)
  .enter()
  .append("rect")
  .classed("gdp-rect", true)
  .filter(function(d) {return (d.type == "gdp") })
  .filter(function(d) {return (d.region == "lombardy") })
  .attr('x', function(d, i) {
    return i * (width / 4)
  })
  .attr('y', function(d) {
    return h - yBarScale(d.value)
  })
  .attr('width', width / 4 - barPadding)
  .attr('height', function(d) {
    return yBarScale(d.value)
  })
  .attr("fill", "#CCC")
  .attr("opacity", 1);




function emiglia() {

  g.selectAll(".gdp-rect")
    .transition()
    .duration(600)
    .filter(function(d) {return (d.region == "gdp") })
    .filter(function(d) {return (d.region == "emiglia") })
    .attr('y', function(d) {
      return h - yBarScale(d.value)
    })
    .attr('height', function(d) {
      return yBarScale(d.value)
    })

}

Is it possible to update based on d3.filter? How can I toggle d.value for both regions?

data.tsv

type    region  year    value
gdp lombardy    2004    70
gdp lombardy    2008    50
gdp lombardy    2012    30
gdp lombardy    2016    110
gdp emiglia 2004    10
gdp emiglia 2008    15
gdp emiglia 2012    23
gdp emiglia 2016    70

Upvotes: 2

Views: 2207

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102198

There are several ways to do that, this is one of them:

To use filter in your update function, you have first to load the data...

d3.csv("data.csv", function(data){

...in an array called data. Then, inside d3.csv, you create your update function (here I'll call it draw) having the region as an argument, and filtering data based on this argument:

function draw(myRegion){

    var newData = data.filter(function(d){ return d.region == myRegion})

Now you use this new array (newData) to draw your bars.

This is an example using buttons to call the function draw: https://plnkr.co/edit/QCt1XgWxrSM8MlFijyxb?p=preview

(Caveat: in this example I'm using D3 v4.x, but I see that you're using D3 v3. So, this is just an example for you to see the general idea.)


Just a final tip: normally, we don't filter the data to change a visualization like this. The normal approach, let's call it the D3 way is simply creating your dataset with both Lombardy and Emiglia as columns:

type   year    lombardy  emiglia
gdp    2004    70        10
gdp    2008    50        15
gdp    2012    30        23
gdp    2016    110       70

That way, we could simply set the width of the bars using:

.attr("width", function(d){ return xScale(d[region])});

And setting region according to the column (Lombardy or Emiglia).

Upvotes: 3

Related Questions