Change Highcharts Graph based on two Select inputs - javascript

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/

Related

Javascript variable not working inside of highcharts

I am trying to show high charts pie chart dynamically, i pass exact value format into data index in high chart but it doesn't show anything in chart, if i give what a variable have a value directly it's working fine, but passing variable directly it show empty pie chart,
Here is my javascript code,
function get_product_chart_by_filter()
{
var product_year_raw = $('#top_least_pro_year_filt').val();
var pro_top_least = $('#top_least_pro_filt').val();
var next_year = '';
var product_year = '';
var pro_top_res = '';
if (product_year_raw.length == 4) {
next_year = parseInt(product_year_raw) + 1;
product_year = product_year_raw+'-'+next_year;
}
else {
product_year = product_year_raw;
}
if (pro_top_least == 1) {
$('#pro_top_or_least').empty().html('Top ');
}
else {
$('#pro_top_or_least').empty().html('Least ');
}
$.ajax({
type:"POST",
url:baseurl+'Dashboard/product_dashboard_dynamic',
data:{'year':product_year,'top_or_least':pro_top_least},
cache: false,
dataType: "html",
success: function(result){
pro_top_res = JSON.parse(result);
var data_series = '';
for (var i = pro_top_res.length - 1; i >= 0; i--) {
data_series += "['"+pro_top_res[i].product_name+"',"+Number(pro_top_res[i].product_order_count)+"],";
}
data_series = data_series.replace(/,\s*$/, "");
// Output of 'data_series' variable = ['Basmathi',6],['null',6],['Basmathi',6],['Basmathi',20],['Basmathi',21]
Highcharts.chart('top_5_products_container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: 0,
plotShadow: false
},
credits:false,
title: {
text: 'Products',
align: 'center',
verticalAlign: 'middle',
y: 60
},
tooltip: {
pointFormat: '{series.name}: <b>{point:y}</b>'
},
accessibility: {
point: {
valueSuffix: '%'
}
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
distance: -50,
style: {
fontWeight: 'bold',
color: 'white'
}
},
startAngle: -90,
endAngle: 90,
center: ['50%', '75%'],
size: '110%'
}
},
series: [{
type: 'pie',
name: 'Product',
innerSize: '50%',
data: [data_series]
}]
});
}
});
}
Here is my server side code,
public function product_dashboard_dynamic()
{
$dashboard_settings_info = get_dashboard_settings_info();
$top_or_least = $this->input->post('top_or_least');
$raw_yr = $this->input->post('year');
$exp_yr = explode('-', $raw_yr);
$yr1 = $exp_yr[0];
$yr2 = $exp_yr[1];
$top_least_count = $dashboard_settings_info->max_product_count;
$get_top_least_product = $this->Dashboard_model->get_top_least_product($top_or_least,$yr1,$yr2,$top_least_count);
echo json_encode($get_top_least_product);
}
Anyone can assist me?
My thought is that it has something to do with the use of a concatenated string rather than an array so you could perhaps try... though I have not used highcharts before
Change
var data_series = '';
for (var i = pro_top_res.length - 1; i >= 0; i--) {
data_series += "['"+pro_top_res[i].product_name+"',"+Number(pro_top_res[i].product_order_count)+"],";
}
to:
var data_series = [];
for( var i = pro_top_res.length - 1; i >= 0; i-- ) {
var obj=pro_top_res[i];
data_series.push( [ obj.product_name, parseInt( obj.product_order_count ) ] );
}
remove
data_series = data_series.replace(/,\s*$/, "");
Finally modify the configuration to accomodate new input data as an array
'series': [{
'type': 'pie',
'name': 'Product',
'innerSize': '50%',
'data':data_series
}]

How to add data tables to dynamically generated highcharts

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
},
},
...

incorrect callback function string

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.

highcharts-ng ajax data load

I have the following HTTP request that i use to fill out my chart:
$scope.series = ['Moduler tager', 'Gns.score'];
$scope.activity_data = [];
$scope.activity_ticks = [];
var tmp_data = [];
$scope.bar = [];
$scope.line = [];
$http.get(api.getUrl('findSelfActivityByDivisions', null))
.success(function (response) {
response.forEach(function(y){
var i = 0;
var log_date = y.date.substr(0, y.date.indexOf('T'));
var date = new Date(log_date);
var logg_date = moment(date).fromNow();
var indexOf = tmp_data.indexOf(logg_date);
var found = false;
var index = 0;
if(tmp_data.length > 0){
tmp_data.forEach(function(current_data){
if(current_data[0] == logg_date){
found = true;
}
if(!found){
index++;
}
})
}
if(found){
var tmp = tmp_data[index];
tmp[1] = tmp[1] + y.num_modules;
tmp[2] = tmp[2] + y.num_score_modules;
tmp[3] = tmp[3] + y.sum_score;
tmp_data[index] = tmp;
}
else
{
var tmp = [logg_date, y.num_modules, y.num_score_modules, y.sum_score];
tmp_data.push(tmp);
}
})
var line = [];
var bar = [];
tmp_data.forEach(function(data){
$scope.activity_ticks.push(data[0])
line.push(data[1]);
var avg_score = data[3] / data[2];
if(isNaN(avg_score)){
avg_score = 0;
}
bar.push(avg_score);
});
$scope.line = line;
$scope.bar = bar;
});
Now then i have the following chart config:
$scope.chartConfig = {
options: {
chart: {
type: 'areaspline'
}
},
series: [{
data: $scope.bar,
type: 'column'
},{
data: $scope.line,
type: 'line'
}],
xAxis: {
categories: $scope.activity_ticks
},
title: {
text: 'Hello'
},
loading: false
}
Sadly none of the graphs are showing (im guessing it has something to do with the date comming after the load)
Can anyone help me out?
Your $scope.chartConfig is likely firing before the success callback of your $http.get(api.getUrl('findSelfActivityByDivisions', null)) completes. I am assuming $scope.chartConfig is located in a controller. Try placing a $watchGroup on the values then apply your chart rendering logic once those values resolve. An example may include
Note that $watchGroup is found within Angular as of 1.3
$scope.$watchGroup(['line', 'bar'], function(newValues, oldValues) {
// newValues[0] --> $scope.line
// newValues[1] --> $scope.bar
if(newValues !== oldValues) {
$scope.chartConfig = {
options: {
chart: {
type: 'areaspline'
}
},
series: [{
data: $scope.bar,
type: 'column'
},{
data: $scope.line,
type: 'line'
}],
xAxis: {
categories: $scope.activity_ticks
},
title: {
text: 'Hello'
},
loading: false
}
}
});

data in javascript to redraw graph logic required

am trying to show data on highcharts that is comming from datatabase in code behind.
so far this is my code in javascript where the chart is drawn, testarray1,2, represents the data
function draw(d) {
var testarray = JSON.parse(a);
var testarray1 = JSON.parse(a1);
var testarray2 = JSON.parse(a2);
$(function() {
$('#container1').highcharts({
chart: {
type: 'column'
},
credits: {
enabled: false
},
title: {
text: 'Consumption by months'
},
xAxis: {
categories: array3
},
yAxis: {
title: {
text: 'kWh'
}
},
tooltip: {
valueDecimals: 2
},
plotOptions: {
type: 'column'
},
series: [{
name: '2011-2012',
type: 'column',
color: '#0000FF',
data: testarray
},
{
name: '2012-2013',
type: 'column',
color: '#92D050',
data: testarray1
}]
});
});
}
my output just shows the same data. what i need is some logic in the function draw do it refreshes when it draws, i have something like this.
var a = testarray
var b = testarray1
if (d == 1)
{
var c = a
}
else if (d == 2)
{
var c = b
}
else if (d == 1)
{
var d = a
}
else if (d == 1)
{
var d = b
}
with this i call c and d in the data. but i need a logic for 3 types of data, testarray, testarray1 and testarray2.
any ideas.

Categories

Resources