Closed andreoliveira56 closed 6 years ago
You need
https://github.com/kirjs/react-highcharts#accessing-highcharts-api-after-render
It works for me.
import React, {Component} from 'react'
import HighchartsExporting from 'highcharts-exporting'
import HighchartsMore from 'highcharts-more'
import Highcharts from 'highcharts'
import ReactHighcharts from 'react-highcharts'
export default class Example extends Component {
setData = () => {
let chart = this.refs.chart.getChart();
chart.series[0].update({
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
});
}
render() {
let config = {
chart: {
events: {
addSeries: function () {
let label = this.renderer.label('A series was added, about to redraw chart', 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
}
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5]
}]
}
HighchartsMore(ReactHighcharts.Highcharts);
HighchartsExporting(ReactHighcharts.Highcharts);
let charts = <ReactHighcharts config={config} ref="chart"> </ReactHighcharts>
return (
<div>
<button onClick={this.setData}>Change data</button>
{charts}
</div>
)
}
}
@ilyjs It would work if my data lives in the component. But my data comes from outside the component.
Something like:
let { value } = this.props;
config = {
chart: {
type: 'pie'
},
series : [{
name: 'Series Name',
....
data: [{
name: 'Name 1',
y: value
} , {
...
}]
}]
};
return <HighChart config={config} />
With a code like this, the chart just re-renders but without animation: it just appears with the new data.
The animations are a major feature of highcharts, and should be included in any wrapper. Check out https://github.com/whawker/react-jsx-highcharts. I'm still experimenting with both to see which offers better animations.
@andreoliveira56 I understood you .
You can't do this let { value } = this.props; in config : y: value. In this case, the graph will always be reset.
You need to use componentWillReceiveProps (Learn more) and neverReflow={true}. And most importantly https://github.com/kirjs/react-highcharts#accessing-highcharts-api-after-render
1) Without Redux
import React, {Component} from 'react'
import Highcharts from 'highcharts'
import ReactHighcharts from 'react-highcharts'
export default class superChart extends Component {
componentWillReceiveProps(nextProps){
const { value } = nextProps
this.setData(value)
}
setData(value){
let chart = this.refs.chart.getChart();
chart.series[0].update({
data: value
});
}
render() {
let config = {
chart: {
events: {
addSeries: function () {
let label = this.renderer.label('A series was added, about to redraw chart', 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
}
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: this.props.value
}]
}
let charts = <ReactHighcharts neverReflow={true} config={config} ref="chart"> </ReactHighcharts>
return (
<div>
{charts}
</div>
)
}
}
2) With Redux
import React, {Component} from 'react'
import Highcharts from 'highcharts'
import ReactHighcharts from 'react-highcharts'
import {connect} from "react-redux";
import {sideChart} from "../../src/AC";
class superChart extends Component {
getData = () => {
const {sideChart} = this.props
sideChart(this.refs.chart.getChart())
}
let {superChart} = this.props
render() {
let config = {
chart: {
events: {
addSeries: function () {
let label = this.renderer.label('A series was added, about to redraw chart', 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
}
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: superChart
}]
}
let charts = <ReactHighcharts neverReflow={true} config={config} ref="chart"> </ReactHighcharts>
return (
<div>
<button onClick={this.getData}>Change data</button>
{charts}
</div>
)
}
}
export default connect((state) => {
return {
superChart:state.chat.updateData
}
}, {sideChart})(superChart)
In "../../src/AC"
...........
export function sideChart(chart) {
return {
type: SIDE_CHART,
payload: { chart }
}
}
in reducer
. . . . .
const {type, payload, response} = action
switch (type) {
case SIDE_CHART: {
payload.chart.series[0].update({
data: ''Any variable"
});
return 'Any State'
}
}
Hi, I'm having the same issue with the animations, I'm trying to get the data from out source and update it in the click event (of a point in the series), the data updates as required but the animation is not working (even after I tried what you suggested above)
my code is:
import React from 'react'; import ReactHighcharts from 'react-highcharts'; import Highcharts from 'highcharts';
export default class CustomChart extends React.Component { constructor(props) { super(props); this.state = { data: [], config: this.getChartConfiguration(props) }; }
getChartConfiguration(props) {
return {
chart: {
type: props.type,
events: {
addSeries: function () {
let label = this.renderer.label('A series was added, about to redraw chart', 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
}
},
title: { text: props.title },
xAxis: {
type: 'category',
},
legend: {
enabled: props.withLegend,
},
tooltip: {
headerFormat:
'<span style="font-size:11px">{series.name}</span><br>',
pointFormat:
'<span style="color:{point.color}">{point.name}</span>: <b>{point.y}</b>',
},
credits: {
enabled: false
},
series: [
{
name: props.tooltipHeader,
colorByPoint: true,
showInLegend: props.withLegend,
point: {
events: {
click: function (obj) {
props.handleClick(obj.point.name);
}
}
},
data: props.data
},
]
}
}
componentWillReceiveProps(props) {
let chart = this.refs.chart.getChart();
chart.series[0].update({ name: 'new title' });
chart.series[0].setData(props.data);
}
render() {
return (
<ReactHighcharts neverReflow config={this.state.config} ref="chart" />
);
}
}
I am using "highcharts": "^5.0.14", "react-highcharts": "^15.0.0",
any suggestions?
thanks much!
@orbengigi For highcharts 5.x.x use v. 13.0.0
I tried this:
"highcharts": "5.0.14",
"react-highcharts": "13.0.0",
didn't work..
@orbengigi Sorry !!!
Use shouldComponentUpdate
shouldComponentUpdate(nextProps) {
let chart = this.refs.chart.getChart();
chart.series[0].update({ name: 'new title' });
chart.series[0].setData(nextProps.data);
return false;
}
You don't need neverReflow true.
Use it wisely!
shouldComponentUpdate return false;
Stops rendering this component. You can change it for your tasks
Sorry, still not working..
import React from 'react'; import ReactHighcharts from 'react-highcharts'; import Highcharts from 'highcharts';
//This component vhart type is defined in props //possible values: pie, column, bar.. export default class CustomChart extends React.Component { constructor(props) { super(props); this.state = { data: [], config: this.getChartConfiguration(props) }; }
shouldComponentUpdate(props) {
let chart = this.refs.chart.getChart();
chart.series[0].update({ name: 'new title' });
chart.series[0].setData(props.data);
return false;
}
getChartConfiguration(props) {
return {
chart: {
type: props.type,
events: {
addSeries: function () {
let label = this.renderer.label('A series was added, about to redraw chart', 100, 120)
.attr({
fill: Highcharts.getOptions().colors[0],
padding: 10,
r: 5,
zIndex: 8
})
.css({
color: '#FFFFFF'
})
.add();
setTimeout(function () {
label.fadeOut();
}, 1000);
}
}
},
title: { text: props.title },
xAxis: {
type: 'category',
},
legend: {
enabled: props.withLegend,
},
tooltip: {
headerFormat:
'<span style="font-size:11px">{series.name}</span><br>',
pointFormat:
'<span style="color:{point.color}">{point.name}</span>: <b>{point.y}</b>',
},
credits: {
enabled: false
},
series: [
{
name: props.tooltipHeader,
colorByPoint: true,
showInLegend: props.withLegend,
point: {
events: {
click: function (obj) {
props.handleClick(obj.point.name);
}
}
},
data: props.data
},
]
};
}
render() {
return (
<ReactHighcharts config={this.state.config} ref="chart" />
);
}
}
am I doing anything wrong? still using these packages: "highcharts": "5.0.14", "react-highcharts": "13.0.0",
@orbengigi Format the code please, and better create an example in https://stackblitz.com
Thank for helping, I added this https://stackblitz.com/edit/react-5mwqst?file=Hello.js although it dosen't seem to load the chart.. got any idea?
@orbengigi It works . For example https://stackblitz.com/edit/react-pqs9kh . I will try to correct your example.
@orbengigi Done https://stackblitz.com/edit/react-sgotbg
Thanks, but this is not the behaviour I was looking for, trying to apply what you did to update the data in a pie click event that calls a callback
@orbengigi
Open the console and click on the pie
https://stackblitz.com/edit/react-sgotbg I think you need here. Soon we will update the demo and add various examples.
Great answer! This works great 😀
Thanks much for your help!
@orbengigi Great!
Hi!
Imagine that I have a dropdown, a Pie Chart and the config data lives outside the component that renders the Pie Chart.
Then, when I change the filter, the config data changes and the Chart should re-render. The problem is: The Chart re-renders without animation! The chart just appears.
I tried this: https://github.com/kirjs/react-highcharts/issues/171#issuecomment-268418008, but it just re-renders the Chart and it animates as is a new Chart.
I would like to have a smooth animation like when we click on the Legend. Is that possible?
Thank you.