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'} ]);