Distinguish between text and checkbox in jquery selector - javascript

I want to convert my table to html. I am trying to derive the data from the input text fields and not from the input checkbox fields
The following is my javascript code as can be seen in the fiddle:
$(document).ready(function(){
$('#hello').click(function(e) {
var array = [];
var headers = [];
$('#my_table tr:first-child td').each(function(index, item) {
headers[index] = $('> input[type="text"]', item).val();
});
$.each(headers, function(index, item) {
var name=item;
var data =[];
$('#my_table tr:first-child').nextAll().each(function() {
$('td:nth-child('+(index+1)+')', $(this)).each(function(index, item) {
data.push(parseInt($('> input[type="text"]', item).val()));
});
});
array.push({name: name, data:data});
});
var categories=array[0].data;
alert(categories);
array.shift();
var chart= new Highcharts.Chart({ chart: {
renderTo: 'container'
},
title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: array
});
});
});
My code is supposed to take the first column as the xaxis. For this it is supposed to skip the checkbox column. However, the jquery selector does not appear to distinguish between both types of inputs and skip the column type. What am I supposed to do differently to achieve what I intend?

There are two main causes for this:
In the loop where you build the header you don't filter out the first column. True, the input[type="text"] selector will not give a result for the first column, but it still generates an entry in the headers array. Instead, move that input selector into the main selector so that you don't even visit the first column
In the loop where you build the array variable, you access the td by the selector td:nth-child('+(index+1)+')', but since the index values start at 0, you'll be accessing child number 1, which still is the first column. So you need to write index+2 in there.
With some other improvements (the use of map is useful for generating arrays), the following code could be used:
var headers = $('#my_table tr:first-child input[type="text"]').map(function() {
return $(this).val();
}).get();
var array = $.map(headers, function(item, index) {
var name = item;
var data = $('#my_table tr td:nth-child('+(index+2)+') input[type="text"]')
// slice(1) will skip the first row (alternative to your method)
.slice(1).map(function() {
return +($(this).val()); // unitary + will do number conversion
}).get();
return {name: name, data: data};
});
var categories = array.shift().data;
var chart= new Highcharts.Chart({ chart: {
// ... etc.
After entering some input in this updated jsfiddle, I got this result:

Related

Chart update everytime on Loading second array : Highcharts, Javascript

So, What I have is a condition in a MySQL to show the first 1000 data points first and then the other 2000 datapoints after that in Highcharts.
if lastindex==0:
cur.execute("SELECT data,value FROM table where id<1001")
else:
cur.execute("SELECT data,value FROM table where id>1001 and id<3000")
data = cur.fetchall()
//python Code to fetch SQL data
Now what I am doing is that I am rendering that data into the Highcharts, the data is being rendered. but the problem arises that after showing the first 1000 data points, the Highcharts value starts from 0 and then shows the other 2000 points
the data is not displaying continuously as it should plot the send array data just after the end of the first data.
I think the Highcharts is being called Twice, What can I do to append the 2nd set of data to the first set without reloading the whole chart.
Here's a snip of my Highchart's js
Highcharts.chart("chartcontainer", {
chart: {
type: 'line',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function() {
var series = this.series[0],
chart = this;
setInterval(function() {
//some logic regarding the chart
//..
v = {
y: y,
x: x
};
console.log("V value", v);
series.addSeries(v, false, true);
counter++;
localcounter++;
} else
{
oldcounter=counter;
flagToreload=1;
}
}, 1000/130);
setInterval(function() {
chart.redraw(false);
}, 100);
}
}
},
time: {
useUTC: false
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'Value',
gridLineWidth: 1
},
yAxis: {
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}],
gridLineWidth: 1
},
tooltip: {
headerFormat: '<b>{series.name}</b><br/>',
pointFormat: '{point.x:%Y-%m-%d %H:%M:%S}<br/>{point.y:.2f}'
},
exporting: {
enabled: false
},
series: [{
animation: false,
name: 'Random data',
data: (function() {
// generate an array of random data
var data = [],
time = counter,
i;
for (i = -1000; i <= 0; i += 1) {
data.push([
counter,
null
]);
}
return data;
}())
}]
});
What I want is just to append the event data rather than loading the whole chart.
How can I reload a particular Highchart value without reloading the whole chart ?
What do you think about updating the current series with new data, which will be an array of old data merged with the new one?
chart: {
events: {
load(){
let chart = this,
currentSeries = chart.series[0],
newData;
newData = [...currentSeries.userOptions.data, ...data1]
setTimeout(()=> {
chart.series[0].update({
data: newData
})
}, 5000)
}
}
},
See the demo

Highchart xAxis labels formatter for multiple series values from multi-dim array

My Requirement
I want to label the X-Axis of multi-series graph from multi-dim array.
HighChart script
var chart_PT1 = new Highcharts.Chart({
chart: {
height: 532,
renderTo: 'review_high_container'
},
title: {
text: 'IO Signal Data'
},
subtitle: {
text: 'Source: GPS Modem'
},
yAxis: {
title: {
text: 'Value'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
xAxis: {
type: 'datetime',
labels: {
enabled: true,
formatter: function () { try { return ddd[i][this.value][0]; } catch (err) { } },
}
},
});
for (i = 0; i < ddd.length; i++) {
chart_PT1.addSeries({ name: name[i], data: ddd[i], turboThreshold: 5000 });
}
My data array
Its an multi dim array signals=[] say 3 as shown below
signals[0] = {"Signal1",signalData[]} <=== signalData has say 20 data
signals[1] = {"Signal2",signalData[]} <=== signalData has say 10 data
signals[2] = {"Signal3",signalData[]} <=== signalData has say 80 data
signalData[] is expected to have the data for the signal say
signalData[0] ==> Value, TimeReceived,ID
signalData[1] ==> Value, TimeReceived,ID
signalData[2] ==> Value, TimeReceived,ID
.
.
.
signalData[20] ==> Value, TimeReceived,ID
Likewise signals[1].signalData[] and signals[2].signalData[] is expected to have data for its corresponding signals.
Each data in signalData includes data for value,TimeReceived and ID. So signals[0].signalData will contain array of data for signalOne; signals[1].signalData will contain array of data for signalTwo;
signals[2].signalData will contain array of data for signalThree;
and so on...
The graph would show one line for each signal(in this case 3 lines)
My Problem
I not able to label the X-Axis with the Time Value available inside the array - signals.signalData. Each signal may or may not have the same time within the array signals. So labelling by signals.signalData[0] do not pose right for other series signals.signalData[1],signals.signalData[2]....
How do I label X-Axis for the multi series?
Whats the best option to do this? as I see the time value inside the array say signals.signalData[0] may not be aligned with the the time value inside signals.signalData[1]
Update
Sample Data
signals ={
{ "SignalOne", {{"42","2/20/2018 05:25:09","S11"},{"99","2/20/2018 06:17:13","S12"},{"89","2/20/2018 07:25:09","S13"} },
{ "SignalTwo", {{"118","2/20/2018 05:25:09","S21"},{"33","2/20/2018 06:17:13","S22"} }
{ "SignalThree", {{"333","2/20/2018 05:25:09","S31"},{"43","2/20/2018 06:17:13","S32"},{"43","2/20/2018 06:17:13","S33"},{"43","2/20/2018 06:17:13","S34"} }
};

Dynamically set highcharts endrow option based on user input

I would like to dynamically set the endrow object based on user input in highcharts. A user would select from a list control between the values 5, 10, 25 and all and I would like to pass that value to the data.endrow property. Thoughts?
data: {
csv: document.getElementById('csv').innerHTML,
startRow: 0,
endRow: <userinput>
endColumn: 1,
firstRowAsNames: false
},
You can make your chart after you will click on submit button. You can check selected value inside your list and pass it to chart options:
$('.submit').click(function() {
var dropMenu = $('#drop'),
selectedIndex = dropMenu[0].options.selectedIndex,
stringVal = $(dropMenu)[0].options[selectedIndex].value,
value = parseInt(stringVal);
if (stringVal === 'All') {
var lines = document.getElementById('csv').innerHTML.split('\n');
value = lines.length - 1;
}
});
Then you can make a chart with new endRow parameter:
$('#container').highcharts({
title: {
text: 'Global temperature change'
},
subtitle: {
text: 'Data module: Show only last 20 years by limiting start row.'
},
data: {
csv: document.getElementById('csv').innerHTML,
startRow: 1,
endRow: value,
endColumn: 1,
firstRowAsNames: false
},
xAxis: {
allowDecimals: false
},
series: [{
name: 'Annual mean'
}]
});
example: http://jsfiddle.net/jpko073c/3/

HighCharts with Dynamic Data not working

I have a ASP.NET MVC project with SignalR.
I have a page with a HighChart and the script looks like this:
$(function () {
window.Highcharts.setOptions({
global: {
useUTC: false
}
});
var chart;
$(document).ready(function () {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'line',
marginRight: 10
},
title: {
text: 'GMAS Queues'
},
xAxis: {
type: 'datetime',
tickInterval: 500,
labels: {
enabled: false
}
},
yAxis: {
title: {
text: 'Queue Count'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Processing Queues'
}]
});
});
$.connection.hub.logging = true;
// Reference the auto-generated proxy for the hub.
var chartData = $.connection.processingQueuesHub;
// Create a function that the hub can call back to display messages.
chartData.client.updateQueueCounts = function (data) {
//$.each(data, function(i, item) {
// // Add the message to the page.
// $('#chartDataLog').append('<li><strong>' + htmlEncode(item.QueueName)
// + '</strong>: ' + htmlEncode(item.Length) + '</li>');
//});
// set up the updating of the chart.
var series = chart.series[0];
$.each(data, function (i, item) {
if (item.QueueName == "Queue A") {
var x = Date.parse(item.Date),
y = item.Length;
series.addPoint([x, y], true, false);
}
});
};
However, I see the graph but not the points.
The strange part is the series data points are there:
Anyone know why HighCharts is not rendering the points?
Thanks, Bill N
I have to thank my good friend and co developer for figuring this out. He is a smarter and braver man than me. :) He went to the highcharts source and found that the highcharts breaks if you add to the graph series before the initial animation is completed. The animation is why the clip-rect is zero-width (it animates from zero to full width over 1s when you first create the chart). You end up adding a point to the series before this animation even really starts. This kills the animation but it doesn’t fix the width of the clip-rect. The fix is to add animation is false for the series.
series: [{ name: 'Processing Queues', data: [], animation: false }]
It looks like you are not defining what your chart.series is until it is created. The line in your ajax is as follows and its not waiting for DOM ready:
var series = chart.series[0];
But you do not define chart until $(document).ready(function () {.... Try keeping your chart object in scope of your ajax.

Highcharts: Plot yAxis values starting from a specific range

I am using highstocks and I am wondering if there is anyway I can plot the y values in a column series starting from an arbitrary number. For example. I have a column series called NU (New Users) with its first entry yAxis value of 1,000. Currently, that first entry is plotted on the yAxis from range [0, 1,000]. But instead I would like it to be plotted from [5,000, 6,000].
The reason I want this is because NU is essentially apart of another column called DAU (Daily Active Users), and I want it to be shown up as so. The first entry of the DAU column series has a Y value of 6,000, and 6,000 - 1,000 is 5,000; therefore I would like this entry of NU to start at 5,000.
Here is what I have so far
http://jsfiddle.net/6JACr/2/
I was going to plot DAU as (Original DAU - NU), and stack NU on top of DAU, but that would mean the series holds an incorrect value for DAU.
Here is my code
$(document).ready(function() {
var all_series = [];
var accu_series;
var accu_data = [];
var pccu_series = [];
var pccu_data = [];
var dau_series;
var dau_data = [];
var nu_series;
var nu_data = [];
function draw_charts() {
$('#container').highcharts('StockChart', {
rangeSelector : {
selected : 1,
buttons: [{
type: 'week',
count: 1,
text: '1w'
}, {
type: 'month',
count: 1,
text: '1m'
}, {
type: 'month',
count: 3,
text: '3m'
}, {
type: 'month',
count: 6,
text: '6m'
}, {
type: 'ytd',
text: 'YTD'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}]
},
plotOptions: {
column: {
grouping: false
}
},
yAxis: [{
// Primary Y-Axis
labels:{
align:'right',
x:-10
},
lineWidth : 1,
offset : 0
}, {
// Secondary Y-Axis
opposite: true
}],
series : all_series
});
}
//Function that takes a record and fills the series data with that record
function fill_data(index, record) {
var date = new Date(record['dailyDate']);
var utc_date = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
accu_data[index] = [utc_date, parseFloat(record['accu'])];
dau_data[index] = [utc_date, parseFloat(record['dau'])];
nu_data[index] = [utc_date, parseFloat(record['users'])];
}
// //Function that sets up the series data for plotting
function fill_series() {
dau_series = {
name: "DAU",
type: "column",
data: dau_data,
stack: 0
};
all_series[0] = dau_series;
nu_series = {
name: "NU",
type: "column",
data: nu_data,
stack: 0
};
all_series[1] = nu_series;
}
//Pull data from API, format it, and store into the series arrays
(function() {
var result = '[{"accounts":"1668","accu":"568","activePayingRate":"1.97757","activePayingUsers":"854","activeUsers":"4905","area":"1","arpu":"34.6908","company":"45","dailyDate":"2013-08-06","dau":"6000","lost":"87","newUser":"0","paying":"96","payingRate":"1.53724","pccu":"747.0","registration":"572","sales":"3305.01","server":"1","users":"1000"},{"accounts":"1554","accu":"497","activePayingRate":"2.18398","activePayingUsers":"833","activeUsers":"4533","area":"1","arpu":"34.7479","company":"45","dailyDate":"2013-08-07","dau":"5873","lost":"89","newUser":"0","paying":"96","payingRate":"1.68568","pccu":"759.0","registration":"483","sales":"3300.04","server":"1","users":"1209"}]';
var json_result = JSON.parse(result);
$.each(json_result, function(index, record) {
fill_data(index,record);
});
fill_series();
draw_charts();
})();
});
You can use low property for column, for example: http://jsfiddle.net/6JACr/4/
To display proper tooltip, add extra property like val and use pointFormat to display it.
Note: when dataGrouping will be used custom properties are removed, in that case I advice to create your own tooltip formatter, to display what you need.

Categories

Resources