Working with Charts in motion [Animating chart] - reactjs

I have created a areaspline chart using highcharts library and making it animated with play/pause button transition between weeks of data
Ref. https://www.highcharts.com/blog/tutorials/176-charts-in-motion/
jsfiddle Ref. https://jsfiddle.net/larsac07/wkev75nL/?utm_source=website&utm_medium=embed&utm_campaign=wkev75nL
in the above example, we are animating the chart week wise
dataSet used :
dataSequence = [
{
name: 'Week 1',
data: [1, 2, 2, 1, 1, 2, 2]
}, {
name: 'Week 2',
data: [6, 12, 2, 3, 3, 2, 2]
}, {
name: 'Week 3',
data: [4, 5, 6, 5, 5, 4, 9]
}, {
name: 'Week 4',
data: [5, 5, 6, 6, 5, 6, 6]
}, {
name: 'Week 5',
data: [6, 7, 7, 6, 6, 6, 7]
}, {
name: 'Week 6',
data: [8, 9, 9, 8, 8, 8, 9]
}, {
name: 'Week 7',
data: [9, 10, 4, 10, 9, 9, 9]
}, {
name: 'Week 8',
data: [1, 10, 10, 10, 10, 11, 11]
}, {
name: 'Week 9',
data: [11, 11, 12, 12, 12, 11, 11]
}
]
I don't want change chart
on play button click I want animate the data points 11 data point for week1 to same data point but different value on y axis for week2
xAxis = ["week1", "Week2", ..... ],
yAxis = [[1,2,3,4,5,6,7,8,9,10,11], [3,5,7,8,2,1,5,7,6,1,10], ....]
on the play button it would transit between week1 then will go to week 2 and so till last week number available.
Trying to have something like this Ref. https://aatishb.com/covidtrends/
this chart is plotted using this dataset for series
Highcharts.chart("container", {
chart: {
type: "areaspline"
},
tooltip: {
shared: true,
valueSuffix: " units"
},
xAxis: {
categories: [
"Week 1",
"Week 2",
"Week 3",
"Week 4",
"Week 5",
"Week 6",
"Week 7"
]
},
yAxis: {
title: {
text: "Index"
}
},
legend: {
layout: "horizontal",
align: "right",
verticalAlign: "top",
x: 50,
y: 50,
floating: true,
borderWidth: 1,
backgroundColor:
(Highcharts.theme && Highcharts.theme.legendBackgroundColor) ||
"#FFFFFF"
},
plotOptions: {
areaspline: {
fillOpacity: 0.5
}
},
credits: {
enabled: false
},
series: [
{
name: "By week",
data: dataSequence[value].data.slice()
},
{
type: "spline",
name: "Topic 1",
data: [3, 2, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 2",
data: [1, 5, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 3",
data: [3, 7, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 4",
data: [5, 1, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 5",
data: [7, 3, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 6",
data: [9, 2, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 7",
data: [11, 8, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 8",
data: [13, 11, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 9",
data: [15, 7, 1, 3, 4, 7, 8]
},
{
type: "spline",
name: "Topic 10",
data: [7, 5, 1, 3, 4, 7, 8]
}
],
title: {
text: ""
},
subtitle: {
text: "Efficiency Index of Topics"
}
});
this my update function in react
update(increment) {
var input = $("#play-range")[0];
var output = $("#play-output")[0];
if (increment) {
input.value = parseInt(input.value) + increment;
}
output.innerHTML = this.state.dataSequence[input.value].name;
this.setState({
value: input.value
});
if (input.value >= input.max) {
// Auto-pause
this.pause();
this.setState(
{
value: 0
},
() => {
output.innerHTML = this.state.dataSequence[0].name;
}
);
}
}
the whole chart is plotted at once, I need something that it should transit
first, it plots all data points for week1 then week 2 after that week 3 when I click on the play button

You need to start with an empty data and use addPoint method in the update function:
function update(increment) {
var input = $('#play-range')[0],
output = $('#play-output')[0],
increment;
chart.series[0].addPoint(dataSequence[input.value].data[actualPointIndex]);
actualPointIndex += increment;
if (actualPointIndex === 6) {
actualPointIndex = 0;
input.value = parseInt(input.value) + increment;
}
output.innerHTML = dataSequence[input.value].name; // Output value
if (input.value >= input.max) { // Auto-pause
pause($('#play-pause-button')[0]);
}
}
Live demo: https://jsfiddle.net/BlackLabel/stpxyfca/
API Reference: https://api.highcharts.com/class-reference/Highcharts.Series#addPoint

Related

HighCharts Series Space

Hi im trying to remove an empty space between series.
Im using Highcharts with react.
I got a dynamic chart area and i need to remove the gap between the walls.
See the example below
Link: https://jsfiddle.net/dczv0u53/13/
Code:
xAxis: {
tickPositions: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
},
series: [
{
groupPadding: 1,
type: `area`,
data: [
[0, 1],
[1, 3],
[2, 2],
],
states: {
inactive: {
opacity: 0.8
}
}
},
{
type: `area`,
groupPadding: 1,
data: [
[5, 4],
[8, 3],
[10, 3]
],
states: {
inactive: {
opacity: 0.8
}
}
},
]
});
You can use breaks:
xAxis: {
...,
breaks: [{
from: 2,
to: 5,
breakSize: 0
}]
}
Live demo: https://jsfiddle.net/BlackLabel/tb4czrfx/
API Reference: https://api.highcharts.com/highcharts/xAxis.breaks

show stacked legends in a grouped column highcharts- RecatJs highcharts

I have an example taken from highcharts: this question is very similar to Highcharts: legend of stacked chart
however I havent found the answer I'm looking there.
what I'm looking is something is to group the stack legends like shown below for every name legend it belongs.
in my case I want to have following structure in the legend
Male:
Joe
JOhn
Female:
Janet
Jane
is that possible?
I also tried : http://jsfiddle.net/7sgdbezh/
however since I'd be having multiple legends I dont want to clutter the chart with too many redundant stack name values.
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},
tooltip: {
formatter: function() {
return '<b>'+ this.x +'</b><br/>'+
this.series.name +': '+ this.y +'<br/>'+
'Total: '+ this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2],
stack: 'male'
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5],
stack: 'male'
}, {
name: 'Jane',
data: [2, 5, 6, 2, 1],
stack: 'female'
}, {
name: 'Janet',
data: [3, 0, 4, 4, 3],
stack: 'female'
}]
});
});

Multiple date array with same value by name on Highcharts

I want to custom highcharts, but before that I am stuck how to combine or manage multiple arrays with the same date and name value from JSON
// sample data JSON
const dataJson = [
{
"day": 1,
"month": 10,
"name": "John",
"value": 1000.0
},
{
"day": 1,
"month": 10,
"name": "Joe",
"value": 2000.0
},
{
"day": 2,
"month": 10,
"name": "John",
"value": 2000
},
{
"day": 2,
"month": 10,
"name": "Joe",
"value": 500
},
{
"day": 2,
"month": 10,
"name": "Joe",
"value": 500
},
{
"day": 2,
"month": 10,
"name": "Jane",
"value": 500
},
{
"day": 3,
"month": 10,
"name": "John",
"value": 1500
},
{
"day": 3,
"month": 10,
"name": "John",
"value": 2000
},
{
"day": 4,
"month": 10,
"name": "Jane",
"value": 1500
},
{
"day": 5,
"month": 10,
"name": "Janet",
"value": 1000
}
]
I want implement the above JSON into this highchart function:
Like merge day and month then show it in xAxis categories be day/month.
ex: day 1 and month 10 => 1/10.
Merge value same name in same day. Sample JSON day 2 Joe has 500 and 500. So in highchart series value for Joe is 1000 for day 2
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Total fruit consumption, grouped by gender'
},
xAxis: {
categories: ['1/10', '2/10', '3/10', '4/10', '5/10']
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [1000, 2000, 3500, 0, 0],
}, {
name: 'Joe',
data: [2000, 1000, 0, 0, 0],
}, {
name: 'Jane',
data: [0, 500, 0, 1500, 0],
}, {
name: 'Janet',
data: [0, 0, 0, 0, 1000],
}]
});
Here is link to my fiddle
Thanks
Ok, this way is maybe not the most performant to accomplish this task, but it gets the job done:
const dataJson = [{
day: 1,
month: 10,
name: "John",
value: 1000.0,
},
{
day: 1,
month: 10,
name: "Joe",
value: 2000.0,
},
{
day: 2,
month: 10,
name: "John",
value: 2000,
},
{
day: 2,
month: 10,
name: "Joe",
value: 500,
},
{
day: 2,
month: 10,
name: "Joe",
value: 500,
},
{
day: 2,
month: 10,
name: "Jane",
value: 500,
},
{
day: 3,
month: 10,
name: "John",
value: 1500,
},
{
day: 3,
month: 10,
name: "John",
value: 2000,
},
{
day: 4,
month: 10,
name: "Jane",
value: 1500,
},
{
day: 5,
month: 10,
name: "Janet",
value: 1000,
},
];
const res = dataJson.reduce((acc, cV) => {
if (acc[cV.name]) {
acc[cV.name] = {
day: {
...acc[cV.name].day,
[cV.day]: acc[cV.name].day[cV.day] ?
acc[cV.name].day[cV.day] + cV.value :
cV.value,
},
};
} else {
acc[cV.name] = {
day: {
[cV.day]: cV.value
}
};
}
return acc;
}, {});
let result = [];
Object.keys(res).forEach(name => {
const values = {
name
};
const data = [];
for (let i = 1; i <= 5; i++) {
if (res[name].day[i]) {
data.push(res[name].day[i]);
} else {
data.push(0);
}
}
values.data = data;
result.push(values);
});
console.log(result);
In the res variable, I change the array of json data into an object with the name and day as keys. If the day exists, I add the new amount to the current one, otherwise I create the key.
After that, I loop through the object and check whether values exist in a given day. If yes, then I push it to the data, if no, I push 0 to the data. My solution is for 5 days, but you can easily adjust it for any given amount of days.

how to get json data form below format using angularJs 1.6

How can I access the JSON data below format: To get JSON data like id et.al
[
{
id: 10,
hotelName: "TajBanjara",
pricePerNight: 200.23,
nbOfNights: 3,
totalPrice: 600.6899999999999
},
{
id: 11,
hotelName: "TajKrishna",
pricePerNight: 90.23,
nbOfNights: 2,
totalPrice: 180.46
},
{
id: 12,
hotelName: "Novatel",
pricePerNight: 100.23,
nbOfNights: 3,
totalPrice: 300.69
}
]
var data = [ { id: 10, hotelName: "TajBanjara", pricePerNight: 200.23,
nbOfNights: 3, totalPrice: 600.6899999999999 }, { id: 11, hotelName:
"TajKrishna", pricePerNight: 90.23, nbOfNights: 2, totalPrice: 180.46
}, { id: 12, hotelName: "Novatel", pricePerNight: 100.23, nbOfNights:
3, totalPrice: 300.69 } ]
and you can get the id value as
data[0].id for the first object in json array.

Highcharts - Passing Data for Flags in Array. It is not rendered

I am trying to render 3 flags (experimenting with flags) in a candlestick chart in Highchart, but the flag {x: Date.UTC(2012, 7, 6),title: 'On series'}
Is not getting rendered. Why?
$(function() {
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function(data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length,
arrflag =[
{x: Date.UTC(2012, 7, 17),title: 'On series'},
{x: Date.UTC(2012, 7, 9),title: 'On series'}
];
arrflag.push([
{x: Date.UTC(2012, 7, 6),title: 'On series'}
]);
for (i = 0; i < dataLength; i++) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
])
}
// set the allowed units for data grouping
var groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]];
// create the chart
chart = new Highcharts.StockChart({
chart: {
renderTo: 'container',
alignTicks: false
},
rangeSelector: {
selected: 0
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
title: {
text: 'OHLC'
},
height: 200,
lineWidth: 2
}, {
title: {
text: 'Volume'
},
top: 300,
height: 100,
offset: 0,
lineWidth: 2
}],
series: [{
type: 'candlestick',
name: 'AAPL',
id: 'AAPLX',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
},{
type: 'flags',
name: 'Flags on series',
data: arrflag,
onSeries: 'AAPLX',
shape: 'squarepin'
}]
});
});
});​
Live DEMO
You array of flags has the following value:
arrflag =[
{x: Date.UTC(2012, 7, 17),title: 'On series'},
{x: Date.UTC(2012, 7, 9),title: 'On series'}
];
When you push the other flag you add it to another array, which isn't the expected. So the result will be.
arrflag =[
{x: Date.UTC(2012, 7, 17),title: 'On series'},
{x: Date.UTC(2012, 7, 9),title: 'On series'},
[{x: Date.UTC(2012, 7, 6),title: 'On series'}]
];
Remove [ and ] from the following code.
arrflag.push([
{x: Date.UTC(2012, 7, 6),title: 'On series'}
]);

Resources