Home > OS >  Bars going beyond axis / axis too short and without correct range
Bars going beyond axis / axis too short and without correct range

Time:06-11

Can someone please tell me exactly where I'm doing wrong with the x-axis / length of bars in this bar chart. The x axis doesn't appear to have the right range, although I used the maximum value for the field of the data. And the bars are going beyond the x axis.

My x axis scale is set up like:

const x = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.sales_usd_billion)])
    .range([0, WIDTH])

Where WIDTH = 1000 - MARGIN.LEFT - MARGIN.RIGHT

and rects are:

    .attr("y", d => y(d.company)  3)
    .attr("x", 0)
    .attr("width", d => x(d.sales_usd_billion))
    .attr("height", d => 4)
    .attr("fill", "grey")

I've been through everything and can't see what needs changing.

The full code is below:

//Forbes companies bar chart 

//set up chart area
const MARGIN = { LEFT: 250, RIGHT: 10, TOP: 50, BOTTOM: 100 }
const WIDTH = 1000 - MARGIN.LEFT - MARGIN.RIGHT
const HEIGHT = 1100 - MARGIN.TOP - MARGIN.BOTTOM

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

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

// X label
g.append("text")
  .attr("class", "x axis-label")
  .attr("x", WIDTH / 2)
  .attr("y", HEIGHT   50)
  .attr("font-size", "20px")
  .attr("text-anchor", "middle")
  .text("Sales, Billions (USD)")

// Y label
g.append("text")
  .attr("class", "y axis-label")
  .attr("x", - (HEIGHT / 2))
  .attr("y", -200)
  .attr("font-size", "20px")
  .attr("text-anchor", "middle")
  .attr("transform", "rotate(-90)")
  .text("Company")

    //Import data
d3.csv("data/data_clean.csv").then(data => {
  data.forEach(d => {
    d.sales_usd_billions = Number(d.sales_usd_billion)
  })
const max = d3.max(data, d => d.value)
console.log(max)

data.sort(function(a, b) {
    return  b.rank - a.rank;
  })

const y = d3.scaleBand()
    .domain(data.map(d => d.company))    
    .range([HEIGHT, 0])

const x = d3.scaleLinear()
    .domain([0, d3.max(data, d => d.sales_usd_billion)])
    .range([0, WIDTH])


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


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

  const rects = g.selectAll("rect")
    .data(data)
  
  rects.enter().append("rect")
    .attr("y", d => y(d.company)  3)
    .attr("x", 0)
    .attr("width", d => x(d.sales_usd_billion))
    .attr("height", d => 4)
    .attr("fill", "grey")

   ;
})

Data snapshot:

rank,company,country,sales_usd_billion,sales_unit,profit_usd_billion,profit_unit,assets_usd_billion,market_usd_billion,sales_usd,profit_usd,assets_usd
1,Berkshire Hathaway,United States,276.09,B,89.8,B,958.78,741.48,276.09,89.8,958.78
2,ICBC,China,208.13,B,54.03,B,5518.51,214.43,208.13,54.03,5518.51
3,Saudi Arabian Oil Company (Saudi Aramco),Saudi Arabia,400.38,B,105.36,B,576.04,2292.08,400.38,105.36,576.04
4,JPMorgan Chase,United States,124.54,B,42.12,B,3954.69,374.45,124.54,42.12,3954.69
5,China Construction Bank,China,202.07,B,46.89,B,4746.95,181.32,202.07,46.89,4746.95
6,Amazon,United States,469.82,B,33.36,B,420.55,1468.4,469.82,33.36,420.55
7,Apple,United States,378.7,B,100.56,B,381.19,2640.32,378.7,100.56,381.19
8,Agricultural Bank of China,China,181.42,B,37.38,B,4561.05,133.38,181.42,37.38,4561.05
9,Bank of America,United States,96.83,B,31,B,3238.22,303.1,96.83,31,3238.22
10,Toyota Motor,Japan,281.75,B,28.15,B,552.46,237.73,281.75,28.15,552.46

CodePudding user response:

Seems to me like you're using the property sales_usd_billion which is a string, when you should be using sales_usd_billions which you converted to number.

  • Related