javascript - 通过按下按钮更新条形图

标签 javascript d3.js bar-chart

我是 D3-v5 的新手,正在尝试创建带有更新按钮(随机值)的条形图。 我按照下面的代码创建了所有东西,

  <body>
    <button onclick="updateData()">Update</button>
    <!-- Bar Chart for SVG-->
    <svg width ="500" height="500" id="svg2">
    </svg>
<script src="https://d3js.org/d3.v5.min.js"></script>

<script>
  //Bar Chart
  //Creating data
  let data2 = [
      {name: 'A', value: Math.floor(Math.random() * 100)},
      {name: 'B', value: Math.floor(Math.random() * 100)},
      {name: 'C', value: Math.floor(Math.random() * 100)},
      {name: 'D', value: Math.floor(Math.random() * 100)},
      {name: 'E', value: Math.floor(Math.random() * 100)},
      {name: 'F', value: Math.floor(Math.random() * 100)},
      {name: 'G', value: Math.floor(Math.random() * 100)},
      {name: 'H', value: Math.floor(Math.random() * 100)},
      {name: 'I', value: Math.floor(Math.random() * 100)},
      {name: 'J', value: Math.floor(Math.random() * 100)}
  ]
  //Creating svg, margin, width, height
  let svg2 = d3.select("#svg2")
  let margin = 30;
  let width = 500 - 2 * margin;
  let height = 500 - 2 * margin;

  //Creating chart by using g in svg2.
  let chart2 = svg2.append('g')
      .attr('transform', 'translate(30, 30)');
  //yScale
  let yScale2 = d3.scaleLinear()
      .range([height, 0])
      .domain([0, 100]);

  //append g to create y axis
  chart2.append('g')
       .call(d3.axisLeft(yScale2));

  //xScale
  let xScale2 = d3.scaleBand()
      .range([0, width])
      .domain(data2.map((d) => d.name))
      .padding(0.2);

  //append g to create x axis
  chart2.append('g')
      .attr('transform', 'translate(0, 440)')
      .call(d3.axisBottom(xScale2));

  //Creating color scale using scaleOrdinal and schemeCategory10
  let colorScale = d3.scaleOrdinal(d3.schemeCategory10)

  //Selecting all in chart2 to set/append rectangular, and axis.
  chart2.selectAll()
      .data(data2)
      .enter()
      .append('rect')
      .attr('x', (d) => xScale2(d.name))
      .attr('y', (d) => yScale2(d.value))
      .attr('height', (d) => height - yScale2(d.value))
      .attr('width', xScale2.bandwidth())

  //Putting colors on the bar
  chart2.selectAll('rect')
      .style('fill', d => colorScale(d.name));

  function updateData(){
    let data2 = [
        {name: 'A', value: Math.floor(Math.random() * 100)},
        {name: 'B', value: Math.floor(Math.random() * 100)},
        {name: 'C', value: Math.floor(Math.random() * 100)},
        {name: 'D', value: Math.floor(Math.random() * 100)},
        {name: 'E', value: Math.floor(Math.random() * 100)},
        {name: 'F', value: Math.floor(Math.random() * 100)},
        {name: 'G', value: Math.floor(Math.random() * 100)},
        {name: 'H', value: Math.floor(Math.random() * 100)},
        {name: 'I', value: Math.floor(Math.random() * 100)},
        {name: 'J', value: Math.floor(Math.random() * 100)}
    ]
    let u2 = chart2.selectAll()
        .data(data2)
    u2
      .enter()
      .append('rect')
      .merge(u2)
      .transition()
      .duration(1000)
        .attr('x', (d) => xScale2(d.name))
        .attr('y', (d) => yScale2(d.value))
        .attr('height', (d) => height - yScale2(d.value))
        .attr('width', xScale2.bandwidth())

    chart2.selectAll('rect')
        .style('fill', d => colorScale(d.name));

  }

</script>

但是,当我按下 HTML 中的更新按钮时,它会像下图那样过渡和重叠图表, transitioning overlapping.

唯一需要改变的是条形,但所有的条形都随着值的变化而变化。 所以我试着从网上用谷歌搜索它来弄清楚但找不到它..

我必须编辑或添加什么样的东西..?

有人可以帮我吗??

谢谢! :)

最佳答案

这...

let u2 = chart2.selectAll()

...与...相同

let u2 = chart2.selectAll(null)

...这是保证您的输入选择始终包含数据数组中的所有元素的最佳方式。您可以在这里阅读:Selecting null: what is the reason behind 'selectAll(null)' in D3.js?

显然,这不是您想要的。所以,简单的解决方法是:

let u2 = chart2.selectAll("rect")

此外,请考虑使用键函数,否则您将通过索引连接数据。

这里是你的代码有那个变化:

<body>
  <button onclick="updateData()">Update</button>
  <!-- Bar Chart for SVG-->
  <svg width="500" height="500" id="svg2">
    </svg>
  <script src="https://d3js.org/d3.v5.min.js"></script>

  <script>
    //Bar Chart
    //Creating data
    let data2 = [{
        name: 'A',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'B',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'C',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'D',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'E',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'F',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'G',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'H',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'I',
        value: Math.floor(Math.random() * 100)
      },
      {
        name: 'J',
        value: Math.floor(Math.random() * 100)
      }
    ]
    //Creating svg, margin, width, height
    let svg2 = d3.select("#svg2")
    let margin = 30;
    let width = 500 - 2 * margin;
    let height = 500 - 2 * margin;

    //Creating chart by using g in svg2.
    let chart2 = svg2.append('g')
      .attr('transform', 'translate(30, 30)');
    //yScale
    let yScale2 = d3.scaleLinear()
      .range([height, 0])
      .domain([0, 100]);

    //append g to create y axis
    chart2.append('g')
      .call(d3.axisLeft(yScale2));

    //xScale
    let xScale2 = d3.scaleBand()
      .range([0, width])
      .domain(data2.map((d) => d.name))
      .padding(0.2);

    //append g to create x axis
    chart2.append('g')
      .attr('transform', 'translate(0, 440)')
      .call(d3.axisBottom(xScale2));

    //Creating color scale using scaleOrdinal and schemeCategory10
    let colorScale = d3.scaleOrdinal(d3.schemeCategory10)

    //Selecting all in chart2 to set/append rectangular, and axis.
    chart2.selectAll()
      .data(data2)
      .enter()
      .append('rect')
      .attr('x', (d) => xScale2(d.name))
      .attr('y', (d) => yScale2(d.value))
      .attr('height', (d) => height - yScale2(d.value))
      .attr('width', xScale2.bandwidth())

    //Putting colors on the bar
    chart2.selectAll('rect')
      .style('fill', d => colorScale(d.name));

    function updateData() {
      let data2 = [{
          name: 'A',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'B',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'C',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'D',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'E',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'F',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'G',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'H',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'I',
          value: Math.floor(Math.random() * 100)
        },
        {
          name: 'J',
          value: Math.floor(Math.random() * 100)
        }
      ]
      let u2 = chart2.selectAll("rect")
        .data(data2)
      u2
        .enter()
        .append('rect')
        .merge(u2)
        .transition()
        .duration(1000)
        .attr('x', (d) => xScale2(d.name))
        .attr('y', (d) => yScale2(d.value))
        .attr('height', (d) => height - yScale2(d.value))
        .attr('width', xScale2.bandwidth())

      chart2.selectAll('rect')
        .style('fill', d => colorScale(d.name));

    }
  </script>

关于javascript - 通过按下按钮更新条形图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58178037/

相关文章:

python - 如何将数据框转换为字典变量并从中制作条形图

javascript - 单击按钮时 Node.js 调用函数

JavaScript 带条件重置输入

javascript - 使用 d3.join 时是否可以不对元素重新排序?

Highcharts 堆积条形负/正总数

javascript - 将股票代码添加到 Flot 条形图中

php - 以编程方式检查图像元素颜色和颜色百分比

javascript - 创建一个响应式且可以发布到数据库的自定义弹出窗口

javascript - 如何在 D3.js 中读取 Blob

javascript - 为什么我的 Angular 组件会忽略我的 css 文件?