VChart
VChart copied to clipboard
我在使用react-vchart,无法通过更新props更新图表的3d配置
您好,代码如下所示(不好意思不知道为什么乱了),我在父组件更新了props.enable3d,通过useEffect也观察到了props.enable3d的更新,但是图表组件并没有任何变化。 ` function AreaChart(props) {
const [spec, setSpec] = useState({
type: 'area',
data: props.dataConfig.data,
...
})
const [options, setOptions] = useState({
options3d: {
enable: true,
enableView3dTransform: props.enable3d,
},
})
React.useEffect(()=>{
setOptions({
options3d: {
enable: true,
enableView3dTransform: props.enable3d,
...
}
})
},[props.enable3d])
return (
<VChart
spec={spec}
options={options}
className={props.chartname}
/>
);
}`
@tacit0428 请提供一下完整的代码,复现问题哦
您好,第一块代码是子组件,第二块代码是使用该子组件。我这边的问题是当创建组件时,options.options3d.enableView3dTransform设置为false,点击rotate希望触发更新该值为true,但图表没有任何反应。
定义AreaChart:
import React, { useState } from 'react';
import { VChart } from '@visactor/react-vchart';
function AreaChart(props) {
const [spec, setSpec] = useState({
type: 'area',
data: props.dataConfig.data,
xField: props.dataConfig.xField,
yField: props.dataConfig.yField,
zField: props.dataConfig.zField,
seriesField: props.dataConfig.seriesField,
title: {
visible: false,
text: 'Stacked area chart of cosmetic products sales'
},
axes: [
{
orient: 'bottom',
mode: '3d',
domainLine: {
visible: false,
style: { stroke: '#000' }
},
tick: {
visible:false,
style: { stroke: '#000' }
},
label: {
visible: false
}
},
{
orient: 'left',
mode: '3d',
domainLine: { visible: false },
tick: { visible: false },
label: {
style: {
fill: 'rgb(162, 162, 162)'
}
},
grid: {
visible:false,
style: {
lineDash: [0],
stroke: 'rgb(231, 231, 231)'
}
}
},
{
orient: 'z',
mode: '3d',
type: 'band',
label: { visible:false },
domainLine: { visible: false },
grid: { visible: false },
width: 200,
height: 500,
depth: 100
}
],
tooltip: {
visible: false,
},
point: {
visible: false
},
hover: {enable: false},
select: {enable: false},
crosshair: {
xField: {
visible: false,
},
},
stack: false,
legends: [{ visible: false }],
width: props.styleConfig.width,
height: props.styleConfig.height,
background: 'rgba(0,0,0,0)'
})
const [options, setOptions] = useState({
options3d: {
enable: true,
enableView3dTransform: false,
alpha: 0,
beta: 0,
fieldRatio: 25,
fieldDepth: 500,
center: {
x: Math.round(props.styleConfig.width/2),
y: Math.round(props.styleConfig.height/2)
}
}
})
React.useEffect(()=>{
setOptions({
options3d: {
enable: true,
enableView3dTransform: props.enable3d,
alpha: 0,
beta: 0,
fieldRatio: 25,
fieldDepth: 500,
center: {
x: Math.round(props.styleConfig.width/2),
y: Math.round(props.styleConfig.height/2)
}
}
})
},[props.enable3d])
return (
<VChart
spec={spec}
options={options}
className={props.chartname}
/>
);
}
export default AreaChart;
使用AreaChart:
import React, {Component, createRef} from 'react'
import AreaChart from '../../charts/areachart';
class ChartTest extends Component {
constructor(props) {
super(props);
this.dataConfig = {
data: {
values: [
{ type: 'Nail polish', country: 'Africa', value: 4229 },
{ type: 'Nail polish', country: 'EU', value: 4376 },
{ type: 'Nail polish', country: 'China', value: 3054 },
{ type: 'Nail polish', country: 'USA', value: 12814 },
{ type: 'Eyebrow pencil', country: 'Africa', value: 3932 },
{ type: 'Eyebrow pencil', country: 'EU', value: 3987 },
{ type: 'Eyebrow pencil', country: 'China', value: 5067 },
{ type: 'Eyebrow pencil', country: 'USA', value: 13012 },
{ type: 'Rouge', country: 'Africa', value: 5221 },
{ type: 'Rouge', country: 'EU', value: 3574 },
{ type: 'Rouge', country: 'China', value: 7004 },
{ type: 'Rouge', country: 'USA', value: 11624 },
{ type: 'Lipstick', country: 'Africa', value: 9256 },
{ type: 'Lipstick', country: 'EU', value: 4376 },
{ type: 'Lipstick', country: 'China', value: 9054 },
{ type: 'Lipstick', country: 'USA', value: 8814 },
{ type: 'Eyeshadows', country: 'Africa', value: 3308 },
{ type: 'Eyeshadows', country: 'EU', value: 4572 },
{ type: 'Eyeshadows', country: 'China', value: 12043 },
{ type: 'Eyeshadows', country: 'USA', value: 12998 },
{ type: 'Eyeliner', country: 'Africa', value: 5432 },
{ type: 'Eyeliner', country: 'EU', value: 3417 },
{ type: 'Eyeliner', country: 'China', value: 15067 },
{ type: 'Eyeliner', country: 'USA', value: 12321 },
{ type: 'Foundation', country: 'Africa', value: 13701 },
{ type: 'Foundation', country: 'EU', value: 5231 },
{ type: 'Foundation', country: 'China', value: 10119 },
{ type: 'Foundation', country: 'USA', value: 10342 },
{ type: 'Lip gloss', country: 'Africa', value: 4008 },
{ type: 'Lip gloss', country: 'EU', value: 4572 },
{ type: 'Lip gloss', country: 'China', value: 12043 },
{ type: 'Lip gloss', country: 'USA', value: 22998 },
{ type: 'Mascara', country: 'Africa', value: 18712 },
{ type: 'Mascara', country: 'EU', value: 6134 },
{ type: 'Mascara', country: 'China', value: 10419 },
{ type: 'Mascara', country: 'USA', value: 11261 }
]
},
xField: 'type',
yField: 'value',
zField: 'country',
seriesField: 'country'
}
this.styleConfig = {
width: 400,
height: 400
}
this.state = {
enable3d: false,
}
}
rotate = () => {
console.log('rotate')
this.setState({
enable3d: true
})
}
render() {
return (
<div>
<AreaChart type='area' dataConfig={this.dataConfig} styleConfig={this.styleConfig} enable3d={this.state.enable3d} chartname={'chart'}/>
<input type="button" value="rotate" id="rotate" onClick={this.rotate}/>
</div>
)
}
}
export default ChartTest
@tacit0428 options 和 spec
不一致,不支持更新,只能初始化的时候设置一次
建议你可以在enable3d
切换的时候,给<VChart />
添加不同的key,实现创建新的实例的效果
<VChart
key={props.enable3d ? '3dChart' : '2dChart'}
spec={spec}
options={options}
className={props.chartname}
/>
@tacit0428 options 和
spec
不一致,不支持更新,只能初始化的时候设置一次建议你可以在
enable3d
切换的时候,给<VChart />
添加不同的key,实现创建新的实例的效果<VChart key={props.enable3d ? '3dChart' : '2dChart'} spec={spec} options={options} className={props.chartname} />
谢谢,不过请问如果要经常更新options的话要怎么办呢,我想经常调整角度,有时候也会调整options.options3d.alpha/beta,调整次数很多的情况下,反复生成新实例感觉不方便,有什么解决方法吗?
@tacit0428 options 和
spec
不一致,不支持更新,只能初始化的时候设置一次 建议你可以在enable3d
切换的时候,给<VChart />
添加不同的key,实现创建新的实例的效果<VChart key={props.enable3d ? '3dChart' : '2dChart'} spec={spec} options={options} className={props.chartname} />
谢谢,不过请问如果要经常更新options的话要怎么办呢,我想经常调整角度,有时候也会调整options.options3d.alpha/beta,调整次数很多的情况下,反复生成新实例感觉不方便,有什么解决方法吗?
- 可以在onReady事件中获取vchart实例
- 调用api更新角度
const stage = vchart.getStage();
stage.set3dOptions({center: { x: 500, y: 250 }, alpha: 0.2} // 这里传参数就行);
stage.renderNextFrame();
2. api更新角度
@tacit0428 如果着急的话,可以先调用上面提供的底层API; 这边我们会封装一个更新3d配置的API CC @neuqzxy
@tacit0428 options 和
spec
不一致,不支持更新,只能初始化的时候设置一次 建议你可以在enable3d
切换的时候,给<VChart />
添加不同的key,实现创建新的实例的效果<VChart key={props.enable3d ? '3dChart' : '2dChart'} spec={spec} options={options} className={props.chartname} />
谢谢,不过请问如果要经常更新options的话要怎么办呢,我想经常调整角度,有时候也会调整options.options3d.alpha/beta,调整次数很多的情况下,反复生成新实例感觉不方便,有什么解决方法吗?
- 可以在onReady事件中获取vchart实例
- 调用api更新角度
const stage = vchart.getStage(); stage.set3dOptions({center: { x: 500, y: 250 }, alpha: 0.2} // 这里传参数就行); stage.renderNextFrame();
我尝试了下您说的方法,我在onready里确实可以拿到实例,但是我把这个实例保存到state中,再次调用会发现为空
用会发
你的调用逻辑是什么?最好给一个在线demo
@xile611 @neuqzxy 你好,我的使用方法是这样的,但是点击change后,我发现图表并没有更新
function AreaChart(props) {
const [spec, setSpec] = useState({
type: 'area',
data: {
values: [
{ type: 'Nail polish', country: 'Africa', value: 4229 },
{ type: 'Nail polish', country: 'EU', value: 4376 },
{ type: 'Nail polish', country: 'China', value: 3054 },
{ type: 'Nail polish', country: 'USA', value: 12814 },
{ type: 'Eyebrow pencil', country: 'Africa', value: 3932 },
{ type: 'Eyebrow pencil', country: 'EU', value: 3987 },
{ type: 'Eyebrow pencil', country: 'China', value: 5067 },
{ type: 'Eyebrow pencil', country: 'USA', value: 13012 },
{ type: 'Rouge', country: 'Africa', value: 5221 },
{ type: 'Rouge', country: 'EU', value: 3574 },
{ type: 'Rouge', country: 'China', value: 7004 },
{ type: 'Rouge', country: 'USA', value: 11624 },
{ type: 'Lipstick', country: 'Africa', value: 9256 },
{ type: 'Lipstick', country: 'EU', value: 4376 },
{ type: 'Lipstick', country: 'China', value: 9054 },
{ type: 'Lipstick', country: 'USA', value: 8814 },
{ type: 'Eyeshadows', country: 'Africa', value: 3308 },
{ type: 'Eyeshadows', country: 'EU', value: 4572 },
{ type: 'Eyeshadows', country: 'China', value: 12043 },
{ type: 'Eyeshadows', country: 'USA', value: 12998 },
{ type: 'Eyeliner', country: 'Africa', value: 5432 },
{ type: 'Eyeliner', country: 'EU', value: 3417 },
{ type: 'Eyeliner', country: 'China', value: 15067 },
{ type: 'Eyeliner', country: 'USA', value: 12321 },
{ type: 'Foundation', country: 'Africa', value: 13701 },
{ type: 'Foundation', country: 'EU', value: 5231 },
{ type: 'Foundation', country: 'China', value: 10119 },
{ type: 'Foundation', country: 'USA', value: 10342 },
{ type: 'Lip gloss', country: 'Africa', value: 4008 },
{ type: 'Lip gloss', country: 'EU', value: 4572 },
{ type: 'Lip gloss', country: 'China', value: 12043 },
{ type: 'Lip gloss', country: 'USA', value: 22998 },
{ type: 'Mascara', country: 'Africa', value: 18712 },
{ type: 'Mascara', country: 'EU', value: 6134 },
{ type: 'Mascara', country: 'China', value: 10419 },
{ type: 'Mascara', country: 'USA', value: 11261 }
]
},
xField: 'type',
yField: 'value',
zField: 'country',
seriesField: 'country',
title: {
visible: false,
text: 'Stacked area chart of cosmetic products sales'
},
axes: [
{
orient: 'bottom',
mode: '3d',
domainLine: {
visible: false,
style: { stroke: '#000' }
},
tick: {
visible:false,
style: { stroke: '#000' }
},
label: {
visible: false
}
},
{
orient: 'left',
mode: '3d',
domainLine: { visible: false },
tick: { visible: false },
label: {
style: {
fill: 'rgb(162, 162, 162)'
}
},
grid: {
visible:false,
style: {
lineDash: [0],
stroke: 'rgb(231, 231, 231)'
}
}
},
{
orient: 'z',
mode: '3d',
type: 'band',
label: { visible:false },
domainLine: { visible: false },
grid: { visible: false },
width: 200,
height: 500,
depth: 100
}
],
tooltip: {
visible: false,
},
point: {
visible: false
},
hover: {enable: false},
select: {enable: false},
crosshair: {
xField: {
visible: false,
},
},
stack: false,
legends: [{ visible: false }],
width: props.styleConfig.width,
height: props.styleConfig.height,
background: 'rgba(0,0,0,0)'
})
const [options, setOptions] = useState({
options3d: {
enable: true,
enableView3dTransform: true,
alpha: 0,
beta: 0,
fieldRatio: 25,
fieldDepth: 500,
center: {
x: 200,
y: 200
}
}
})
const [stage, setStage] = useState({})
const onChangeStage = ()=>{
stage.set3dOptions({
enableView3dTransform: false,
})
stage.renderNextFrame()
console.log(stage)
}
const onChartReady = (chart)=>{
const getstage = chart.getStage()
setStage(getstage)
}
return (
<div>
<VChart
spec={spec}
options={options}
className={'testchart'}
onReady={onChartReady}
/>
<input type="button" value="change" onClick={onChangeStage}/>
</div>
);
}
export default AreaChart;
@xile611 @neuqzxy 你好,我的使用方法是这样的,但是点击change后,我发现图表并没有更新
function AreaChart(props) { const [spec, setSpec] = useState({ type: 'area', data: { values: [ { type: 'Nail polish', country: 'Africa', value: 4229 }, { type: 'Nail polish', country: 'EU', value: 4376 }, { type: 'Nail polish', country: 'China', value: 3054 }, { type: 'Nail polish', country: 'USA', value: 12814 }, { type: 'Eyebrow pencil', country: 'Africa', value: 3932 }, { type: 'Eyebrow pencil', country: 'EU', value: 3987 }, { type: 'Eyebrow pencil', country: 'China', value: 5067 }, { type: 'Eyebrow pencil', country: 'USA', value: 13012 }, { type: 'Rouge', country: 'Africa', value: 5221 }, { type: 'Rouge', country: 'EU', value: 3574 }, { type: 'Rouge', country: 'China', value: 7004 }, { type: 'Rouge', country: 'USA', value: 11624 }, { type: 'Lipstick', country: 'Africa', value: 9256 }, { type: 'Lipstick', country: 'EU', value: 4376 }, { type: 'Lipstick', country: 'China', value: 9054 }, { type: 'Lipstick', country: 'USA', value: 8814 }, { type: 'Eyeshadows', country: 'Africa', value: 3308 }, { type: 'Eyeshadows', country: 'EU', value: 4572 }, { type: 'Eyeshadows', country: 'China', value: 12043 }, { type: 'Eyeshadows', country: 'USA', value: 12998 }, { type: 'Eyeliner', country: 'Africa', value: 5432 }, { type: 'Eyeliner', country: 'EU', value: 3417 }, { type: 'Eyeliner', country: 'China', value: 15067 }, { type: 'Eyeliner', country: 'USA', value: 12321 }, { type: 'Foundation', country: 'Africa', value: 13701 }, { type: 'Foundation', country: 'EU', value: 5231 }, { type: 'Foundation', country: 'China', value: 10119 }, { type: 'Foundation', country: 'USA', value: 10342 }, { type: 'Lip gloss', country: 'Africa', value: 4008 }, { type: 'Lip gloss', country: 'EU', value: 4572 }, { type: 'Lip gloss', country: 'China', value: 12043 }, { type: 'Lip gloss', country: 'USA', value: 22998 }, { type: 'Mascara', country: 'Africa', value: 18712 }, { type: 'Mascara', country: 'EU', value: 6134 }, { type: 'Mascara', country: 'China', value: 10419 }, { type: 'Mascara', country: 'USA', value: 11261 } ] }, xField: 'type', yField: 'value', zField: 'country', seriesField: 'country', title: { visible: false, text: 'Stacked area chart of cosmetic products sales' }, axes: [ { orient: 'bottom', mode: '3d', domainLine: { visible: false, style: { stroke: '#000' } }, tick: { visible:false, style: { stroke: '#000' } }, label: { visible: false } }, { orient: 'left', mode: '3d', domainLine: { visible: false }, tick: { visible: false }, label: { style: { fill: 'rgb(162, 162, 162)' } }, grid: { visible:false, style: { lineDash: [0], stroke: 'rgb(231, 231, 231)' } } }, { orient: 'z', mode: '3d', type: 'band', label: { visible:false }, domainLine: { visible: false }, grid: { visible: false }, width: 200, height: 500, depth: 100 } ], tooltip: { visible: false, }, point: { visible: false }, hover: {enable: false}, select: {enable: false}, crosshair: { xField: { visible: false, }, }, stack: false, legends: [{ visible: false }], width: props.styleConfig.width, height: props.styleConfig.height, background: 'rgba(0,0,0,0)' }) const [options, setOptions] = useState({ options3d: { enable: true, enableView3dTransform: true, alpha: 0, beta: 0, fieldRatio: 25, fieldDepth: 500, center: { x: 200, y: 200 } } }) const [stage, setStage] = useState({}) const onChangeStage = ()=>{ stage.set3dOptions({ enableView3dTransform: false, }) stage.renderNextFrame() console.log(stage) } const onChartReady = (chart)=>{ const getstage = chart.getStage() setStage(getstage) } return ( <div> <VChart spec={spec} options={options} className={'testchart'} onReady={onChartReady} /> <input type="button" value="change" onClick={onChangeStage}/> </div> ); } export default AreaChart;
@xile611 @neuqzxy 请帮帮看一下这个问题,谢谢~我这边逻辑很简单,就是在onReady里getStage之后保存到状态中,然后点击某按钮时对stage进行set和render,但是没有效果。麻烦您看看是不是我的使用方法出错了,感谢
抱歉现在才回复,我新建了一个项目,看到这个已经是生效了,点击change之后图表已经发生了变化 @tacit0428
如果github不好消息沟通,可以加飞书群沟通 @tacit0428
如果github不好消息沟通,可以加飞书群沟通 @tacit0428
请问怎么加飞书群呢
如果github不好消息沟通,可以加飞书群沟通 @tacit0428
请问怎么加飞书群呢
@tacit0428