Nivo 条形图调用标签函数数百次
Posted
技术标签:
【中文标题】Nivo 条形图调用标签函数数百次【英文标题】:Nivo bar chart calling label function hundreds of times 【发布时间】:2020-06-26 10:27:06 【问题描述】:我正在使用 Nivo 栏来表示用户的预算进度。我通过将类别余额除以类别目标来标准化数据。示例数据。
[
"category": "Gas",
"budget": 0.24,
"over_budget": 0.0
,
"category": "Groceries",
"budget": 1.0,
"over_budget": 0.26
]
我不希望将这些值用作图表上的标签。我打算用实际余额值作为标签。我有一个端点,它将返回一个类别的余额,并尝试了以下使用该值:
<ResponsiveBar
...
label=d => this.getDollarAmount(d.value)
...
>
功能POC为:
getDollarAmount(value)
console.log("hitting getDollarAmount")
return 1
;
日志消息被记录了 500 多次。我的期望是,对于图表中的每个条形,该函数只会被点击一次。
我仍在学习反应,所以这可能是显而易见的。提前致谢!
编辑 - 这是整个 BarChart 组件:
import axios from 'axios';
import React, Component from "react";
import ResponsiveBar from '@nivo/bar'
// Nivo theming
const theme =
axis:
ticks:
line:
stroke: "#e9ecee",
strokeWidth: 40
,
text:
// fill: "#919eab",
fill: "black",
fontFamily: "BlinkMacSystemFont",
fontSize: 16
,
grid:
line:
stroke: "#e9ecee",
strokeWidth: 5
,
legends:
text:
fontFamily: "BlinkMacSystemFont"
;
let budgetStatusAPI = 'http://127.0.0.1:8000/api/budget_status/?auth_user=1&month=2020-02-01';
class BarChart extends Component
constructor(props)
super(props);
this.state =
data: [],
this.getDollarAmount = this.getDollarAmount.bind(this);
componentDidMount()
console.log("component did mount")
axios.get(budgetStatusAPI).then(response =>
this.setState(
data: response.data
, function ()
console.log(this.state.data);
)
);
componentDidUpdate()
console.log("component did update")
getDollarAmount(value)
console.log("hitting getDollarAmount")
console.log(value)
return 1
;
render()
const hard_data = [
"category": "Groceries",
"budget_status": 1.0,
"over_budget": .26,
,
"category": "Gas",
"budget_status": .24,
"over_budget": 0.0,
]
return(
<ResponsiveBar
maxValue=1.5
markers=[
axis: 'x',
value: 1,
lineStyle: stroke: 'rgba(0, 0, 0, .35)', strokeWidth: 2 ,
legend: 'Goal',
legendOrientation: 'horizontal',
legendPosition: 'top'
,
]
enableGridX=false
gridXValues=[1]
enableGridY=false
data=this.state.data
// data=hard_data
keys=['budget_status', 'over_budget']
indexBy="category"
margin= top: 25, right: 130, bottom: 50, left: 125
padding=0.3
layout="horizontal"
colors= scheme: 'set2'
theme=theme
defs=[
id: 'dots',
type: 'patternDots',
background: 'inherit',
color: '#38bcb2',
size: 4,
padding: 1,
stagger: true
,
id: 'lines',
type: 'patternLines',
background: 'inherit',
color: '#eed312',
rotation: -45,
lineWidth: 6,
spacing: 10
]
borderColor= from: 'color', modifiers: [ [ 'darker', 1.6 ] ]
axisBottom=null
label=d => this.getDollarAmount(d.value)
isInteractive=false
animate=true
motionStiffness=90
motionDamping=15
/>
)
export default BarChart;
转载于此:https://codesandbox.io/s/nivo-bar-label-issue-k4qek
【问题讨论】:
您的组件(或其他应用程序状态管理)代码中有一些东西会触发多个渲染。请提供完整的组件代码。 我已经添加了整个组件。我注意到,当我对数据使用硬编码值时,不会发生此问题。如果我使用从状态中抓取的数据,它就会发生。 我在这里转载了这个:codesandbox.io/s/nivo-bar-label-issue-k4qek 仍然不确定它为什么会发生。 请在下面查看我的答案。 【参考方案1】:之所以会发生多次调用,是因为条形图正在为每个动画刻度/帧渲染调用 label
函数。如果我们设置一个计数器,我们将看到将animate
属性设置为true
,它将从450+
渲染到550+
次,但是如果我们将属性animate
设置为false
,我们将它会渲染6
次,这正是> 0.0
的价格值。
如果您想避免所有这些渲染,则必须使用 animate=false
属性禁用动画,如下所示:
getDollarAmount(value)
// Remove every console.log inside this function
return `$$value`
render()
return (
<ResponsiveBar
animate=false
label=d => this.getDollarAmount(d.value)
...
);
您可以检查它是否运行到您克隆的CodeSandbox。我已将animate
设置为false
并且counter
内的getDollarAmount
日志正在调用6
次。尝试将animate
更改为true
,您将看到500+-
渲染。
另外,您不必为每个label
调用创建一个函数,您只需传递getDollarAmount
函数并让它处理整个d
参数,如下所示:
getDollarAmount(d)
// Remove every console.log inside this function
return `$$d.value`
render()
return (
<ResponsiveBar
animate=false
label=this.getDollarAmount
...
);
【讨论】:
我怎么知道它还没有调用该函数数百次? @brewcrazy 你是对的,这不是罪魁祸首,动画才是。检查我更新的答案。以上是关于Nivo 条形图调用标签函数数百次的主要内容,如果未能解决你的问题,请参考以下文章
Python使用seaborn可视化分组条形图并且在分组条形图的条形上添加数值标签(seaborn grouped bar plot add labels)