【问题标题】:How to build a simple chart in React based on data from API response如何根据来自 API 响应的数据在 React 中构建一个简单的图表
【发布时间】:2021-01-06 20:52:40
【问题描述】:

我想在 React 中使用 Nivo 库构建一个简单的图表来表示 API 响应中数据的百分比值。

响应中的数据如下所示:https://run.mocky.io/v3/7c46c4ce-09c0-4f95-b4e1-84ae10bd24ab

我需要用一个非常简单的折线图来表示这些数据。

到目前为止,我的组件中有这段代码:

import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {useParams} from 'react-router-dom';
import Loader from '../Components/Loader';
import { Bar } from "@nivo/bar";


function ArtistDetail() {
const {artist_uuid} = useParams()
const url = `https://run.mocky.io/v3/${artist_uuid}`; 
const [artist, setArtist] = useState({
    loading: false,
    data: null,
    error: false
})

let content = null;

useEffect(() => {
    setArtist({
      loading: true,
      data: null,
      error: false  
    })
    axios.get(url)
        .then(response => {
            setArtist({
                loading: false,
                data: response.data,
                error: false
            })
        })
        .catch(() => {
            setArtist({
                loading: false,
                data: null,
                error: true
            })
        })
}, [url])


if(artist.error) {
    content = <p>There was an error loading an artist.</p>
}


if(artist.loading) {
    content = <p><Loader/></p>
}


if(artist.data) {
    content = 
    <main className="main">
        <section className="section section-artist-detail trending claimed">
            <div className="page">          
                <div className="col visual">
                    <figure>
                        <img src= {artist.data.data.image}/>
                        <figcaption>
                            <button className="btn btn-claim-music-id">Claim music_id</button>
                        </figcaption>
                    </figure>
                </div>
                <div className="col-wrapper">
                    <div className="col info">
                        <div className="col-content">                               
                            <div className="info-wrapper">
                                <div className="title-wrapper">
                                    <button className="btn btn-solid border btn-booking-request">Booking Request</button>
                                    <h1 className="title">
                                        {artist.data.data.name}
                                        <div className="tooltip-wrapper">
                                            <span className="profile-claimed">Profile claimed</span>
                                            <div className="tooltip">
                                                <h3>Vote for subgenres</h3>
                                                <p>Don’t agree with the subgenres? Add the ones you think are missing or vote for existing to get yours on top!</p>
                                                <div className="stats-sheet">
                                                        {artist.data.data.subgenres.map(subgenre => {
                                                        const {name, score} = subgenre;
                                                        return (
                                                        <div className="row" key={name, score}>
                                                            <h5>{name}</h5>
                                                            <div className="graph-line">
                                                            <span className="line" style= {{width: score + '%'}}>{score}%</span>
                                                            </div>
                                                        </div>
                                                        );
                                                    })}
                                                </div>
                                                <p>
                                                    <button className="btn btn-shadow">Vote now</button>
                                                </p>
                                            </div>
                                        </div>                                          
                                        <span className="trending-icon">Trending</span>
                                    </h1>
                                </div>
                                <div className="row">
                                    <button className="btn btn-save long">Follow</button>
                                    <button className="btn btn-share">
                                        Share
                                        <span>Link copied to clipboard</span>
                                    </button>
                                </div>
                                <div className="row">
                                    <label>Origin</label>
                                    <a className="btn btn-filter-tag">{artist.data.data.country.name}</a>
                                </div>
                                <div className="row">
                                    <label>Genre</label>
                                    <span className="btn btn-filter-tag">{artist.data.data.genre.name}</span>
                                </div>
                                <div className="row">
                                    <label>Subgenres</label>
                                    {artist.data.data.subgenres.map(subgenre => {
                                        const {name} = subgenre;
                                        return (
                                            <span key={name} className="btn btn-filter-tag">{name}</span>                                                           
                                        );
                                    })}
                                    <div className="tooltip-wrapper">
                                        <button className="btn btn-add">Add subgenre</button>
                                        <div className="tooltip">
                                            <h3>Vote for subgenres</h3>
                                            <p>Don’t agree with the subgenres? Add the ones you think are missing or vote for existing to get yours on top!</p>
                                            <div className="stats-sheet">
                                                {artist.data.data.subgenres.map(subgenre => {
                                                        const {name, score} = subgenre;
                                                        return (
                                                        <div className="row" key={name, score}>
                                                            <h5>{name}</h5>
                                                            <div className="graph-line">
                                                                <span className="line" style= {{width: score + '%'}}>{score}%</span>
                                                            </div>
                                                        </div>
                                                        );
                                                    })}
                                            </div>
                                            <p>
                                                <button className="btn btn-shadow">Vote now</button>
                                            </p>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div className="footer-detail">

                                <ul className="social-list">
                                    {artist.data.data.social_links.map(item => {
                                        const {channel, link} = item;
                                        return (
                                            <li key={channel, link}>
                                                <a href= {link} className= {`btn social-icon ${channel}`}>{channel}</a>
                                            </li>
                                        );
                                    })}
                                </ul>

                                <div className="tooltip-wrapper">
                                        <button className="btn btn-add">Add links</button>
                                        <div className="tooltip">
                                            <h3>Got more info?</h3>
                                            <p>Add Place's links so everyone can see their social media highlights.</p>
                                            <p>
                                                <button className="btn btn-shadow">Add links</button>
                                            </p>
                                        </div>
                                    </div>
                            </div>
                        </div>
                    </div>

                    <div className="col stats">
                        <div className="col-content">

                        <Bar
                            width={600}
                            height={400}
                            margin={{ top: 60, right: 80, bottom: 60, left: 80 }}
                            data={artist.data.data.popularity}
                            indexBy="city"
                            keys={["percentage"]}
                            labelTextColor="inherit:darker(1.4)"
                            enableGridX={false}
                            layout="horizontal"
                            maxValue={10}
                            axisTop={null}
                            axisRight={null}
                            axisBottom={null}
                            axisLeft={null}
                            enableGridX={false}
                            enableGridY={false}
                            isInteractive={false}
                        />

                            <div className="stats-sheet">
                                <label>Most popular in</label>
                                {artist.data.data.popularity.map(popular => {
                                    const {city} = popular;
                                    return (
                                        <div className="row" key={city}>
                                            <h5>{city}</h5>
                                            <div className="graph-line">
                                                <span className="line" style={{width: 47 + '%'}}>47%</span>
                                            </div>
                                        </div>
                                    );
                                })}
                            </div>
                        </div>
                    </div>
                </div>
                <button className="btn btn-scroll-down">Scroll down</button>
            </div>
        </section>
    </main>      
}


return (
    <div>
        {content}
    </div>
)
}


 export default ArtistDetail;

我不知道如何在这个 div 中显示百分比数据:

<div className="graph-line">
  <span className="line" style={{ width: 47 + "%" }}>
    47%
  </span>
</div>;

看起来像这样

对于图表,我使用了来自here的代码

【问题讨论】:

    标签: javascript reactjs api d3.js response


    【解决方案1】:

    干得好!

    根据 Nivo 文档,我会尝试使用这个

     <ResponsiveBar
            data={data.popularity}
            keys={[ 'city', 'percentage' ]}
            maxValue={100}
           ...
       >
    

    ..将 maxValue 设置为 100 或百分比。将 data.popularityartist.data.data.popularity 传递给 data 属性并设置适当的键。

    {artist.data.data.popularity.map(popular => {
                                        const {city} = popular;
    

    这可能是问题所在 - 从“流行”中解构“城市”和“百分比”。

    const { city, percentage } = popular
    

    然后

    <span>{percentage}%</span>
    

    【讨论】:

      【解决方案2】:

      查看设计而不是 Nivo,您实际上可以使用 simple css 。下面是我使用 flex 实现这一目标的代码。 CodeSandbox Link

       <div className="App">
            <h1>Most Popular in</h1>
            {popularity.map((popular) => (
              <div>
                <div>{popular.city}</div>
                <div className="linear-graph">
                  <div
                    style={{
                      background: "black",
                      flex: popular.percentage
                    }}
                  />
                  <div
                    style={{
                      background: "#c5c5c56b",
                      flex: 10 - popular.percentage
                    }}
                  />
                </div>
              </div>
            ))}
          </div>
      

      以及相应的 css

      .App {
        font-family: sans-serif;
        color: black;
      }
      
      .linear-graph {
        width: 200px;
        display: flex;
        position: relative;
        height: 6px;
        margin-bottom: 10px;
      }
      

      干杯

      【讨论】:

        猜你喜欢
        • 2022-08-06
        • 2019-08-29
        • 1970-01-01
        • 1970-01-01
        • 2020-09-29
        • 1970-01-01
        • 2021-09-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多