onClick takes two clicks to populate results, HighCharts - javascript

My issue revolves around having to click a button twice to populate the results desired. I am using HighCharts to draw a chart, but the updateTime3Period() function must be called twice before the chart is properly displayed. Below I have included all my code, except for the updateTime6Period() function, since it is the same as updateTime3Period() in most ways. They both have the same issue. I would like to have the button be clicked once, and then populate the desired chart. I apologize for the lengthy post. Thank you in advance! Note: This does work if updateTime3Period() is clicked twice.
HTML:
<div id="timelinePeriods">
<ul class="timeSelection">
<li><a href="#" onclick="updateTime6Period();" > Past 6 Periods</a></li>
<li> Past 3 Periods</li>
</ul>
</div>
JS/AJAX for updateTime3Period:
function updateTime3Period() {
timeFrameUpdate = 'Past 3 Periods';
displayParam();
$.ajax({
url: 'PHP/getValues.php',
type: 'post',
data: {
type: "A",
type2: B,
type3: C,
type4: D,
type5: E,
type6: F,
type7: "getChartCurr"
},
success: function(response2) {
obj2 = JSON.parse(response2);
}
});
$.ajax({
url: 'PHP/getValues.php',
type: 'post',
data: {
type: "A",
type2: B,
type3: C,
type4: D,
type5: E,
type6: F,
type7: "getChartPrev"
},
success: function(response3) {
obj3 = JSON.parse(response3);
}
});
updateCharts(obj2, obj3, measureUpdate);
}
Functions that are called above (same file):
function displayParam() {
document.getElementById("params").innerHTML = timeFrameUpdate;
}
function updateCharts(data1, data2, measureData) {
} else if (timeFrameUpdate == 'Past 6 Periods') {
updateSixMonthPeriodChart(data1, data2, measureData);
} else if (timeFrameUpdate == 'Past 3 Periods') {
updateThreeMonthPeriodChart(data1, data2, measureData);
}
HighCharts Graph:
function updateThreeMonthPeriodChart(data1, data2, measureData) {
var measureValue = data1["graph"];
var measureValuePrev = data2["graphPrev"];
var changeValue = new Array();
for (i = 0; i < 3; i++) {
measureValue[i] = parseInt(measureValue[i]);
changeValue[i] = (parseInt(measureValue[i]) - parseInt(measureValuePrev[i])) / parseInt(measureValuePrev[i])
}
var chart1; // globally available
$(document).ready(function() {
chart1 = new Highcharts.Chart({
chart: {
renderTo: 'myChart',
},
title: {
text: 'Sales and Percent Change vs. Last Year - Past 3 Periods'
},
xAxis: {
categories: [1, 2, 3],
title: {
text: 'Period'
},
},
yAxis: [{
labels: { //Right y-axis
formatter: function() {
return Highcharts.numberFormat(this.value, 1, '.', ',') + '%';
}
},
title: {
text: '% Change'
},
opposite: true
},
{ //Left y-axis
labels: {
formatter: function() {
return '$' + Highcharts.numberFormat(this.value, 0, '', ',');
}
},
title: {
text: 'Sales ($)'
}
},
],
series: [{
name: 'Sales',
data: [measureValue[0], measureValue[1], measureValue[2]],
color: '#363534',
//Charcoal
yAxis: 1,
type: 'column'
},
{
name: '% Change',
data: [changeValue[0], changeValue[1], changeValue[2]],
color: '#E17000',
//Pumpkin
//yAxis: 2,
type: 'spline'
}]
});
});
}

It might be cause of your ajax request, it didn't complete at first click.in the next click it get the result from the catch and runs faster.
try this :
function updateTime3Period() {
timeFrameUpdate = 'Past 3 Periods';
displayParam();
$.ajax({
url : 'PHP/getValues.php',
type : 'post',
data : {
type : "A",
type2 : B,
type3 : C,
type4 : D,
type5 : E,
type6 : F,
type7 : "getChartCurr"
},
success : function (response2) {
obj2 = JSON.parse(response2);
$.ajax({
url : 'PHP/getValues.php',
type : 'post',
data : {
type : "A",
type2 : B,
type3 : C,
type4 : D,
type5 : E,
type6 : F,
type7 : "getChartPrev"
},
success : function (response3) {
obj3 = JSON.parse(response3);
updateCharts(obj2,obj3,measureUpdate);
}
});
}
});
}

Related

Highchart JS Set data not updating Export: ShowTable on Dropdown Event but chart updates fine

I have an .aspx file which has drop-down lists and on selected index changed a javascript function is being called to update the series data points on a highchart rather than rendering the entire chart again. I have created the below function but this doesnt seem to be updating the highchart table.It works when updating the chart.
Used this example to create the chart and table that synchronize together:
https://www.highcharts.com/blog/tutorials/synchronize-selection-bi-directionally-between-chart-and-table/
But when I click an item on the dropdown which refreshes the points using setData the table is not updating the values!!!
function salesPurchaseScatter() {
console.log("I am in the function");
var scatterData = [];
var xAxisLabels = [];
var scatterDatas;
$.ajax({
type: "POST",
async: false,
url: "Index.aspx/ReturnData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
scatterDatas = data.d;
}
});
const chart = window.chart;
console.log("CHart: ", chart);
chart.series[0].setData(scatterDatas.map(item => item["bucket5"]));
chart.series[1].setData(scatterDatas.map(item => item["bucket10"]));
chart.series[2].setData(scatterDatas.map(item => item["bucket15"]));
chart.series[3].setData(scatterDatas.map(item => item["bucket20"]));
chart.series[4].setData(scatterDatas.map(item => item["bucket25"]));
chart.series[5].setData(scatterDatas.map(item => item["bucket30"]));
chart.viewData();
}
The above is not updating the data points on the data table!
My original function to create the chart in the first place which works fine is below:
var scatterData = [];
var xAxisLabels = [];
var scatterDatas;
$.ajax({
type: "POST",
async: false,
url: "Index.aspx/ReturnData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
scatterDatas = data.d;
}
});
let chart = Highcharts.chart('container1', {
chart: {
type: 'scatter',
events: {
selection: selectPointsByDrag,
click: unselectByClick
},
// necesssary to be able to select by dragging
zoomType: 'xy'
},
title: {
text: '(' + minDWT + ' <DWT ' + ' < ' + maxDWT + ')',
style: {
fontWeight: 'bold',
fontSize: '20px'
}
},
plotOptions: {
scatter: {
lineWidth: 2,
dashStyle: 'dot'
},
series: {
connectNulls: true,
allowPointSelect: true,
pointPadding: 0,
point: {
events: {
select: function (e) {
selectTableCell(this, true);
},
unselect: function (e) {
selectTableCell(this, false);
}
}
},
marker: {
states: {
select: {
fillColor: 'tomato',
borderColor: 'green'
}
}
}
}
},
series: [{
name: 'bucket5',
data: scatterDatas.map(item => item["bucket5"]),
turboThreshold: 0,
id: 'Results1',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket10',
data: scatterDatas.map(item => item["bucket10"]),
turboThreshold: 0,
id: 'Results2',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket15',
data: scatterDatas.map(item => item["bucket15"]),
turboThreshold: 0,
id: 'Results3',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket20',
data: scatterDatas.map(item => item["bucket20"]),
turboThreshold: 0,
id: 'Results4',
marker: {
symbol: 'circle'
},
},
{
name: 'bucket25',
data: scatterDatas.map(item => item["bucket25"]),
turboThreshold: 0,
id: 'Results5',
marker: {
symbol: 'circle'
},
}, {
name: 'bucket30',
data: scatterDatas.map(item => item["bucket30"]),
turboThreshold: 0,
id: 'Results6',
marker: {
symbol: 'circle',
fillColor: 'red',
radius: 10
},
}],
xAxis: {
categories: scatterDatas.map(item => item["date"])
},
tooltip: {
formatter: function () {
var s = '<span style="color:' + this.point.color + '">\u25CF</span> ' + this.point.series.name + '<br /><b>Date: ' + this.x + '</b><br/><b>Sales Price: ' + this.y + '</b>';
return s;
}
},
exporting: {
showTable: true
},
});
UPDATE:
I have managed to get a step further. The chart is updating with the new data points but the table is not :
exporting: {
showTable: true
},
The fix i put in place:
const chart = window.chart;
console.log("CHart: ", chart);
for (i = 0; i < chart.series.length; i++) //Added this
chart.series[i].setData([]);
chart.series[0].setData(scatterDatas.map(item => item["bucket5"]));
chart.series[1].setData(scatterDatas.map(item => item["bucket10"]));
chart.series[2].setData(scatterDatas.map(item => item["bucket15"]));
chart.series[3].setData(scatterDatas.map(item => item["bucket20"]));
chart.series[4].setData(scatterDatas.map(item => item["bucket25"]));
chart.series[5].setData(scatterDatas.map(item => item["bucket30"]));
chart.viewData();
chart.redraw(); //Added this
Have i missed something out? Struggling to debug and identify what is going wrong
Found a JSFiddle which is similar to my current set up. http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/export-data/showtable/
The above JS Fiddle has a similar chart and table output. When i click on a drop down item I am trying to setData (the data point values) as per above code and this should update the chart and table. In my case it is only updating the chart and not the table. The function I am calling is salesPurchaseScatter on dropdown selected index changed event.
ATTEMPTED THIS:
const table = window.table;
table.series[0].setData(scatterDatas.map(item => item["saleagebucket5"]));
table.series[1].setData(scatterDatas.map(item => item["saleagebucket10"]));
table.series[2].setData(scatterDatas.map(item => item["saleagebucket15"]));
table.series[3].setData(scatterDatas.map(item => item["saleagebucket20"]));
table.series[4].setData(scatterDatas.map(item => item["saleagebucket25"]));
table.series[5].setData(scatterDatas.map(item => item["imo"]));
chart.redraw();
table.redraw();
but series is not possible using a table. How can i update the data using setData for the table? I tried using chart.viewData() but this doesnt seem to work either.
My guess is: const chart= window.chart; is only referring to the chart but dont know how to re-do the entire high chart canvas just the chart on it own!
A JSFiddle I tried to follow - https://jsfiddle.net/hxgp0yvj/
but same issue happening- Table not updating in this but chart does. I moved the code into my own solution to test it out. What am i missing?
Thank you for sharing it, after digging into I found out that it is a regression. I reported it on the Highcharts GitHub issue channel where you can follow this thread. If you don't need any new functionalities please use the previous version of the Highcharts until the bug will be fixed.
https://github.com/highcharts/highcharts/issues/14320

Bubble chart change X label values from a value in JSON response dynamically

I have a bubble chart using Chart.JS and getting my values dynamically from the database. The plotting of the data works absolutely fine, however I am trying to make a few formatting tweaks to the chart.
I want to change the X values to show the category (it is in my JSON output) on the horizontal axis rather than the i value. The JSON output contains category which is a string but I cant seem to do x: bubbleDatas[i].category?
The output currently shows on my x axis: 0,1,2,3,4,5 but i want it so show the value category from my JSON response which is in bubbleDatas?
data e.g.:
{
x: 0,
y: 60,
r: 10
}, {
x: 1,
y: 20,
r: 10
},
{
x: 2,
y: 40,
r: 10
}...
In my JSON response ajax request my X values i want it to be text:
e.g. 01_First, 02_Second
$(function () {
var bubbleData = [];
var xAxisLabels;
$.ajax({
type: "POST",
async: false,
url: "ExecView.aspx/ReturnData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
var bubbleDatas = data.d;
bubbleData = new Array(bubbleDatas.length);
console.log(bubbleDatas);
for (i = 0; i < bubbleDatas.length; i++) {
if (bubbleDatas[i].score >= 60) {
rgbcolour = "#008000";
}
else if (bubbleDatas[i].score >= 50 && bubbleDatas[i].score < 60) {
rgbcolour = "#FFA500";
}
else {
rgbcolour = "#FF6347";
}
bubbleData[i] = { **x: i,** y: bubbleDatas[i].score, r: bubbleDatas[i].radius, backgroundcolor: rgbcolour };
console.log(bubbleData[i]);
}
}
});
var popData = {
datasets: [{
label: "Test",
data: bubbleData
}]
};
var bubbleOptions = {
responsive: true,
legend: {
display: false
},
tooltips: {
callbacks: {
label: function (t, d) {
return d.datasets[t.datasetIndex].label +
': (Category:' + t.xLabel + ', Score:' + t.yLabel + ')';
}
}
},
scales: {
yAxes: [{
ticks: {
// Include a % sign in the ticks
callback: function (value, index, values) {
return value + '%';
}
}
}]
}
};
var ctx5 = document.getElementById("bubble_chart").getContext("2d");
new Chart(ctx5, { type: 'bubble', data: popData, options: bubbleOptions });
});
Changing category to more meaning might be your specific requirement, check this fiddle if it helps bubble chartJS fiddle and check this labelling in chartJS
P.S. check out your condition for x-axis in the callback and print accordingly

Data in highchart JSON format is correct

I have code like this
public static string summarydata(string RegNo)
{
try
{
TrackDataEntities1 sd = new TrackDataEntities1();
var mdata = new TrackDataEntities1().spsumdata(RegNo)
.Select(s => new { month = s.Month }).ToArray();
var sdata = new TrackDataEntities1().spsumdata(RegNo)
.Select(s => new { s.VName, s.total }).ToArray();
return Newtonsoft.Json.JsonConvert.SerializeObject(mdata) + "*" + Newtonsoft.Json.JsonConvert.SerializeObject(sdata);
}
catch (Exception)
{
throw new Exception();
}
}
now this return me data like this
"[{\"month\":\"July\"},{\"month\":\"June\"},{\"month\":\"June\"},
{\"month\":\"August\"},{\"month\":\"July\"},{\"month\":\"June\"},
{\"month\":\"May\"},{\"month\":\"June\"}]*[{\"VName\":\"DDSB\",\"total\":1},
{\"VName\":\"DPSB\",\"total\":1},{\"VName\":\"DSB\",\"total\":1},
{\"VName\":\"MV\",\"total\":5},{\"VName\":\"MV\",\"total\":11},
{\"VName\":\"MV\",\"total\":7},{\"VName\":\"MV\",\"total\":1},
{\"VName\":\"PSB\",\"total\":1}]"
jquery
UPDATED JQUERY
$(function () {
$('#tabledata').on('click', 'tr', function () {
var row = $(this);
var regno = row.find('td')[0].firstChild.data;
var obj = {};
obj.RegNo = regno;
Getsumdata(obj);
return false;
});
});
function Getsumdata(obj) {
$.ajax({
type: "POST",
url: "WebForm1.aspx/summarydata",
data: JSON.stringify(obj),
contentType: "application/json;charset=utf-8",
dataType: "json",
async: true,
cache: false,
success: function (result) {
alert(JSON.stringify(result.d));
var data1 = result.d.split('*')[0];
console.log(typeof (data1)); //Still a String...
var data11 = JSON.parse(data1);
console.log(data11); //
$('#sum').highcharts({
title: {
text: 'Combination chart'
},
xAxis: {
categories: data11,
title: {
text: null
}
},
labels: {
items: [{
html: 'Total fruit consumption',
style: {
left: '50px',
top: '18px',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
}]
},
// series:data2
series: [{
type: 'column',
name: 'Jane',
data: [3, 2, 1, 3, 4]
}, {
type: 'column',
name: 'John',
data: [2, 3, 5, 7, 6]
}, {
type: 'column',
name: 'Joe',
data: [4, 3, 3, 9, 0]
},
]
});
}
});
}
</script>
but chart look like this
Now the question is JSON look correct i think so why data is not populated in chart .. i use BAR highchart
any solution please?
data2 is still a string, you have to parse it.
Take a look at the Docs on how to add chart data, you have to transform your current data.
var a = "[{\"month\":\"July\"},{\"month\":\"June\"},{\"month\":\"June\"}, {\"month\":\"August\"},{\"month\":\"July\"},{\"month\":\"June\"}, {\"month\":\"May\"},{\"month\":\"June\"}]*[{\"VName\":\"DDSB\",\"total\":1}, {\"VName\":\"DPSB\",\"total\":1},{\"VName\":\"DSB\",\"total\":1}, {\"VName\":\"MV\",\"total\":5},{\"VName\":\"MV\",\"total\":11}, {\"VName\":\"MV\",\"total\":7},{\"VName\":\"MV\",\"total\":1}, {\"VName\":\"PSB\",\"total\":1}]";
var d = a.split('*')[1];
console.log(typeof(d)); //Still a String...
var e = JSON.parse(d);
console.log(e); //Yay an object.
It seems that you are not passing correct data to categories and series's.
Please transform your data in such a way that,
data1 represent categories, should look like this
["May","June","July","August"]
while your data2 represent the series data which you want to plot for a given month, should look like below.
[1,10,12,5]

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.

highcharts dynamically adding series with addSeries

I'm working on creating a dynamically created chart that will add a series if there isn't one and if there is one add a point. I'm getting an Uncaught TypeError: Cannot call method 'addSeries' of undefined. I've looked around and I can't find why it says that method is undefined.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript" src="highcharts.js"></script>
$(document).ready(function () {
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column',
events: {
load: requestData
}
},
title: {
text: 'Survey Chart'
},
xAxis: {
categories: [],
title: {
text: 'Question Number'
}
},
yAxis: {
title: {
text: 'Total Answered'
}
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true
},
series: []
});
with the document ready function taking up the entire script i have the following functions
function requestData() {
ajaxCall(chartCreate, createSeries, "services/Survey.svc/DoWork", "{}");
chart1.redraw();
};
function chartCreate(point) {
var temp;
temp = $.parseJSON(point.d);
$.each(temp, function (key, p) {
var seriesObj;
seriesObj = seriesExists(p.mcAnswer);
if (seriesObj.status == false) {
chart1.addSeries({name: '' + p.mcAnswer + '', data: [] });
chart1.series[seriesObj.count].addPoint(p.total, false);
} else {
chart1.series[seriesObj.count].addPoint(p.total, false);
}
});
};
//loops through all the series to see if the series exists.
//if true returns index and true if not just returns false
function seriesExists(name) {
var ct = 0;
//var len = chart1.series.length;
var len = 0;
if (len > 0) {
$.each(chart1.series, function (count, curSeries) {
if (curSeries.name == name) {
return { 'count': count, 'status': true };
}
ct = count;
});
}
return { 'count': ct, 'status': false };
}; function createSeries() {
alert("error");
};
//$.ajaxCall({successFun: function, errorFun: function, source: "", data: {}});
function ajaxCall(myFunSuccess, myFunError, url, data) {
//chart1 = chartTemp;
$.ajax({
type: "POST",
async: false,
url: url,
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: myFunSuccess,
error: myFunError
});
//return chart1;
};
I'm able to use the ajax function call fine it's when I get to my chartCreate where I run into the problem.
The problem is that you're trying to add the serie before chart1 get your chart reference. That's why chart1 doens't have addSeries method.
You can see this issue here.
To fix it you can set manually the chart reference to chart1 before call requestData.
Like the following.
load: function() {
chart1 = this; // `this` is the reference to the chart
requestData();
}

Categories

Resources