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
   ...