Highcharts: Plot yAxis values starting from a specific range - javascript

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.

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

Highcharts : Real time updating spline chart sets y-axis data to zero

I am trying to display a set of dynamic data in a spline type chart using highcharts.
My spline type line chart has 4 series of data that needs to update through a service call. Service returns an array of data such as [0.345, 0.465, 0, 0.453] and I want to update y value of each series with the respective value in the array.
But my chart does not draw the data as expected. Even if I receive different values for y, in the chart it always displays it as 0.
This is my source code. Greatly appreciate if someone could help me figure out the issue in this or a give solution to this problem.
function drawHighChart() {
hchart = Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
},
time: {
useUTC: false
},
title: {
text: 'Audio Analytics'
},
xAxis: {
tickInterval: 1,
},
yAxis: {
title: {
text: 'Prediction'
},
min: 0,
max: 1,
tickInterval: 0.5,
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
},
/* Initially I'm setting some hardcoded values for each series.*/
series: [{
name: 'Calm',
data: [0.43934, 0.52503, 0.57177, 0.69658, 0.97031, 0.119931, 0.137133]
}, {
name: 'Happy',
data: [0.24916, 0.24064, 0.29742, 0.0000, 0.32490, 0.0000, 0.38121]
}, {
name: 'Angry',
data: [0.11744, 0.17722, 0.16005, 0.19771, 0.20185, 0.24377, 0.32147]
}, {
name: 'Disgust',
data: [0.7988, 0.15112, null, 0.22452, 0.34400, null, 0.34227]
}],
});
}
Now when I call drawHighChart() at the windows onload this is what it outputs.
Now from here, I need to update each series dynamically as service returns a data array.
This is my function that updates the chart dynamically every time the service returns a response. Every time I call this fucntion, I pass a data array constructed from the response data.
initiVal = 7; //This is a gloabl variable that increases x-axis value from 7.
function updateHighChart(dataArray) {
var series = hchart.series[0];
var series1 = hchart.series[1];
var series2 = hchart.series[2];
var series3 = hchart.series[3];
var x = initiVal;
y = dataArray[0];
y1 = dataArray[1];
y2 = dataArray[2];
y3 = dataArray[3];
console.log("dataArray: " + dataArray);
series.addPoint([x, y], true, true);
series1.addPoint([x, y1], true, true);
series2.addPoint([x, y2], true, true);
series3.addPoint([x, y3], true, true);
initiVal++;
}
But even if data is dynamically assigned to y axis values in each series, they do not update as expected in the chart. This is how the charts looks after the 6th second/instance when data needs to dynamically update in the chart.

JSON api timestamp + data parsing

I'm making a chart using Highcharts.js
The API I'm using has a different output than what Highchart uses.
Highchart reads JSON data as [timestamp, data]
which looks something like this: [1512000000000,171.85],
furthermore, the rest of the data is parsed within the same call.
Now MY Api outputs data by a single call for each timestamp (via url &ts=1511929853 for example
outputs {"ENJ":{"USD":0.02154}} (the price for that point in time)
Now here's where things get complicated. I would need to parse the price from a certain date, till now.
I've already made a ++ variable for the timestamp, but how would I include the timestamp and the price for that timestamp within the array for the data output.
It's a bit confusing, as the calls would have to be repeated so many times to draw a historical graph of the price. Some help would be appreciated. If you need more clarification, I'm right here.
Data is parsed via data function
full code here
var startDate = 1511929853;
var endDate = Math.floor((new Date).getTime()/1000);
function count() {
if (startDate != endDate) {
startDate++
}
else {
return false;
}
};
count();
$.getJSON('https://min-api.cryptocompare.com/data/pricehistorical?fsym=ENJ&tsyms=USD&ts=' + startDate, function (data) {
// Create the chart
var enjPrice = `${data.ENJ.USD}`;
console.log(enjPrice);
Highcharts.stockChart('container', {
xAxis: {
gapGridLineWidth: 0
},
rangeSelector: {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1D'
}, {
type: 'all',
count: 1,
text: 'All'
}],
selected: 1,
inputEnabled: false
},
series: [{
name: 'AAPL',
type: 'area',
data: JSON.parse("[" + enjPrice + "]"),
gapSize: 5,
tooltip: {
valueDecimals: 2
}
}]
});
});
You can use spread operator, like this,
let var = [new Date().getTime(), { ...data }.ENJ.USD]
This will result [1512000000000, 171.85] as you expected.
You need to make different functions for getting the data and generating the chart. Below is an example of how would you do it.
var startDate = 1511929853;
var endDate = Math.floor((new Date).getTime() / 1000);
var data = [];
function count() {
if (startDate != endDate) {
data.push(getPrice(startDate));
startDate++;
} else {
generateChart();
}
};
count();
function getPrice(timestamp) {
$.getJSON('https://min-api.cryptocompare.com/data/pricehistorical?fsym=ENJ&tsyms=USD&ts=' + startDate, function(data) {
return [timestamp, data.ENJ.USD];
});
}
function generateChart() {
Highcharts.stockChart('container', {
xAxis: {
gapGridLineWidth: 0
},
rangeSelector: {
buttons: [{
type: 'hour',
count: 1,
text: '1h'
}, {
type: 'day',
count: 1,
text: '1D'
}, {
type: 'all',
count: 1,
text: 'All'
}],
selected: 1,
inputEnabled: false
},
series: [{
name: 'AAPL',
type: 'area',
data,
gapSize: 5,
tooltip: {
valueDecimals: 2
}
}]
});
}
Though this is not the best way how you would do it but you get an idea.
I managed to solve the problem, by using a different API, which indexes data for past 30 days. I iterated into each index, 31, of them and grabbed the time and high(price) values and parsed them into a number since I was getting a "string" and then looped them into an array and put them into the final data [array]. just what I needed for the chart to work. If anyone needs any help just ask away. :) PS: Excuse the console.logs as I was using them to debug and test which helped me tremendously, you can remove them, as shall I
$.getJSON('https://min-api.cryptocompare.com/data/histoday?fsym=ENJ&tsym=USD', function(data) {
var x = `${data.Data[0].time}`;
var y = `${data.Data[0].high}`;
console.log(x);
console.log(y);
var tempData = [];
console.log(tempData);
for (var i = 0; i < 31; i++ ) {
var a = `${data.Data[i].time}`;
var b = `${data.Data[i].high}`;
function numberfy(val){
parseFloat(val);
}
a = parseFloat(a);
a = a * 1000;
b = parseFloat(b);
x = [a , b];
tempData.push(x);
};
data = tempData;
console.log(data.length);
Highcharts.stockChart('container', {

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/

How to remove axis labels without data points in Highcharts?

I am using the x-axis minRange to have my data points always start from the left on the x-axis. My data sets can have a maximum of 9 points. Whenever my sets only have a single data point or a few, these will end up centered in the graph, if I don't set minRange to a proper value. My x-axis is set to categories: [] to use my time values as strings and not date values. The problem is that when I have only eg two data points and minRange = 9, I will have seven axis labels numbered 2-9 with no data points. How can I remove these labels?
Fiddle
var json = [{"price":"15","time":"12:00"},{"price":"20","time":"12:30"}];
var processed_json = new Array();
$.map(json, function (obj, i) {
processed_json.push({name: obj.time,y: parseInt(obj.price) });
});
$('#container').highcharts({
xAxis: {
categories: [],
minRange: 9,
min: 0
},
yAxis: {
minRange: 30
},
series: [{
data: processed_json
}]
});
I would use tickPositions for this.
You can build the tickPositions array in the same loop that you are using to build your data by simply adding:
tickPositions.push(i);
Example:
http://jsfiddle.net/n4ym5xgr/4/
Another way to do it is to manually supply the list of categories to highcharts library. The idea is to have categories corresponding to your data-points named after obj.time and remaining categories being just empty strings.
var categoryCount = 10;
var json = [{"price":"15","time":"12:00"},{"price":"20","time":"12:30"}];
var processed_json = new Array();
var categories = new Array(categoryCount);
categories.fill("", 0, categoryCount); //Fill list of categories with empty strings
$.map(json, function (obj, i) {
processed_json.push({name: obj.time,y: parseInt(obj.price) });
categories[i] = obj.time; //Set the time for particular category
});
$('#container').highcharts({
xAxis: {
categories: categories,
minRange: categoryCount - 1,
min: 0
},
yAxis: {
minRange: 30
},
plotOptions: {
},
series: [{
data: processed_json
}]
});
Variable categories should be something like ["12:00", "12:30", "", "", "", "", "", "", ""] in this particular case.

Categories

Resources