简体   繁体   中英

How to change bars color on mouse hover on d3 using join?

How can I add interactivity to a bar chart in d3 using join? For example in following code (full code in on codesandbox ), how can I delete a bar when I click on it?

rectG
  .selectAll('rect')
  .data(data)
  .join(
    (enter) =>
      enter
        .append('rect')
        .attr('width', xScale.bandwidth())
        .attr('height', 0)
        .attr('y', (d) => innerDimensions.height)
        .attr('x', (d) => xScale(d.country))

        .attr('fill', 'steelblue')
        .attr('stroke', 'black')
        .attr('stroke-width', 2)
        .call((enter) =>
          enter
            .transition()
            .duration(1000)
            .attr('y', (d) => yScale(d.population))
            .attr(
              'height',
              (d) => innerDimensions.height - yScale(d.population)
            )
        ),

    (update) => update.attr('fill', 'orange')
  );

Here is a index.js with a click callback that deletes a bar:

import * as d3 from "d3";

let _data = [
  {
    id: 0,
    country: "China",
    population: 1400000000
  },
  {
    id: 1,
    country: "India",
    population: 1200000000
  },
  {
    id: 2,
    country: "USA",
    population: 450000000
  },
  {
    id: 3,
    country: "Russia",
    population: 145000000
  }
];

const update = data => {
  const dimensions = {
    width: 600,
    height: 600
  };

  const margins = {
    left: 100,
    top: 20,
    right: 20,
    bottom: 100
  };

  const innerDimensions = {
    width: dimensions.width - margins.left - margins.right,
    height: dimensions.height - margins.top - margins.bottom
  };

  const xScale = d3
    .scaleBand()
    .domain(data.map((d) => d.country))
    .range([0, innerDimensions.width])
    .padding(0.1);

  const yScale = d3
    .scaleLinear()
    .domain([0, d3.max(data, (d) => d.population)])
    .range([innerDimensions.height, 0]);

  const xAxis = d3.axisBottom(xScale);
  const yAxis = d3
    .axisLeft(yScale)
    .tickFormat((n) => d3.format("0.2s")(n).replace("G", "B"));

  d3.select("#canvas").selectAll('svg').remove();

  const svg = d3
    .select("#canvas")
    .append("svg")
    .attr("width", dimensions.width)
    .attr("height", dimensions.height);

  const rectG = svg
    .append("g")
    .attr("width", innerDimensions.width)
    .attr("height", innerDimensions.height)
    .attr("transform", `translate(${margins.left}, ${margins.top})`);

  const xAxisG = rectG
    .append("g")
    .attr("class", "x-axis")
    .attr("transform", `translate(0,${innerDimensions.height})`)
    .call(xAxis);

  const yAxisG = rectG.append("g").attr("class", "y-axis").call(yAxis);

  rectG
    .selectAll("rect")
    .data(data)
    .join((enter) =>
      enter
        .append("rect")
        .on('click', (e, d) => {
          const newData = data.filter(item => item.id !== d.id);
          update(newData);
        })
        .attr("width", xScale.bandwidth())
        .attr("height", 0)
        .attr("y", (d) => innerDimensions.height)
        .attr("x", (d) => xScale(d.country))

        .attr("fill", "steelblue")
        .attr("stroke", "black")
        .attr("stroke-width", 2)
        .call((enter) =>
          enter
            .transition()
            .duration(1000)
            .attr("y", (d) => yScale(d.population))
            .attr("height", (d) => innerDimensions.height - yScale(d.population))
        )
    );
}

update(_data);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM