React - 如何解析大型 JSON 对象以进行绘图努力与国家合作

问题描述

我无法从我的 Axios 调用中解析大型 JSON 对象并将它们设置为状态,然后作为 X 和 Y 轴数据传递以在 react-chartist 中绘制图形。就我而言,我正在绘制股票市场数据。

我一直在尝试使用状态钩子 chartData 解析数据,但无法使其正常工作,例如 response.data.symbolresponse.data.adj_closeresponse.data.date

我还尝试为直接从 axios 调用获取的 X、Y 和符号数据创建三种不同的状态,但未能实现。

这是我正在使用的代码

export default function Graph() {
const [chartData,setChartData] = useState([])

    const getData = () => {
      axiosInstance
        .get('price/' + slug)
        .then(result => setChartData(result.data))
    }
    useEffect(() => {
        getData()
    },[])


    const graphChart = () =>
    {
        var data = {
            
            labels: //date values from JSON object
            series: //adj_close values from JSON object
        };
        var options = {
            width: 500,height: 400
        };
        
        return (
                <ChartistGraph data={data} options={options} type="Line" />
        );
    };
     return (
         <Container>
             <Grid>
                 {graphChart()} 
             </Grid>
         </Container>

     );
};

我这样做是错误的吗?有没有更简单的方法

我已经添加了数据来复制问题,这基本上是,我如何解析这样的大对象?请记住,每一行都需要按其各自的 symbol 进行分组以进行绘图。在下面的数据中,有 8 家公司有价值的数据。将所有这些数据放在图表上会很糟糕,但如果我知道如何解析特定符号,那么我将能够自己完成绘图。

[{"symbol":"PG","date":"2020-12-04","adj_close":137.47},{"symbol":"HSY","adj_close":150.87},{"symbol":"CLX","adj_close":199.98},{"symbol":"COST","adj_close":373.43},{"symbol":"MDLZ","adj_close":59.03},{"symbol":"K","adj_close":62.37},{"symbol":"KHC","adj_close":34.12},{"symbol":"PEP","adj_close":145.85},{"symbol":"PG","date":"2020-12-07","adj_close":137.68},"adj_close":149.72},"adj_close":200.61},"adj_close":373.33},"adj_close":58.41},"adj_close":61.95},"adj_close":33.6},"adj_close":145.37},"date":"2020-12-08","adj_close":138.05},"adj_close":150.63},"adj_close":202.88},"adj_close":377.6},"adj_close":58.29},"adj_close":62.55},"adj_close":34.34},"adj_close":145.52},"date":"2020-12-09","adj_close":136.41},"adj_close":152.14},"adj_close":200.51},"adj_close":374.29},"adj_close":57.72},"adj_close":62},"adj_close":34.22},"adj_close":145.69},"date":"2020-12-10","adj_close":135.51},"adj_close":149.7},"adj_close":200.6},"adj_close":372.79},"adj_close":57.18},"adj_close":61.98},"adj_close":34.1},"adj_close":144.67},"date":"2020-12-11","adj_close":136.51},"adj_close":149.11},"adj_close":201.73},"adj_close":375.1},"adj_close":57.4},"adj_close":62.11},"adj_close":34.07},"adj_close":144.97},"date":"2020-12-14","adj_close":135.85},"adj_close":149.14},"adj_close":202.38},"adj_close":374.38},"adj_close":57.29},"adj_close":61.92},"adj_close":34.42},"adj_close":144.23},"date":"2020-12-15","adj_close":136.65},"adj_close":150.23},"adj_close":203.04},"adj_close":371.88},"adj_close":57.45},"adj_close":61.24},"adj_close":34.33},"adj_close":144.77},"date":"2020-12-16","adj_close":137.27},"adj_close":150.28},"adj_close":203.44},"adj_close":369.44},"adj_close":57.2},"adj_close":61.5},"adj_close":34.43},"adj_close":144.89},"date":"2020-12-17","adj_close":138.25},"adj_close":151.61},"adj_close":202.34},"adj_close":370.29},"adj_close":57.93},"adj_close":62.48},"adj_close":34.62},"adj_close":145.71},"date":"2020-12-18","adj_close":139.04},"adj_close":150.88},"adj_close":203.17},"adj_close":367},"adj_close":58.32},"adj_close":62.08},"adj_close":34.77},"adj_close":146.93},"date":"2020-12-21","adj_close":137.52},"adj_close":149.66},"adj_close":202.45},"adj_close":364.97},"adj_close":57.68},"adj_close":61.53},"adj_close":34.57},"adj_close":145.4},"date":"2020-12-22","adj_close":136.55},"adj_close":148.62},"adj_close":201.39},"adj_close":362.03},"adj_close":57.16},"adj_close":61.19},"adj_close":34.39},"adj_close":144.02},"date":"2020-12-23","adj_close":136.34},"adj_close":149.45},"adj_close":202.33},"adj_close":361.89},"adj_close":57.35},"adj_close":61.61},"adj_close":34.8},"adj_close":144.41},"date":"2020-12-24","adj_close":137.72},"adj_close":149.95},"adj_close":203.8},"adj_close":364.58},"adj_close":57.85},"adj_close":61.78},"adj_close":34.98},"adj_close":145.06},"date":"2020-12-28","adj_close":138.68},"adj_close":151.8},"adj_close":202.25},"adj_close":371.06},"adj_close":58.27},"adj_close":62.34},"adj_close":35.21},"adj_close":146.91},"date":"2020-12-29","adj_close":138.42},"adj_close":151.44},"adj_close":201.76},"adj_close":372.72},"adj_close":58.45},"adj_close":62.29},"adj_close":34.9},"adj_close":147.42},"date":"2020-12-30","adj_close":137.77},"adj_close":150.53},"adj_close":201.04},"adj_close":374.45},"adj_close":58},"adj_close":34.67},"adj_close":147.31},"date":"2020-12-31","adj_close":139.14},"adj_close":152.33},"adj_close":201.92},"adj_close":376.78},"adj_close":58.47},"adj_close":62.23},"adj_close":34.66},"adj_close":148.3},"date":"2021-01-04","adj_close":137.82},"adj_close":150.9},"adj_close":200.44},"adj_close":380.15},"adj_close":57.92},"adj_close":61.45},"adj_close":34.23},"adj_close":144.27},"date":"2021-01-05","adj_close":138.7},"adj_close":150.73},"adj_close":200.01},"adj_close":375.74},"adj_close":57.98},"adj_close":61.8},"adj_close":33.57},"adj_close":144.7},"date":"2021-01-06","adj_close":140.16},"adj_close":151.26},"adj_close":197.41},"adj_close":370.02},"adj_close":57.87},"adj_close":61.32},"adj_close":33.94},"adj_close":142.93},"date":"2021-01-07","adj_close":138.85},"adj_close":151.17},"adj_close":196.43},"adj_close":367.92},"adj_close":57.76},"adj_close":60.89},"adj_close":33.695},"adj_close":142.47},"date":"2021-01-08","adj_close":138.79},"adj_close":152.03},"adj_close":197.84},"adj_close":369.94},"adj_close":58.19},"adj_close":60.2},"adj_close":33.62},"adj_close":144.18},"date":"2021-01-11","adj_close":137.85},"adj_close":150.11},"adj_close":193.73},"adj_close":364.01},"adj_close":57.09},"adj_close":59.37},"adj_close":32.85},"adj_close":142.09},"date":"2021-01-12","adj_close":137.05},"adj_close":149.38},"adj_close":194.24},"adj_close":364.2},"adj_close":57.32},"adj_close":58.56},"adj_close":32.18},"adj_close":141.43},"date":"2021-01-13","adj_close":137.26},"adj_close":149.92},"adj_close":193.74},"adj_close":366.95},"adj_close":57.37},"adj_close":59.14},"adj_close":32.01},"adj_close":142.59},"date":"2021-01-14","adj_close":135.8},"adj_close":195.55},"adj_close":362.35},"adj_close":57.31},"adj_close":59.05},"adj_close":32.08},"adj_close":141.76},"date":"2021-01-15","adj_close":134.78},"adj_close":148.46},"adj_close":197.52},"adj_close":362.16},"adj_close":57.22},"adj_close":31.99},"adj_close":141.39},"date":"2021-01-19","adj_close":133.6},"adj_close":148.75},"adj_close":196.51},"adj_close":354.47},"adj_close":57.14},"adj_close":58.46},"adj_close":32.36},"adj_close":142.06},"date":"2021-01-20","adj_close":131.93},"adj_close":149.63},"adj_close":196.93},"adj_close":361.3},"adj_close":57.1},"adj_close":57.64},"adj_close":32.86},"adj_close":141.33},"date":"2021-01-21","adj_close":131.01},"adj_close":148.98},"adj_close":197.21},"adj_close":362.8},"adj_close":56.12},"adj_close":57.89},"adj_close":32.78},"adj_close":139.61},"date":"2021-01-22","adj_close":130},"adj_close":148.2},"adj_close":202.35},"adj_close":362.3},"adj_close":56.25},"adj_close":58.3},"adj_close":32.91},"adj_close":138.59},"date":"2021-01-25","adj_close":132.24},"adj_close":147.53},"adj_close":211.96},"adj_close":361.88},"adj_close":56.87},"adj_close":59.84},"adj_close":33.75},"adj_close":140.18},"date":"2021-01-26","adj_close":133.09},"adj_close":149.52},"adj_close":212.99},"adj_close":364.98},"adj_close":57.59},"adj_close":60.92},"adj_close":141.8},"date":"2021-01-27","adj_close":128.38},"adj_close":146.19},"adj_close":222.18},"adj_close":356.39},"adj_close":56.42},"adj_close":62.36},"adj_close":34.74},"adj_close":138.04},"date":"2021-01-28","adj_close":130.36},"adj_close":148.21},"adj_close":209.57},"adj_close":357.06},"adj_close":57.12},"adj_close":60.17},"adj_close":33.96},"adj_close":139.19},"date":"2021-01-29","adj_close":128.21},"adj_close":145.44},"adj_close":209.46},"adj_close":352.43},"adj_close":55.44},"adj_close":58.94},"adj_close":33.51},"adj_close":136.57},"date":"2021-02-01","adj_close":128.97},"adj_close":145.11},"adj_close":210.02},"adj_close":350.52},"adj_close":55.25},"adj_close":58.82},"adj_close":33.25},"adj_close":136.98},"date":"2021-02-02","adj_close":128.79},"adj_close":147.12},"adj_close":204.23},"adj_close":355.58},"adj_close":56.16},"adj_close":33.16},"adj_close":138.38},"date":"2021-02-03","adj_close":128.95},"adj_close":146.58},"adj_close":204.59},"adj_close":355.21},"adj_close":55.28},"adj_close":58.01},"adj_close":33.01},"adj_close":138.02},"date":"2021-02-04","adj_close":129.03},"adj_close":147.22},"adj_close":191.65},"adj_close":355.85},"adj_close":56},"adj_close":32.92},"adj_close":139.68},"date":"2021-02-05","adj_close":129.57},"adj_close":146.6},"adj_close":191.25},"adj_close":355.17},"adj_close":56.21},"adj_close":58.03},"adj_close":33.8},"adj_close":140.96},"date":"2021-02-08","adj_close":129.17},"adj_close":149.33},"adj_close":190},"adj_close":359.83},"adj_close":56.02},"adj_close":57.74},"adj_close":33.91},"adj_close":140.4},"date":"2021-02-09","adj_close":128.67},"adj_close":149.62},"adj_close":187.35},"adj_close":359.56},"adj_close":55.5},"adj_close":139.6},"adj_close":33.71},"adj_close":57.64}]

解决方法

我已经重写了你的代码,检查它是否适合你的情况

import React,{ useState,useEffect } from "react";
import ChartistGraph from 'react-chartist';

export default function Graph() {
  const [data,setData] = useState({
    chart: {
      label: [],series: []
    },dataBySymbols: {},symbols: [],select: "",});

  const getData = () => {
    setTimeout(() => {
      const _tmp = new Set();
      const dataBySymbols = {};

      response.forEach(item => {
        _tmp.add(item.symbol);
        if (!dataBySymbols.hasOwnProperty(item.symbol)) {
          dataBySymbols[item.symbol] = {
            label: [],series: [
              []
            ]
          };
        }

        dataBySymbols[item.symbol]['label'].push(item.date);
        dataBySymbols[item.symbol]['series'][0].push(item.adj_close);
      });

      const copy = {...data};
      copy['dataBySymbols'] = dataBySymbols;
      copy['symbols'] = Array.from(_tmp);
      copy['chart'] = dataBySymbols[copy['symbols'][0]];

      setData(copy);
    },3000)
  }

  useEffect(() => {
    getData()
  },[])

  function onSelectChange(evt) {
    const copy = {...data};
    copy['select'] = evt.target.value;
    copy['chart'] = copy.dataBySymbols[evt.target.value]
    setData(copy);
  }

  const options = {
    width: 500,height: 400
  };

  return (
    <div>
      <select value={data.select} onChange={onSelectChange}>
        {data.symbols.map(option => {
          return (
            <option key={option} value={option}>{option}</option>
          );
        })}
      </select>

      <ChartistGraph data={data.chart} options={options} type="Line" />
    </div>

  );
};

export default function App() {
  return (
    <Graph />
  );
}

在这里工作example

,

这是一个包含公司代码选择器的示例:

Presentator.js

export function Presentator() {
  const [data,setData] = useState([]);
  const [ticker,setTicker] = useState('');

  useEffect(() => {
    const fetchData = async () => {
      /* DO ACTUAL FETCH FROM SERVICE */
      const result = await Promise.resolve(response);

      setData(result);
    }

    fetchData();
  },[]);

  const handleTickerChange = (event) => {
    setTicker(event.target.value);
  }

  const getTickerData = (ticker) => {
      return data.filter(item => item.symbol.toLowerCase() === ticker.toLowerCase());
  };

  const getTickerDropdownValues = () => {
    const set = new Set();

    data.forEach(item => {
      if (!set.has(item.symbol)) {
        set.add(item.symbol);
      }
    });

    return Array.from(set);
  }

  const getTickerDropdown = () => {
    const options = getTickerDropdownValues();

    return (
      <select value={ticker} onChange={handleTickerChange}>
        {options.map(option => {
          return (
            <option key={option} value={option}>{option}</option>
          );
        })}
      </select>
    );
  }

  return (
    <>
      {getTickerDropdown()}
      <Graph data={getTickerData(ticker)} />
    </>
  );
}

Graph.js:

export function Graph(props) {
  const { data } = props;

  const getChartData = () => {
    const labels = [];
    const series = [];

    data.forEach(item => {
      labels.push(item.date);
      series.push(item.adj_close);
    });

    return {
      labels: labels,series: [series]
    };
  }

  // Add your graph configuration here
  const chartOptions = {
    // width: 2000,height: 400,// scaleMinSpace: 20
  };

  return (
    <ChartistGraph data={getChartData()} options={chartOptions} type="Line" />
  );
}

基本上,Presentator 处理数据的初始获取和按代码拆分数据的逻辑。然后,Graph 组件处理特定代码数据本身的可视化。

您可以查看一个工作示例 at this codesandbox

除了数据本身之外,您不需要在状态中存储更多内容。在我们的例子中,我们还存储了股票代码下拉列表的选定值。其他一切都可以计算。

getChartData 函数中,您可以进一步过滤和处理数据,例如仅显示最后 10 条记录(日期)而不是整个数据集。

,

如果我理解正确,您需要显示每个日期的 adj_close 值,按 symbol 分组。对吗?


首先,更改您的状态:

  const [chartData,setChartData] = useState({
    labels: [],series: []
  });

您可以像这样按 symbol 对响应进行分组:

const symbols = response.reduce((map,value) => {
        if (map.has(value.symbol)) {
          map.set(value.symbol,[...map.get(value.symbol),value]);
        } else {
          map.set(value.symbol,[value]);
        }
        return map;
},new Map())

然后获取唯一日期:

const dates = [...new Set(response.map(r => r.date))]; // note: it doesn't sort dates!

然后构造series多维数组。对于每个符号,您包括每个日期的 adj_close 值。


const series = Array.from(symbols).map(value => {
    const valuesForSymbol = value[1];
    return dates.map(date => {
      const valueForDate = valuesForSymbol.find(v => v.date === date);
      return valueForDate.adj_close;
    });
});

设置状态:

setChartData({labels: dates,series });

最后,像这样显示图表:

<ChartistGraph data={chartData} options={options} type="Line" />

完整示例 here.