Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to filter a barchart by a "thrid" value using d3.js

I was able to plot a very simple barchart using D3.js version 7 that relates names with points from a dataset. In this same dataset there’s a third value that I would like to use to filter the barchart.

I can filter it by name or points already simply using:

.filter((d) => d.name = "OneA")
.filter((d) => d.points > 100000)

But if I try to filter the barchart data by status it doesn’t work. Nothing is filtered.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is the entire code:

// set margins, width and height
const MARGIN = { LEFT: 64, RIGHT: 2, TOP: 32, BOTTOM: 16 }
const WIDTH = 600 - MARGIN.LEFT - MARGIN.RIGHT
const HEIGHT = 400 - MARGIN.TOP - MARGIN.BOTTOM

// set svg
const svg = d3.select("#chart-area").append("svg")
  .attr("width", WIDTH + MARGIN.LEFT + MARGIN.RIGHT)
  .attr("height", HEIGHT + MARGIN.TOP + MARGIN.BOTTOM)

// set group
const g = svg.append("g")
  .attr("transform", `translate(${MARGIN.LEFT}, ${MARGIN.TOP})`)

// import data
d3.json("data/data.json").then(data => {
  // prepare data
  data
    .forEach(d => {
      d.points = Number(d.points)
    })

  // set scale, domain and range for x axis
  const x = d3.scaleBand()
    .domain(data.map(d => d.name))
    .range([0, WIDTH])
    .padding(0.1)
  
  // set scale, domain and range for y axis
  const y = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.points)])
    .range([HEIGHT, 0])

  // call x axis
  const xAxisCall = d3.axisBottom(x)
  g.append("g")
    .attr("class", "x axis")
    .attr("transform", `translate(0, ${HEIGHT})`)
    .call(xAxisCall)

  // call y axis
  const yAxisCall = d3.axisLeft(y)
  g.append("g")
    .attr("class", "y axis")
    .call(yAxisCall)

  // join data
  const rects = g.selectAll("rect")
    .data(data)

  // enter elements to plot chart
  rects.enter().append("rect")
    .filter((d) => d.status = "ON") // THIS IS NOT WORKING. WHY?
    .attr("x", (d) => x(d.name))
    .attr("y", d => y(d.points))
    .attr("width", x.bandwidth)
    .attr("height", d => HEIGHT - y(d.points))
    .attr("fill", "steelblue")
})

And json file with the data is:

[
    {
        "name": "OneA",
        "points": "492799",
        "status": "ON"
    },
    {
        "name": "TwoB",
        "points": "313420",
        "status": "ON"
    },
    {
        "name": "ThreeC",
        "points": "133443",
        "status": "ON"
    },
    {
        "name": "FourD",
        "points": "50963",
        "status": "OFF"
    },
    {
        "name": "FiveE",
        "points": "26797",
        "status": "OFF"
    },
    {
        "name": "SixF",
        "points": "13483",
        "status": "OFF"
    },
    {
        "name": "SevenG",
        "points": "12889",
        "status": "OFF"
    }
]

How is it possible to filter the barchart by status in this case?

>Solution :

You should compare values in filter statement with "==" (double equals signs)

rects.enter().append("rect")
    .filter((d) => d.status == "ON") // This Should work now
    .attr("x", (d) => x(d.name))
    .attr("y", d => y(d.points))
    .attr("width", x.bandwidth)
    .attr("height", d => HEIGHT - y(d.points))
    .attr("fill", "steelblue")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading