CodePudding user response:
const ReleaseScopeCharts = () => {
const data = [
{
name: 'Transit',
passed: 100,
skipped: 0,
failed: 0,
untested: 0
},
{
name: 'Transit',
passed: 25,
skipped: 50,
failed: 25,
untested: 0
},
{
name: 'Access',
passed: 0,
skipped: 0,
failed: 0,
untested: 100
}
];
// Basic style
const newCardStyle = {
display: 'flex'
};
const xtitle = {
color: 'red',
marginTop: '20%',
transform: 'rotate(-45deg)'
};
const contentStyle = {
display: 'flex',
flexFlow: 'column',
alignItems: 'center',
};
const width = 90;
const colors = ['#30D158', '#005EA7', '#FF453A', '#ffcc00'];
const entries = data.map(d => ({
name: d.name,
total: ['passed', 'skipped', 'failed', 'untested'].reduce(
(acc, key) => acc d[key],
0
),
bars: ['passed', 'skipped', 'failed', 'untested']
.map((key, i) => ({
value: d[key],
color: colors[i],
y:
key === 'passed'
? 0
: key === 'skipped'
? d['passed']
: d['skipped'] d['passed'],
}))
.filter(bar => bar.value),
}));
const rows = (entry, rowIndex) => {
return entry.bars.map((bar, index) => {
console.log('bar', entry, bar)
const graphHeight = 490 - 5;
const height = (bar.value / entry.total) * graphHeight;
const y = (bar.y / entry.total) * graphHeight;
return (
<>
<g key={Math.random()}>
<rect
width={50}
height={height}
fill={bar.color}
x={100 rowIndex * 60} // multiply with the width (50) 10 for space
y={490 - y - height}
/>
<text
x={125 rowIndex * 60} // visible centre point of your bar
y={490 - y - height/2}
dy="0.5em" // adjusts the text y position to adjust for text descenders.
textAnchor="middle" // centre the text horizontall at x
class="bar-label"
style={{ fill: 'white',
fontSize: '12px' }}// styling for this text
>{`${bar.color === '#ffcc00' && bar.value === 100 ? 'X': bar.value}`}</text>
<text
x={125 rowIndex * 60}
y={520}
textAnchor="middle"
class="bottom-label"
style={{ fill: '#000',
fontSize: '12px' }}
>label</text>
</g>
</>
);
});
};
return (
<div>
<div className="new-card" style={newCardStyle}>
<svg class="graph">
<g class="grid x-grid" id="xGrid">
<line x1="90" x2="90" y1="5" y2="490"></line>
</g>
<g class="grid y-grid" id="yGrid">
<line x1="90" x2="805" y1="490" y2="490"></line>
</g>
<g class="labels y-labels">
<text x="80" y="15">100</text>
<text x="80" y="131">75</text>
<text x="80" y="248">50</text>
<text x="80" y="373">25</text>
<text x="80" y="500">0</text>
<text x="60" y="200" class="label-title">Pass %</text>
</g>
<g>
{entries.map((entry, indx) => (
rows(entry, indx)
))}
</g>
</svg>
</div>
</div>
);
};
// Render the component to the browser
ReactDOM.render(
// Pass in props
<ReleaseScopeCharts />,
document.getElementById('root')
);
body {
font-family: 'Open Sans', sans-serif;
margin-top: 1rem;
}
.mGraph > svg {
position: relative;
left: -40rem;
top: -.65rem;
}
.mGraph > div {
position: relative;
left: -39rem;
top: -.65rem;
}
.mGraph > text {
position: relative;
left: -50rem;
}
.graph .labels.x-labels {
text-anchor: middle;
}
.graph .labels.y-labels {
text-anchor: end;
}
.graph {
height: 500px;
width: 1200px;
}
.graph .grid {
stroke: #ccc;
stroke-dasharray: 0;
stroke-width: 1;
}
.labels {
font-size: 13px;
}
.label-title {
font-weight: bold;
text-transform: uppercase;
font-size: 12px;
fill: black;
margin-left: 50%
}
.data {
fill: red;
stroke-width: 1;
}
svg{overflow: visible}
.bottom-label{font-weight: bold;}
<div id="root"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>