I have an array of data of the following format:
[["sno","day","status","data1","data2","data3","data4"],
["1","01-12-2020","success","23","66","53","34"],
["2","02-12-2020","success","12","9","8","6"],
["3","03-12-2020","success","10","11","16","13"],
["4","04-12-2020","success","34","43","54","34"],
["5","01-12-2020","fail","45","26","36","44"],
["6","02-12-2020","fail","12","15","11","13"],
["7","03-12-2020","fail","34","43","33","29"],
["8","04-12-2020","fail","23","34","31","23"]
]
to display the particular text in Highcharts I used the Following code:
var weekData = [["sno","day","status","data1","data2","data3","data4"],["1","01-12-2020","success","23","66","53","34"],["2","02-12-2020","success","12","9","8","6"],["3","03-12-2020","success","10","11","16","13"],["4","04-12-2020","success","34","43","54","34"],["5","01-12-2020","fail","45","26","36","44"],["6","02-12-2020","fail","12","15","11","13"],["7","03-12-2020","fail","34","43","33","29"],["8","04-12-2020","fail","23","34","31","23"]] ;
//console.log(weekData);
function change()
{
var valStatus = document.getElementById("statusSelect");
status = valStatus.value;
//console.log(status);
if(status == 'success')
{
const successValues = weekData.filter((x)=>x[2] === "success"); //New Cases
console.log(successValues);
return successValues;
}
else if(status == 'fail')
{
const failValues = weekData.filter((x)=>x[2] === "fail"); //New Cases
console.log(failValues)
return failValues;
}
}
function getCol(matrix, col){
var column = [];
for(var i=0; i<matrix.length; i++){
column.push(matrix[i][col]);
}
return column;
}
function chartCreate()
{
change();
const toNumbers = arr => arr.map(Number);
var getstat= change();
var day = getCol(getstat,1);
console.log(day);
var sdata1 = toNumbers(getCol(getstat,3));
console.log("data 1" ,sdata1);
var sdata2 = toNumbers(getCol(getstat,4));
console.log(sdata2);
var sdata3 = toNumbers(getCol(getstat,5));
console.log(sdata3);
var sdata4 = toNumbers(getCol(getstat,6));
console.log(sdata4);
For the full program You can check my fiddle : https://jsfiddle.net/abnitchauhan/L27n0wfs/
the problem is that when I am status select box, The Chart is not updating.
Also I feel that this code is quite lengthy when the datasets will increase overtime. is there any efficient approach to display this data on Highchart's based on the same select options.
I made an update to JS code. See if this is what you want:
var weekData = [["sno","day","status","data1","data2","data3","data4"],["1","01-12-2020","success","23","66","53","34"],["2","02-12-2020","success","12","9","8","6"],["3","03-12-2020","success","10","11","16","13"],["4","04-12-2020","success","34","43","54","34"],["5","01-12-2020","fail","45","26","36","44"],["6","02-12-2020","fail","12","15","11","13"],["7","03-12-2020","fail","34","43","33","29"],["8","04-12-2020","fail","23","34","31","23"]] ;
//console.log(weekData);
function change()
{
var valStatus = document.getElementById("statusSelect");
status = valStatus.value;
//console.log(status);
if(status == 'success')
{
const successValues = weekData.filter((x)=>x[2] === "success"); //New Cases
console.log(successValues);
return chartCreate(successValues);
}
else if(status == 'fail')
{
const failValues = weekData.filter((x)=>x[2] === "fail"); //New Cases
console.log(failValues)
return chartCreate(failValues);
}
}
function getCol(matrix, col){
var column = [];
for(var i=0; i<matrix.length; i++){
column.push(matrix[i][col]);
}
return column;
}
function chartCreate(stat)
{
const toNumbers = arr => arr.map(Number);
var getstat= stat;
var day = getCol(getstat,1);
console.log(day);
var sdata1 = toNumbers(getCol(getstat,3));
console.log("data 1" ,sdata1);
var sdata2 = toNumbers(getCol(getstat,4));
console.log(sdata2);
var sdata3 = toNumbers(getCol(getstat,5));
console.log(sdata3);
var sdata4 = toNumbers(getCol(getstat,6));
console.log(sdata4);
var options = {
chart:{
renderTo: 'chart',
defaultSeriesType: 'line'
},
title: {
text: 'dummy'
},
subtitle: {
text: ' '
},
yAxis: {
title: {
text: ' ',
//tickPointInterval: 250
},
minorTickInterval: 'auto',
// tickInterval: 4,
},
xAxis: {
labels :{
minorTickInterval: 'auto',
formatter: function(){
return day[this.value];
}
},
tickInterval: 10
},
credits: {
enabled: false
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
// pointStart: 0
}
},
tooltip: {
// split: true,
formatter: function() {
var points = this.points,
tooltipArray = ['day: <b>' + day[this.x] + '</b><br/> Value : <b>'+ this.y +'</b>']
return tooltipArray;
}
},
series: [
{
name: 'Check',
data: sdata1
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
};
var chart = new Highcharts.Chart(options);
$("#dataSelect").on('change', function(){
//alert('f')
var selVal = $("#dataSelect").val();
if(selVal == 'data1' || selVal == '')
{
options.series = [{name: 'Data', data: sdata1}];
options.yAxis = [{tickInterval:undefined, minorTickInterval: 'auto'}];
}
else if(selVal == 'data2')
{
options.series = [{name: 'Data', data: sdata2}]
}
else if(selVal == 'data3')
{
options.series = [{name: 'Data', data: sdata3}];
options.yAxis = [{tickInterval:undefined, minorTickInterval: 'auto'}];
}
else if(selVal == 'data4')
{
options.series = [{name: 'Data', data: sdata4}];
options.yAxis = [{tickInterval:undefined, minorTickInterval: 'auto'}];
}
var chart = new Highcharts.Chart(options);
});
}
change();
Your code looks very complex and does not fully work. In this case, I will suggest using the series setData method mixed with the change event listener. My example is a bit simplified, but I think it might be the right way.
document.getElementById('dataSelect').addEventListener('change', () => {
const selectorValue = document.getElementById('dataSelect').value
chart.series[0].setData(data[selectorValue])
});
API: https://api.highcharts.com/class-reference/Highcharts.Series#setData
Demo: https://jsfiddle.net/BlackLabel/nfz0a9bm/
I want to add data tables to Charts.
I tried the implementation shown here: http://jsfiddle.net/highcharts/z9zXM/
but it didnt work for me.
I suspect its because how I instantiate highcharts.
in the example above the chart is generated by instantiating the Highcharts object.
my code:
// data from an ajax call
$.each(data, function(indicator, questions) {
indicator_type = "";
$.each(questions, function(question, value) {
dataChartType = "column";
series = [];
categories = [];
category_totals = {};
if(value.programs == null) {
return true;
}
$.each(value.programs, function(program, body) {
total = 0;
values = [];
$.each(body, function(j, k) {
if (categories.indexOf(j) == -1) {
categories.push(j);
category_totals[j] = 0;
}
if(k != 0) {
values.push(k);
} else {
values.push(null);
}
category_totals[j] += parseInt(k, 10);
total += k;
});
series.push({
data: values,
total: total,
name: program //question
});
}); // eo each program
var chartDiv = document.createElement('div');
chartDiv.className = "chart";
$('.charts_wrap').append(chartDiv);
$(chartDiv).highcharts({
events: {
load: Highcharts.drawTable
},
chart: {
type: dataChartType
},
xAxis: {
categories: categories
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'right',
verticalAlign: 'top',
y: 60,
x: -60
},
tooltip: {
formatter: function () {
return '<strong>' + this.series.name + '</strong><br/>' + this.x + ': ' + this.y;
}
},
plotOptions: {
line: {
connectNulls: true
},
column: {
stacking: 'normal',
dataLabels: {
enabled: false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px w'
}
}
}
},
series: series,
title:{ text: indicator },
subtitle:{ text: question }
});
}); // EO each question
}); // eo each indicator
When instantiating highcharts like this:
$("#container").highcharts({ ...
The events option needs to be included inside the charts option:
$("#container").highcharts({
chart: {
type: 'column',
events: {
load: Highcharts.drawTable
},
},
...
I am using this code belong to plot currency change values but there is a problem while plotting chart.
$(document).ready(function () {
localhost1 = {}; //our global namespace variable
localhost1.chg_percent = [];
localhost1.currency =[];
localhost1.chart1 = {yAxisMin : null, yAxisMax : null }; //this object holds things belonging to this chart1
var url1 = 'http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json&view=basic';
$.ajax({
url: url1,
cache: false,
dataType: 'jsonp',
context: localhost1,
success: function(data) {
for(var i=0; i<data.list.resources.length; i++) {
this.currencyObj = data.list.resources[i].fields;
this.chg_percent.push(parseFloat(data.list.resources[i].resource.fields.chg_percent));
this.currency.push(data.list.resources[i].resource.fields.name);
}
this.chart1.yAxisMax = (function(array){
var number_array = [];
for(var i=0; i<array; i++){
if(array[i] != null){
number_array.push(array[i]);
}
}
return math.max.apply(Math, number_array);
})(this.chg_percent);
this.chart1.yAxisMin = (function(array){
var number_array = [];
for(var i=0; i<array; i++){
if(array[i] != null){
number_array.push(array[i]);
}
}
return math.min.apply(Math, number_array);
})(this.chg_percent);
this.chart1.data.series[0].data = this.chg_percent;
this.chart1.data.xAxis.categories = this.currency;
chart = new Highcharts.Chart(this.chart1.data);
console.log(data);
}
});
localhost1.chart1.data = {
chart: {
renderTo: 'container',
type: 'bar'
},
title: {
text: 'Historic World Population by Region'
},
subtitle: {
text: 'Source: Source : yahoo'
},
xAxis: {
categories: null,
title: {
text: null
}
},
yAxis: {
min: localhost1.chart1.yAxisMin,
max: localhost1.chart1.yAxisMax,
title: {
text: 'Daily Percentage Change',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
formatter: function(){
return ''+
this.series.name +': '+ this.y +' %';
}
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -1,
y: 1,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: 'Daily Change',
data: null
}]
};
});
when i run this code, i get an error message in console "Not acceptable : http://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json&view=basic&callback=jQuery18203581249208157574_1452451202663&_=1452451202773".
though the api i have used is correct but the string that callback function returns seems to be incorrect.
Not sure why because I have done it in the past, but I have a Highcharts bar chart and it won't animate. This is the declaration of the chart,
function initializeData() {
$http.get(url).success(function(ret) {
$scope.jsondata = ret;
var newdata = [];
for (x = 0; x < 5; x++) {
newdata.push({
name: setName($scope.jsondata[x].name),
y: $scope.jsondata[x].data[0],
color: getColor($scope.jsondata[x].data[0])
});
}
$scope.chart.series[0].setData(newdata);
});
mainInterval = $interval(updateData, 5000);
}
function updateData() {
$http.get(url).success(function(ret) {
$scope.jsondata = ret;
console.debug("here");
for (x = 0; x < 5; x++) {
$scope.chart.series[0].data[x].update({
y: $scope.jsondata[x].data[0],
color: getColor($scope.jsondata[x].data[0])
});
}
});
}
$scope.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar',
animation: true,
events: {
load: initializeData
}
},
title: {
text: ''
},
xAxis: {
type: 'category',
labels: {
style: {
fontSize: '11px'
}
}
},
yAxis: {
min: 0,
max: 100,
title: {
text: 'Total Score',
align: 'high'
}
},
legend: {
enabled: false
},
tooltip: {
pointFormat: 'Total Score <b>{point.y:.3f}</b>'
},
series: [{
name: 'Active Users',
data: [],
dataLabels: {
enabled: true,
rotation: 30,
style: {
fontSize: '10px',
fontFamily: 'Verdana, sans-serif'
},
format: '{point.y:.3f}', // one decimal
}
}]
});
And as you can see I have animate : true, so I am not sure what is the problem here. I have this older plunker where all of the data is in separate series, but it animates fine. But this is the plunker I am working on and having trouble with. They are like identical basically. In the newer one I broke out the initialization of data into its own method, but that is the only real main difference.
Some edits:
So as I was saying, I have done things this way with an areaspline chart (I know it was said they work a bit different but they are set up identically).
function initializeData() {
$interval.cancel(mainInterval);
$scope.previousPackets = '';
$http.get("https://api.myjson.com/bins/nodx").success(function(returnedData) {
var newdata = [];
var x = (new Date()).getTime();
for (var step = 9; step >= 0; step--) {
newdata.push([x - 1000 * step, 0]);
}
$scope.chart.series[0].setData(newdata);
});
mainInterval = $interval(updateData, 2000);
}
function updateData() {
$http.get(url + acronym + '/latest').success(function(returnedData) {
var x = (new Date()).getTime();
if ($scope.previousPackets != returnedData[0].numPackets) {
$scope.chart.series[0].addPoint([x, returnedData[0].numPackets], true, true);
$scope.previousPackets = returnedData[0].numPackets;
} else {
$scope.chart.series[0].addPoint([x, 0], true, true);
}
});
}
$scope.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'areaspline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: initializeData
}
},
title: {
text: ''
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Packets'
},
plotLines: [{
value: 0,
width: 1,
color: '#d9534f'
}]
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.y) + ' packets<b> | </b>' + Highcharts.dateFormat('%H:%M:%S', this.x);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Packets',
data: []
}]
});
I also updated the first chunk of code with the initializeData() method and updateData() method which are seemingly identical in both different charts.
It looks like it plays an important role if you provide your data at chart initialization or after. For simplicity I refactored your code a little
function initializeChart(initialData, onload) {
$scope.chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar',
animation: true,
events: {
load: onload
}
....
series: [{
name: 'Active Users',
data: initialData,
dataLabels: {
enabled: true,
format: '{point.y:.3f}', // one decimal
}
}]
});
}
function getData(callback) {
$http.get(url).success(function(ret) {
$scope.jsondata = ret;
var newdata = [];
for (x = 0; x < 5; x++) {
newdata.push([setName(ret[x].name), ret[x].data]);
}
callback(newdata);
});
}
As a result your two planks are in essense reduced to two methods below. The first initializes chart with preloaded data and the second updates data in existing chart.
function readDataFirst() {
getData(function(newdata) {
initializeChart(newdata);
});
}
function initializeChartFirst() {
initializeChart([], function() {
getData(function(newdata) {
$scope.chart.series[0].setData(newdata);
})
});
}
The first one animates fine while the second does not. It looks like highcharts skips animation if dataset is not initial and is treated incompatible.
However if you really want to have animation in your current plant (chart first workflow) you can achieve that by initializing first serie with zeros and then with the real data. This case it will be treated as update
function forceAnimationByDoubleInitialization() {
getData(function(newdata) {
initializeChart([]);
var zerodata = newdata.map(function(item) {
return [item[0], 0]
});
$scope.chart.series[0].setData(zerodata);
$scope.chart.series[0].setData(newdata);
});
All these options are available at http://plnkr.co/edit/pZhBJoV7PmjDNRNOj2Uc
I have started working with highcharts.js, but fails to add new points my bar graph:
Every time it goes into addPoint, Firefox freezes :(
I am using Firebug, and when it tries to addPoint, it always freeze :(
// if no graph
if (! charts[0])
{
// make chart table
var round_ids = [];
var total_players = [];
var total_bets = [];
$.each(last_rounds_cache.last_rounds_data, function(index, value)
{
round_ids.push(Number(value[0]));
total_players.push(Number(value[2]));
total_bets.push(Number(value[3]));
}
)
charts[0] = new Highcharts.Chart({
chart: {
renderTo: 'players_per_round',
type: 'column',
events: {
click: function(e) {
// find the clicked values and the series
var x = e.xAxis[0].value,
y = e.yAxis[0].value,
series = this.series[0];
// Add it
series.addPoint([x, y]);
}
}
},
title: {
text: 'Players/Bets per Round'
},
xAxis: {
categories: round_ids,
},
yAxis: {
min: 0,
title: {
text: 'Rainfall (mm)'
}
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'left',
verticalAlign: 'top',
x: 10,
y: 10,
floating: false,
shadow: true
},
tooltip: {
formatter: function() {
return ''+
this.x +': '+ this.y;
}
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: 'Players',
data: total_players
}, {
name: 'Bets',
data: total_bets
}]
});
}
else
{
if (newChartsPoints.length > 0)
{
$.each(newChartsPoints, function(index, value)
{
// retreive data
var temp_round_id = value[0];
var temp_total_players = value[1][0];
var temp_total_bets = value[1][1];
// add points
var series = charts[0].series;
series[0].addPoint([temp_round_id, temp_total_players], false);
series[1].addPoint([temp_round_id, temp_total_bets], false);
// add categories
categories = charts[0].xAxis[0].categories;
categories.push(temp_round_id);
charts[0].xAxis[0].setCategories(categories, false);
charts[0].redraw();
});
}
}