I have below piece of code. I am using React and svg for bar charts. I am not using any third party library for charts. With this below piece of code, i am able to get the bar charts. But the issue is that my bar charts show horizontally, I want to show it vertically. I am not able to figure out how to get this same piece of code working for a vertical bar chart.
I saw one video online https://egghead.io/lessons/javascript-build-a-bar-chart-with-svg-from-scratch-with-react This guy is able to achieve the bar chart vertically. I am not sure where i am going wrong in displaying it. Any changes i do or try, it always show horizontal bar chart.
export const ReleaseScopeCharts = () => {
const data = [
{
"name": "Transit",
"passed": 2,
"skipped": 5,
"failed": 22,
},
{
"name": "Access",
"passed": 7,
"skipped": 2,
"failed": 11,
}
]
const fontSize=14
const width=1000
const rowHeight=40
const colors = ["#30D158", "#005EA7", "#FF453A"];
const entries = data.map((d) => ({
name: d.name,
total: d.total,
bars: ["passed", "skipped", "failed"].map((key, i) => ({
value: d[key],
portion: d[key] / 29,
color: colors[i]
}))
.filter((bar) => bar.value)
}))
const heightPerRow = rowHeight;
const canvasHeight = entries.length * heightPerRow;
const canvasWidth = width;
const labelWidth = canvasWidth / 4;
const plotWidth = canvasWidth - labelWidth;
const verticalPadding = heightPerRow / 2;
const barHeight = heightPerRow - verticalPadding;
const horizontalPadding = 0;
const rows = entries.map((entry, i) => {
const widths = entry.bars.map((bar) => plotWidth * bar.portion)
const offsets = entry.bars.map((bar, i, array) => {
const previous = array.slice(0, i);
const offset = previous.map((bar) => bar.portion)
.reduce((a, b) => a + b, 0)
return offset + bar.portion / 2
})
const bars = entry.bars.map((bar, i) => {
const barWidth = widths[i] - horizontalPadding;
return (<g key={i} transform={`translate(${plotWidth * offsets[i]}, ${heightPerRow / 2})`}>
<rect
rx={barHeight / 2} ry={barHeight / 2} width={barWidth} height={barHeight} fill={bar.color} x={-barWidth / 2} y={-barHeight / 2} />
<text fill={"#fff"} fontSize={fontSize} textAnchor={"middle"} alignmentBaseline={"middle"}>{bar.value}</text>
</g>)
})
return (
<g key={i} transform={`translate(${labelWidth},${heightPerRow * i})`}>
<g transform={`translate(${-labelWidth}, ${heightPerRow / 2})`}>
<text
fontSize={fontSize}
textAnchor={"start"}
alignmentBaseline={"middle"}>{entry.name}</text>
</g>
{bars}
</g>
)
})
return (
<div className="new-card">
<div>
</div>
<svg viewBox={`0, 0, ${canvasWidth}, ${canvasHeight}`}
height={canvasHeight}
width={canvasWidth}
>
{rows}
</svg>
</div>
)}
Can someone please help me figure out where i went wrong.