HorizontalBar Chart
The Horizontal Bar chart is the most simple form of chart that can be created with D3. Svg coordinates starts from top left corner of the screen and move towards the right so it's easier to create an element that starts from left and grows towards right. This makes it easy to create a horizontal chart with left base and growing towards right. At first, the data will be converted to pixel representation with D3 and then react and svg will be used for projection it on screen. I am using D3 with React. The data set used here is
const fruits=
[
{ name: "🍊", count: 21 },
{ name: "🍇", count: 13 },
{ name: "🍏", count: 8 },
{ name: "🍌", count: 5 },
{ name: "🍐", count: 3 },
{ name: "🍋", count: 2 },
{ name: "🍎", count: 1 },
{ name: "🍉", count: 1 }
] The count value will be projected on the horizontal x-scale with the help of linear scale from D3. The vertical y-axis will represent an individual item and will be using a band scale.
xScale=scaleLinear()
.domain([lowestValue,maximumValue])
.range([pixelStart,pixelEnd])
yScale=scaleBand()
.domain(allElements)
.range([pixelStart,pixelEnd])
.padding(space between bar items)The data will be used to create rect svg elements which will represent an individual bar.
<rect
x={xStartPixel}
y={yStartPixel}/>
width={how hight one bar will be}
height={how fat the bar will be}So the code is
const xScale = scaleLinear()
.domain([0, max(fruits, d => d.count)])
.range([margin.left, width - 3 * margin.right - margin.left])
const yScale = scaleBand()
.domain(fruits.map(d => d.name))
.range([margin.top, height - margin.bottom])
.padding(0.1)
<rect
key={index}
x={0}
y={yScale(a.name)}
width={xScale(a.count)}
height={yScale.bandwidth()}>The data fruits is looped through and the value a is provided to each rect
Next process is to add axis to indicate values on the axis. We will be using ticks property of linear scale as it will gives us an equal descending interval and we will use domain from band scale since the data is discontinous.
To add the axis we have used the line component and the text component from the svg.
<line
key={index}
x1={xScale(a)}
x2={xScale(a)}
y1={margin.top + 5}
y2={(margin.top * 0.95)}
/>
<text
key={'xScaleText-{index}'}
textAnchor="middle"
x={xScale(a)}
y={(margin.top * 0.75)}
>
{a}
</text>
<line
key='yScale-{index}'
x1={margin.left + 5}
x2={margin.left * 0.9}
y1={yScale(a) + yScale.bandwidth() / 2}
y2={yScale(a) + yScale.bandwidth() / 2}
/>
<text
key='yScaleText-$index'
textAnchor="end"
dy="0.3em"
x={margin.left * 0.75}
y={yScale(a) + yScale.bandwidth() / 2}
{a}
</text>Due to the formatting of code in html the Key tag are missing bracket in index. We have used line to create the tick and text to display the value. Some css was added on top for display asthetics. The ticks are displayed with the help of margins. The chart is moved inside by a fixed margin top and left where the ticks are placed.
Adding name to the axis to make it clear on what the axis data is.
To do this I added two text item with the index name and placed them in the spacing position with svg text.