首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我有一个图表,但是它没有用react js-2更新图表。

我有一个图表,但是它没有用react js-2更新图表。
EN

Stack Overflow用户
提问于 2022-02-05 19:38:01
回答 2查看 1.3K关注 0票数 0

我有一个基于API的react天气项目,我有一个名为图表的组件,但是它没有更新项目中最重要的部分。每当我键入城市名称时,它就是获取所有信息并更新项目的书面部分。但是它不是用chart.And来做的,它总是显示第一次调用的第一个值,而不是更新。当我进入Chart.js文件并在项目中留出一个空间并点击保存时,它将显示基于API的正确图表。我能闻到一定有用例的useEffect钩,但是怎么会呢?

以下是子组件

代码语言:javascript
复制
import React, {  useEffect, useState } from 'react';
import { Line } from 'react-chartjs-2';
import { Chart as ChartJS} from 'chart.js/auto';

const Chart = ({following}) => {
  const date = following.map(item => new Date(item.dt * 1000));
  const dateLocal = date.map(item => item.toLocaleString('default', { weekday: 'long' }));
  const temp = following.map(item => Math.floor(item.temp.day));



  const [userData, setUserData] = useState({
    labels: dateLocal,
    datasets: [
      { 
        data: temp,    
        label: 'Temperature',
        backgroundColor: [
          'rgba(0, 0, 0,.5)',
          'rgba(0, 0, 0,.5)',
          'rgba(0, 0, 0,.5)',
        ],
        color : ['rgba(0,0,0,1)'],
        fill:true,  
        pointRadius: 1,
        pointHitRadius:4,
        pointHoverRadius:8,
        pointBackgroundColor: 'mediumblue',
        borderWidth: 2,
        pointBorderColor: 'lightblue',
        pointBorderWidth: 2,
        pointHoverBorderWidth: 2,
        tooltips: {
          mode: 'index',
          intersect: true,
          windowPadding: 10,
        },
        scales: {
          xAxes: [{
            gridLines: {
              display: false,
            },
            ticks: {
              fontColor: 'green',
              zeroLineColor: 'blue',
              callback : 
               function (value) {
                  return value
                }
            }
          }],
          yAxes: [{
            gridLines: {
              display: false,
            },
            ticks: {
              fontColor: 'black',
              fontSize: 112,
              fontStyle: 'bold',
              color: 'red',
              callback :
                function (value) {
                  return value
                }
            }
          }]
        }
      }
    ]
  });

  return (
    <div className="line" style={{ width:'100%'}}>
    <Line  
      data={userData} 
     />
    </div>
  )
};

export default Chart;
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

下面是父App.js

代码语言:javascript
复制
import React, { useEffect, useState } from 'react';
import Chart from './Chart';

const api = {
  key: `${process.env.REACT_APP_API_KEY}`,
  base: 'https://api.openweathermap.org/data/2.5/'
}

function App() {

  const [query, setQuery] = useState('');
  const [weather, setWeather] = useState({});
  const [location, setLocation] = useState({ lat: '', lon: '' });
  const [following, setFollowing] = useState([]);
  


  const search = async (e) => {
    if (e.key === 'Enter') {
      await fetch(`${api.base}weather?q=${query}&units=metric&appid=${api.key}&lang=tr`)
        .then(res => res.json())
        .then(result => {
          setWeather(result);
          setQuery('');
          setLocation(result.coord);
          console.log(result);
          searchFollowing();
        }
        )
    }
  }



  useEffect(() => {
    if (location.lat && location.lon) {
      searchFollowing();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [location])

  const searchFollowing = async () => {
    await fetch(`${api.base}onecall?lat=${location.lat}&lon=${location.lon}&units=metric&exclude=hourly,minutely&appid=${api.key}`)
      .then(res => res.json())
      .then(result2 => {
        const array = result2.daily.slice(1, 6);
        console.log(following);
        setFollowing(array);
        // following == array
      }
      )
  }



  const integer = (number) => {
    return Math.floor(Math.round(number));
  }
 

  const mapped = (following) => {
    following = [...following];
    return following.map((item, idx) => {
      const date = new Date(item.dt * 1000);
      const date1 = date.toLocaleString('default', { weekday: 'long' });
      const icon = item.weather[0].icon;
      const day = integer(item.temp.day);
      const night = integer(item.temp.night);
      return (
        <div key={idx} className="box">
          <h4>{date1}</h4>
          <img
            src={`http://openweathermap.org/img/wn/${icon}.png`}
            alt='weather'
            width={100}
            height={100}
          />
          <h4>Gündüz &nbsp; &nbsp; {day} °C</h4>
          <h4>Gece &nbsp; &nbsp; {night} °C</h4>
        </div>
      )
    })
  }

  const dateBuild = (d) => {
    let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
    let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

    let day = days[d.getDay()]
    let date = d.getDate()
    let month = months[d.getMonth()]
    let year = d.getFullYear()

    return `${day} ${date} ${month} ${year}`
  }


  return (
    <div className={(typeof weather.main !== 'undefined') ?
      ((weather.main.temp > 25) ? 'App hot' :
        ((weather.main.temp < 25 && weather.main.temp > 5) ?
          'App warm' : 'App')) : 'App'}>
      <main>
        <div className="search-box">
          <input
            type="text"
            className="search-bar"
            placeholder="Search for a location..."
            onChange={e => setQuery(e.target.value)}
            onKeyPress={search}
            value={query}
          />
        </div>
        {(typeof weather.main != "undefined") ? (
          <div className="content">
            <div className="location-box">
              <div className="location">
                {weather.name}, {weather.sys.country}
              </div>
              <div className="date"> {dateBuild(new Date())}
              </div>
            </div>
            <div className="weather-box">
              <div className="temp">
                {Math.round(weather.main.temp)}°C
                <img
                  src={`http://openweathermap.org/img/wn/${weather.weather[0].icon.slice(0, 2)}d.png`}
                  alt='weather'
                  width={150}
                  height={150}
                />
              </div>
              <div className="weather">
                <p>
                  <span>Hissedilen</span>
                  {Math.floor(weather.main.feels_like)} °C
                </p>
                <p>
                  <span>Şu an</span>
                  {weather.weather[0].description}
                </p>
                <p>
                  <span>Basınç</span>
                  {weather.main.pressure} mb
                </p>
                <p>
                  <span>Rüzgar </span>
                  {Math.floor(weather.wind.speed)} km/h
                </p>
                <p>
                  <span>En fazla</span>
                  {Math.floor(weather.main.temp_max)} °C
                </p>
                <p>
                  <span>En az</span>
                  {Math.floor(weather.main.temp_min)} °C
                </p>
              </div>
            </div>
            <Chart following={following} />
            <div className="followingdays"
            >
              {mapped(following)}
            </div>
          </div>) : ('')}
      </main>
    </div>
  );
}

export default App;
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

EN

回答 2

Stack Overflow用户

发布于 2022-02-05 20:57:40

Chart.js有更新方法。尝试将图表保存在变量中,必要时调用foo.update()

票数 0
EN

Stack Overflow用户

发布于 2022-02-06 10:22:54

UPDATE1 ==>,我用useEffect钩子做的,不能用内置的方法update()来完成。

代码语言:javascript
复制
import React, {  useEffect, useState } from 'react';
import { Line } from 'react-chartjs-2';
import { Chart as ChartJS} from 'chart.js/auto';



const Chart = ({following}) => {
  const date = following.map(item => new Date(item.dt * 1000));
  const dateLocal = date.map(item => item.toLocaleString('default', { weekday: 'long' }));
  const temp = following.map(item => Math.floor(item.temp.day));

  // if userData changes then the chart will re-render
    useEffect(() => {
      setUserData({ 
        labels: dateLocal,
        datasets: [
          { 
            data: temp,       
            label: 'Temperature', 
            backgroundColor: [
              'rgba(0, 0, 0,.5)',
              'rgba(0, 0, 0,.5)',
              'rgba(0, 0, 0,.5)', 
            ],
            color : ['rgba(0,0,0,1)'],
            fill:true,  
            pointRadius: 1,
            pointHitRadius:4,
            pointHoverRadius:8,  
            pointBackgroundColor: 'mediumblue',
            borderWidth: 2,
            pointBorderColor: 'lightblue',
            pointBorderWidth: 2,
            pointHoverBorderWidth: 2, 
            tooltips: {
              mode: 'index',
              intersect: true,
              windowPadding: 10,
            },
            scales: {
              xAxes: [{
                gridLines: {
                  display: false,
                },
                ticks: {
                  fontColor: 'green'
                }
              }],
              yAxes: [{
                gridLines: {
                  display: false,
                }, 
                ticks: { 
                  fontColor: 'green' 
                }
              }] 
            }
          } 
        ]   
      });
    },[following]);


 
  const [userData, setUserData] = useState({ 
    labels: dateLocal,
    datasets: [ 
      { 
        data: temp,       
        label: 'Temperature', 
        backgroundColor: [ 
          'rgba(0, 0, 0,.5)',
          'rgba(0, 0, 0,.5)',
          'rgba(0, 0, 0,.5)',   
        ],
        color : ['rgba(0,0,0,1)'], 
        fill:true,  
        pointRadius: 1,
        pointHitRadius:4,
        pointHoverRadius:8,  
        pointBackgroundColor: 'mediumblue',
        borderWidth: 2,
        pointBorderColor: 'lightblue', 
        pointBorderWidth: 2,
        pointHoverBorderWidth: 2, 
        tooltips: {
          mode: 'index',
          intersect: true,
          windowPadding: 10,
        },
        scales: {
          xAxes: [{
            gridLines: {
              display: false,
            },
            ticks: {
              fontColor: 'green'
            }
          }],
          yAxes: [{
            gridLines: { 
              display: false,
            }, 
            ticks: { 
              fontColor: 'green' 
            }
          }] 
        } 
      } 
    ]     
  });

  return (
    <div className="line" style={{ width:'100%'}}>
    <Line className="actual-chart"
      data={userData}
      redraw={true}
     />    
    </div>
  ) 
}; 
  
export default Chart;
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71001503

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档