javascript - 在 React 中使用 select 标签并使用状态在 React Charts 的数据集之间切换

标签 javascript html reactjs data-visualization

我正在使用 React 图表。我有一个折线图,我希望能够在两组数据之间切换。 使用标签我做了一个下拉菜单。看一个活生生的例子:

https://codesandbox.io/s/mm2vnz6869

转到下拉菜单并切换到“收入”。请注意,它会根据需要切换到另一组数据。但现在尝试切换回“花费”。注意它不起作用。 这是为什么?有人可以看看我的逻辑,让我知道我做错了什么吗?谢谢。

import React, { Component } from 'react';
import { render } from 'react-dom';
import { Line } from 'react-chartjs-2';

let lineData;

const lineDataSpend = {
  labels: ['March', 'April', 'May', 'June', 'July', 'August', 'September'],
  datasets: [
    {
      label: 'Spend - Account 1',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'green',
      borderColor: 'green',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'green',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [65, 59, 80, 81, 56, 55, 40]
    },
    {
      label: 'Spend - Account 2',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'blue',
      borderColor: 'blue',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'blue',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [25, 5, 8, 53, 96, 35, 20]
    }
  ]
};

const lineDataRev = {
  labels: ['March', 'April', 'May', 'June', 'July', 'August', 'September'],
  datasets: [
    {
      label: 'Revenue - Account 1',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'red',
      borderColor: 'red',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'red',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [27, 9, 37, 31, 102, 42, 19]
    },
    {
      label: 'Revenue - Account 2',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'yellow',
      borderColor: 'yellow',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'yellow',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [1, 29, 4, 112, 26, 49, 81]
    }
  ]
};

lineData = lineDataSpend; //init the graph data to 'Spend'

class App extends Component {

  constructor(props) {
    super(props);
    this.changeMetric = this.changeMetric.bind(this);

    this.state = {
      selectedMetric: 'Spend'
    };
  }

  changeMetric(event) {

    this.setState({
      selectedMetric: event.target.value
    });

    switch (event.target.value) {
      case 'Spend':
        lineData = lineDataSpend;
        break;
      case 'Revenue':
        lineData = lineDataRev;
        break;
      default:
    }
  }

  render() {
    const lineOptions = {
      title: {
        display: true,
        text: 'Account 1 vs Account 2'
      },
      tooltips: {
        enabled: true,
        callbacks: {
          label: function (value, data) {
            console.log('data', data)
            const currentLabel = data.datasets[value.datasetIndex].label;
            return currentLabel + ': ' + '$' + value.yLabel;
          }
        }
      },
      legend: {
        display: true
      },
      maintainAspectRatio: true,
      scales: {
        yAxes: [{
          ticks: {
            callback: function (value) {
              return '$' + parseFloat(value.toFixed(2));
            }
          },
          stacked: false,
          gridLines: {
            display: true,
            color: "rgba(255,99,132,0.2)"
          }
        }],
        xAxes: [{
          gridLines: {
            display: false
          }
        }]
      }

    };

    return (
      <div>


        <select onChange={this.changeMetric} value={this.state.selectedMetric}>
          <option value="Spend">Spend</option>
          <option value="Revenue">Revenue</option>
        </select>

        <div className="row">
          <div className="col-xl-10">
            <div className="card">
              <div className="card-header">
                <i className="fa fa-align-justify" />
              </div>
              <div className="card-block">
                <Line data={lineData} options={lineOptions} />
              </div>
            </div>
          </div>
        </div>

      </div>

    )

  }
}


render(<App />, document.body);

除此之外,有没有一种方法可以通过使用复选框同时显示两个图表?例如,如果有两个复选框的支出、收入和其他一些选项。如果我们选中支出,则会在图表上显示支出数据,如果我们选中两个或更多复选框,则会显示所有这些图表。请帮忙。

最佳答案

您对 lineDataSpend 的 lineData 初始化导致了这个问题。如果您直接将一个默认对象分配给 lineData 而不是让它持有 lineDataSpend 对象,您的问题就解决了。

因此,如果您更改第 103 行,

lineData = lineDataSpend; //init the graph data to 'Spend'

lineData = {
labels: ['March', 'April', 'May', 'June', 'July', 'August', 'September'],
  datasets: [
    {
      label: 'Spend - Account 1',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'green',
      borderColor: 'green',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'green',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [65, 59, 80, 81, 56, 55, 40]
    },
    {
      label: 'Spend - Account 2',
      fill: false,
      lineTension: 0.1,
      backgroundColor: 'blue',
      borderColor: 'blue',
      borderCapStyle: 'butt',
      borderDash: [],
      borderDashOffset: 0.0,
      borderJoinStyle: 'miter',
      pointBorderColor: 'rgba(75,192,192,1)',
      pointBackgroundColor: '#fff',
      pointBorderWidth: 1,
      pointHoverRadius: 5,
      pointHoverBackgroundColor: 'blue',
      pointHoverBorderColor: 'rgba(220,220,220,1)',
      pointHoverBorderWidth: 2,
      pointRadius: 1,
      pointHitRadius: 10,
      data: [25, 5, 8, 53, 96, 35, 20]
    }
  ]
}

您的问题将得到解决。您可以在此处测试修复 - https://codesandbox.io/s/3rko469pkm

但即使我也不清楚为什么您的初始作业会导致问题,因为作业看起来非常好。必须深入挖掘才能了解此问题背后的原因。

关于javascript - 在 React 中使用 select 标签并使用状态在 React Charts 的数据集之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46231937/

相关文章:

javascript - 类实例的未定义​​返回 - Javascript

javascript - 如何在 Internet Explorer 中使用 html 子元素获取 contenteditable div 中的插入符位置

php - 从html表格单元格分配php变量值

javascript - UglifyJs 意外 token : keyword «const» Webpack 4

javascript - 使用 Sqlite ResultSet 验证表单

javascript - 我可以检查 pin 码是否由使用 ASCII 的数字组成吗?

javascript - 使用Javascript对 Angular 线来回移动元素

html - 在输入字段中的第一个空格后 Handlebars 不填充数据

reactjs - ReactDOM.Hydrate() 会触发客户端的生命周期方法吗?

javascript - ReactJS switch case 错误 相邻的 JSX 元素必须包含在封闭标签中