JSFiddle - React, Tailwind, and code Playground
by Paco86
HTML
<div id="chart">
<div id="tooltip"></div>
</div>
<hr>
<button class="update">update</button>
<button class="add">Add</button>
<button class="remove">Remove</button>
CSS
#chart {
width: 100%;
max-width: 600px;
height: 300px;
margin: 0 auto;
position: relative;
}
button {
display: block;
margin: 0 auto;
}
/* rect:hover {
fill: #82660D;
transition: 500ms all ease-in;
} */
text {
pointer-events: none;
}
#tooltip {
position: absolute;
width: 75px;
padding: 10px;
background-color: #fff;
border-radius: 10px;
border: 1px solid #000;
pointer-events: none;
display: none;
}
JavaScript
const charData = [
{key: 0, num: 10},
{key: 1, num: 14},
{key: 2, num: 7},
{key: 3, num: 9},
{key: 4, num: 11},
{key: 5, num: 12},
{key: 6, num: 13},
{key: 7, num: 22},
{key: 8, num: 14},
{key: 9, num: 25},
{key: 10, num: 18},
{key: 11, num: 14},
{key: 12, num: 11},
{key: 13, num: 25},
{key: 14, num: 15},
{key: 15, num: 6},
];
const key = d => d.key;
let maxKey = charData.length;
let ascending = true;
const CHART_HEIGHT = 300;
const CHART_WIDTH = 600;
//const BAR_PADDING = 5;
const xScale = d3
.scaleBand()
.domain(d3.range(charData.length))
.rangeRound([0, CHART_WIDTH])
.paddingInner(0.05);
const yScale = d3
.scaleLinear()
.domain([
0,
d3.max(charData, d => d.num)
])
.range([0, CHART_HEIGHT]);
const svg = d3
.select('#chart')
.append('svg')
.attr('viewBox', '0 0 600 300')
.attr('preserveAspectRatio', 'xMinYMid')
/* .attr('width', CHART_WIDTH)
.attr('height', CHART_HEIGHT); */
svg.selectAll('rect')
.data(charData, key)
.enter()
.append('rect')
.attr('x', function(d, i){
//return i * (CHART_WIDTH / charData.length) ;
return xScale(i);
})
.attr('y', function(d){
return CHART_HEIGHT - yScale(d.num);
})
.attr('height', function(d){
return yScale(d.num);
})
.attr('width', function(d, i){
//return CHART_WIDTH / charData.length - BAR_PADDING;
return xScale.bandwidth();
})
.attr('fill', '#7ED26D')
.on('mouseover', function(d){
const thisBar = d3.select(this);
thisBar
.transition('updateColor')
.attr('fill', '#82660D');
const x = +thisBar.attr('x') + xScale.bandwidth() / 2;
const y = +thisBar.attr('y') / 2 + CHART_HEIGHT / 2;
d3
.select('#tooltip')
.style('left', x + 'px')
.style('top', y + 'px')
.style('display', 'block')
.text(d.num)
})
.on('mouseout', function(){
d3
.select(this)
.transition('updateColorBack')
.attr('fill', '#7ED26D')
d3
...