Highcharts Graph displaying 0 value continuously : Javascript Array - javascript

I am trying to display the points on a graph using PHP Mysql, I saved the data into an array in php Variable and then passed that array into a Javascript array.
Now, What I want to do is that I want to show the array elements one by one after every one second. But what is Happening is that the graph plots 0 value countinuously on the Highchart.
Here is my Code :
numArray = [1,5,3,5,6,3,3,7,4,6,7,3,5,3,6,7,5,2,5,7,4,6,4,5,3,6,7,8,5,4,3,6,7,8,5,7,8,8,5,3,2,4,6,7,4,6,7] ;
/* Just for understanding */
var json_array =numArray ;
var i = 0;
function next() {
return json_array[i];
i++;
}
Highcharts.chart('container', {
chart: {
type: 'line',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
// set up the updating of the chart each second
var series = this.series[0],
chart = this;
setInterval(function() {
var x = (new Date()).getTime(), // current time
y =next();
console.log(y) ;
series.addPoint([x, y], false, true);
}, 1000);
setInterval(function() {
chart.redraw(false);
}, 1000);
}
}
},
time: {
useUTC: false
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
headerFormat: '<b>{series.name}</b><br/>',
pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}'
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
animation: false,
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -1000; i <= 0; i += 1) {
data.push([
time + i * 10,
null
]);
}
return data;
}())
}]
});
Here is the Fiddle that I have created :
https://jsfiddle.net/abnitchauhan/v7tdLr1j/2/
The Chart runs till infinite loop and show only 0 Value. I just want to show the array values till the End

Check the below demo with the result you probably want to achieve.
Code:
const numArray = [1, 5, 3, 5, 6, 3, 3, 7, 4, 6, 7, 3, 5, 3, 6, 7, 5, 2, 5, 7, 4, 6, 4, 5, 3, 6, 7, 8, 5, 4, 3, 6, 7, 8, 5, 7, 8, 8, 5, 3, 2, 4, 6, 7, 4, 6, 7];
Highcharts.chart('container', {
chart: {
events: {
load: function() {
let chart = this,
now = (new Date()).getTime(),
i = 0;
const interval = setInterval(function() {
chart.series[0].addPoint([
now + i * 1000,
numArray[i]
]);
i++;
if (i === numArray.length) {
clearInterval(interval);
}
}, 1000);
}
}
},
xAxis: {
type: 'datetime'
},
series: [{}]
});
Demo:
https://jsfiddle.net/BlackLabel/vf906wam/

First of there is no endpoint in your setInterval method. It will keep on calling after 1 sec. You cant even stop. First, have a separate function to form data. Let's say have series data initialized. Have as a global variable. then have the Promise to generate you x point.
var promise1 = new Promise(function(resolve, reject) {
var points [];
setTimeout(function() {
var x = (new Date()).getTime(), // current time
y =next();
points.push([x, y], false, true);
if(your counter let says 1000 : points.lenght > 1000) {
resolve(points) //resolve your points
}
}, 300);});
wrap above thins in function and return a promise and call that.
callYourDefinedFun().then(function(points) {
// now you have points ready, series ready make your chart configuration and then
// call to render the chart
});

Related

Echart: How to set mark area to fill sections in xAxis

I have a problem with marking area: i need to be able to select a bar area based on xAxis, for example from 0 to 1, from 1 to 2, etc. But when i try to provide options for bar like
[{xAxis: 0, itemStyle: {color: red}},{xAxis: 1}]
it marks an area from a middle of xAxis area with an index of 0 to a middle of xAxis area with an index of 1. Is there a way to make it mark from start of an area to an end. Currently i managed to do so only with x option in pixels:
https://codesandbox.io/s/react-echart-markarea-ksj31?file=/src/index.js:714-726
Is there a better way to do it?
I can't imagine a method that would cover your requirements. It seems there is no such but nothing prevents to do it ourselves, see below.
When call function with join = true markedArea will calc as range from first to last.
calcMarkAreaByBarIndex(myChart, join = true, [4, 9])
When call function with join = false markedArea will calc for each bar.
calcMarkAreaByBarIndex(myChart, join = true, [4, 5, 6, 9])
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {},
xAxis: {
data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
},
yAxis: {},
series: [
{
id: 'myBar',
name: 'Series',
type: 'bar',
data: [11, 11, 11, 11, 12, 13, 110, 123, 113, 134, 93, 109],
markArea: {
data: [
[{x: 184},{x: 216}],
[{x: 224},{x: 256}],
]
},
},
]
};
myChart.setOption(option);
function calcMarkAreaByBarIndex(chartInstance, join = false, barIdx){
var series = chartInstance.getModel().getSeriesByType('bar');
var seriesData = series.map((s, idx) => s.getData())[0];
var barNum = seriesData.count();
var barCoors = [];
var layout = idx => seriesData.getItemLayout(idx);
for(var i = 0; i < barNum; i++){
if(!barIdx.includes(i)) continue;
barCoors.push([
{ x: layout(i).x },
{ x: layout(i).x + layout(i).width },
])
}
if(join){
return [
[
{ x: barCoors[0][0].x },
{ x: barCoors[barCoors.length - 1][1].x }
]
]
} else {
return barCoors
}
}
var markedAreas = {
series: {
id: 'myBar',
markArea: {
data: calcMarkAreaByBarIndex(myChart, join = true, [4,9])
}
}
};
myChart.setOption(markedAreas);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.7.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>
I found a solution, that worked for me:
Basically, you need to manually set yAxis's max props, add another xAxis, make it invisible, create a custom series with type 'bar' and set xAxisIndex to 1:
data: [maxYaxisValue,maxYaxisValue...], //length === xAxis.data.length
type: 'bar',
barWidth: '100%',
color: transparent,
xAxisIndex: 1,
And style a bar by index with background color and borderWidth
You can check the working example here
https://codesandbox.io/s/react-echart-markarea-m0mgq?file=/src/index.js

Highchart Data not getting displayed after looping through data from database

I am trying to get data from database and display it dynamically onto the highchart series data. For this i am using the following code:
$(function () {
$.ajax({
url: "/WebApi/MIPResource_DistrictWise",
cache: false,
success: function (data) {
var categories ;
var i;
for (i = 0; i < data.length; i++) {
categories += data[i].DISTRICT_NAME;
}
alert(categories);
// var xx = [][][];
// var data = "";
// var i;
// for (i = 0; i < xx.length; i++) {
// data += xx[i];
// }
Highcharts.chart('MIPDistrictWise', {
chart: {
type: 'bar'
},
title: {
text: 'MIP Resource Requirement <br> (District Wise)'
},
xAxis: {
categories: categories
},
yAxis: {
min: 0,
title: {
text: 'Total Resources Required'
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'percent',
borderWidth: 1,
groupPadding: 0,//add here
pointPadding: 0//add here
},
bar: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b><br>{point.percentage:.1f} %',
color: 'white'
}
}
},
series: [{
name: 'TVET',
data: [5, 3, 4, 7, 2, 4, 7, 2]
}, {
name: 'IGGs',
data: [2, 2, 3, 2, 1, 4, 7, 2]
}, {
name: 'CIF',
data: [3, 4, 4, 2, 5, 4, 7, 2]
}]
});
}
});
});
In the "alert" it shows names of the districts correctly but there is an additional keyword of "undefined" in the start with them, also showing the following error in console panel:Uncaught TypeError: Cannot read property 'parts/Globals.js' of undefined.i want to display name of categories dynamically from the database.
You need to check your loop
for (i = 0; i < data.length; i++) {
categories += data[i].DISTRICT_NAME;// Here some of the string output are undefined
}
So you might need to check the
data[i].DISTRICT_NAME
is undefined or not inside your loop. I'm attaching the link how to check undefined in javascript below.
JS: How to check if a variable is NOT undefined

Plotly.extendTraces only work with two traces but not with three

function getData() {
return Math.random();
};
function plotGraph(graph_div) {
let UPDATE_INTERVAL = 300;
Plotly.plot(graph_div, [{
y: [1, 2, 3].map(getData),
name: 'x',
mode: 'lines',
line: { color: '#80CAF6' }
}, {
y: [1, 2, 3].map(getData),
name: 'y',
mode: 'lines',
line: { color: '#DF56F1' }
}, {
y: [1, 2, 3].map(getData),
name: 'z',
mode: 'lines',
line: { color: '#4D92E9' }
}]);
var cnt = 0;
var interval = setInterval(function () {
var time = new Date();
Plotly.extendTraces(graph_div, {
y: [[getData()], [getData()], [getData()]]
}, [0, 1])
cnt = cnt+1;
if (cnt === 100) clearInterval(interval);
}, UPDATE_INTERVAL);
}
error:
plotly-latest.min.js:7 Uncaught Error: attribute y must be an array of length equal to indices array length
at plotly-latest.min.js:7
at R (plotly-latest.min.js:7)
at Object.t [as extendTraces] (plotly-latest.min.js:7)
at realtime_vis.js:40
point to
Plotly.extendTraces(graph_div, {
y: [[getData()], [getData()], [getData()]]
}, [0, 1])
Example from official documentation only shows how plot 2 lines, but that example not working with three lines.
Any help? I assume that I can explicitly specify the size of the array?!
The Plotly documentation isn't really clear here but the third parameter is an array of plot indexes you want to modify.
In your case you are telling Plotly to modify [0, 1] but you provide 3 new y-values. If you change it to [0, 1, 2] it should work, or you could provide only two new y-values.
function getData() {
return Math.random();
};
Plotly.plot(graph_div, [{
y: [1, 2, 3].map(getData),
name: 'x',
mode: 'lines',
line: { color: '#80CAF6' }
}, {
y: [1, 2, 3].map(getData),
name: 'y',
mode: 'lines',
line: { color: '#DF56F1' }
}, {
y: [1, 2, 3].map(getData),
name: 'z',
mode: 'lines',
line: { color: '#4D92E9' }
}]);
var cnt = 0;
var interval = setInterval(function () {
var time = new Date();
Plotly.extendTraces(graph_div, {
y: [[getData()], [getData()], [getData()]]
}, [0, 1, 2])
cnt = cnt+1;
if (cnt === 100) clearInterval(interval);
}, 300);
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="graph_div"></div>
</body>

How to show more than one "dataMax" in Highcharts?

Currently, I'm showing a max point in the line chart. But I want to change dataMax to top 5 max value points in chart.How can I achieve this in Highcharts?
var defaultData = 'urlto.csv';
var urlInput = document.getElementById('fetchURL');
var pollingCheckbox = document.getElementById('enablePolling');
var pollingInput = document.getElementById('pollingTime');
function createChart() {
Highcharts.chart('closed5', {
chart: {
type: 'area',
zoomType: 'x'
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
style: {},
formatter: function() {
if (this.y === this.series.dataMax) {
return this.y;
}
}
}
}
},
title: {
text: 'Chart for charting'
},
data: {
csvURL: urlInput.value,
enablePolling: pollingCheckbox.checked === true,
dataRefreshRate: parseInt(pollingInput.value, 10)
}
});
if (pollingInput.value < 1 || !pollingInput.value) {
pollingInput.value = 1;
}
}
urlInput.value = defaultData;
// We recreate instead of using chart update to make sure the loaded CSV
// and such is completely gone.
pollingCheckbox.onchange = urlInput.onchange = pollingInput.onchange = createChart;
// Create the chart
createChart();
As #ewolden rightly noticed, you can sort your data and show only the five highest values:
var data = [11, 22, 33, 44, 55, 66, 15, 25, 35, 45, 55, 65],
sortedData = data.slice().sort(function(a, b){
return b - a
});
Highcharts.chart('container', {
series: [{
data: data,
dataLabels: {
enabled: true,
formatter: function() {
if (sortedData.indexOf(this.y) < 5) {
return this.y;
}
}
}
}]
});
Live demo: http://jsfiddle.net/BlackLabel/xkf2w5tb/
API: https://api.highcharts.com/highmaps/series.mapbubble.dataLabels.formatter
As far as I know formatter callback is the way to format the data labels. If you want to show the top N points you should sort the data in a new array and pull the top 5 values. This is an example of how to clone and sort the array and extract the top 5 elements in the formatter call.
let data = [32, 10, 20, 99, 30, 54, 85, 56, 11, 26, 15, 45, 55, 65];
//Copy the array
let temp = data.slice();
// Sort the temp array in descending order
temp.sort((a, b) => b - a);
Highcharts.chart('closed5', {
chart: {
type: 'area',
zoomType: 'x'
},
title: {
text: 'Chart for charting'
},
series: [{
data: data,
dataLabels: {
enabled: true,
formatter: function() {
if (temp.indexOf(this.y) < 5) {
return this.y;
}
},
},
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="closed5"></div>

Spline Graph with diagonally fixed values with 0,0 and ploting remaing same

We are using Spline Graph for our game in which we are facing issue with x and y axis value which we need to put 0,0 and save the values from initially till end as we need to all plotting from start till end of the value.
Check Live Demo Here
JavaScript Code
<script>
var a = 1;
var b = 1;
var factor = 1.2;
$(document).ready(function () {
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
b = b*1.2;
console.log(b);
var x = a; // current time
var y = b;
a++;
series.addPoint([x, y], true, true);
}, 700);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'number',
min: 0,
tickInterval: 2
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>X: ' + this.x+', Y:'+this.y;
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],i;
for (i = 1; i <= 19; i++) {
b = b*factor;
data.push({
x: a,
y: b
});
a++;
}
return data;
}())
}]
});
});
The following code draws a curve line from the origin (0,0) to the end point which gets updated on the interval. You needed to make the shift variable false in the addPoint call. Higchart docs
$(document).ready(function () {
var a = 1;
var b = 1;
var factor = 1.2;
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
b = b*1.2;
var x = a; // current time
var y = b;
a++;
// Add new end point
series.addPoint([x, y], true, false);
}, 700);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'number',
min: 0,
tickInterval: 2
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>X: ' + this.x+', Y:'+this.y;
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
// Add point at origin and last point of series
var data = [{x:0,y:0}],i;
for (i = 1; i <= 19; i++) {
b = b*factor;
a++
data.push({
x: a,
y: b
});
}
return data;
}())
}]
});
});
Updated JsFiddle

Categories

Resources