问题描述
我想使用Nivo库在React中构建一个简单的图表,以表示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,error: false
})
axios.get(url)
.then(response => {
setArtist({
loading: false,data: response.data,error: false
})
})
.catch(() => {
setArtist({
loading: false,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}>
<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
中的代码解决方法
辛苦了!
根据Nivo文档,我将尝试使用此
<ResponsiveBar
data={data.popularity}
keys={[ 'city','percentage' ]}
maxValue={100}
...
>
..将maxValue设置为100或百分比。将 data.popularity 或 artist.data.data.popularity 传递到data属性并设置适当的密钥。
{artist.data.data.popularity.map(popular => {
const {city} = popular;
这可能是问题所在-使“城市”和“百分比”与“受欢迎”同时消失。
const { city,percentage } = popular
然后
<span>{percentage}%</span>
,
查看设计而不是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;
}
欢呼