This is my JSON:
[{"name":"AniSig01",
"data":[["2013,06,11,16,06,55",14],
["2013,06,11,16,07,00",14],
["2013,06,11,16,07,06",15],
["2013,06,11,16,07,11",14]]},
{"name":"AniSig02",
"data":[["2013,06,11,16,06,55",0],
["2013,06,11,16,07,00",0],
["2013,06,11,16,07,06",0],
["2013,06,11,16,07,11",0]]},
{"name":"AniSig03",
"data":[["2013,06,11,16,06,55",6],
["2013,06,11,16,07,00",6],
["2013,06,11,16,07,06",7],
["2013,06,11,16,07,11",6]]},
{"name":"AniSig04",
"data":[["2013,06,11,16,06,55",13],
["2013,06,11,16,07,00",13],
["2013,06,11,16,07,06",14],
["2013,06,11,16,07,11",13]]}]
And my HighCharts code:
$(document).ready(function()
{
var options =
{
chart:
{
renderTo: 'container',
type: 'spline',
},
title:
{
text: 'Statistik',
},
xAxis:
{
type:'datetime',
},
yAxis:
{
title: { text: ''},
},
tooltip:
{
shared: true,
crosshairs: true,
},
plotOptions:
{
series:
{
marker: {enabled: false},
animation: false,
threshold: null
}
},
series:[]
};
$.getJSON('datgen/DatReq.txt',function(data)
{
$.each(data, function(key,value)
{
var series = { data:[]};
$.each(value, function(key,val)
{
if (key == 'name')
{
series.name = val;
}
else
{
$.each(val, function(key,val)
{
val[0] = 'Date.UTC(' + val[0] + ')';
series.data.push(val[0], val[1]);
});
}
});
options.series.push(value);
});
var linechart = new Highcharts.Chart(options);
});
});
But I see these 4 signals only as a point (vertical line) on the chart.
and the Tooltip didn't show the correct time (the x-value)!
Does anyone know what the problem is?
As you've discovered, your X values are at fault. Not only are they wrong (per the tooltip), but they seem to be the same wrong for each point (giving you a vertical line).
So, let's concentrate on the X values. What are they? Okay, times. At some point, you had to parse the times from the data source into Javascript. Where did you do that?
Here:
val[0] = 'Date.UTC(' + val[0] + ')';
There we go — Javascript functions simply don't work that way. You can't just shove code into a string and expect it to be executed.
Split val[0] on the comma character, and feed each part of the result into a real call to Date.UTC.
Related
I'm looking to hide the first yAxis label in highcharts. I am unable to find how to do this option. This question closely ressembles this question: Hide first yaxis label . However the solution I'm looking is for highcharts.
From the image above, I would just like for the -10 to be hidden.
What options do I need to add to accomplish this?
The code added below is just a generic function I've created that takes in a parameter that I have named options (an object) that I've set with a list of options (such as title, subtitles, series... ).
var hc_bubble = function(options){
$(options.target).highcharts({
chart: {
type: 'bubble',
zoomType: 'xy'
},
title: {
text: options.title || 'unknown'
},
subtitle: {
text: options.subtitle || ''
},
xAxis: {
type: options.date || 'datetime',
labels: {
formatter: function() {
return Highcharts.dateFormat("%b %Y", this.value)
}
},
title: {
enabled: true,
text: options.xTitle || 'unknown'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true
},
yAxis: {
title: {
text: options.yTitle || 'unknown'
}
},
tooltip:{
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.y} ' + options.yType || 'Connections'
},
series: options.series
});
}
While your solution works, there is a slightly more generic solution you might like if your intent is always to prevent the yAxis having a label at the bottom left:
yAxis: {
labels: {
formatter: function() {
if ( this.isFirst ) { return ''; }
return this.value;
}
}
},
Making use of the isFirst property that Highcharts has on this prevents your reliance on "magic numbers" (similarly, there is an isLast value if you'd like to try that -- though I don't see as much use for it).
I wasn't going to post this question at first because I just found the answer (after searching in the docs for a while) but I figured this could help others.
Simply make sure you add the formatter callback in your labels object:
yAxis: {
labels:{
formatter: function(){
if(this.value >= 0){
return this.value;
}
}
}
}
http://api.highcharts.com/highcharts#yAxis.labels.formatter
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.
I have a requirement to plot run history of a task in Highcharts. It needs to show that run history of the tasks as a horizontal bar. There are additional requirements which I've added as an update below. Recently I found out that inverted option is not supported in StockChart and that only navigator & rangeSelector are available in StockChart. Therefore I am using those functions.
So in order to achieve the requirement I created something similar to this jsfiddle example (found somewhere while browsing don't remember the source) and ended up with this plunker link with help from my previous question, thanks to Pawel Fus
Updating question to avoid confusion
Additional requirements:
Show only those tasks which ran in a particular date and time range. In case there are too many runs, such as more than 10 run, then there needs to be a way to display only 10 tasks visibly with a y-axis that is scrollable to show other tasks.
plunker link to the problem
Problem explanation of above plunker.
If you check the screenshot below from above plunker, the time range is from 12/12/2014 09:32:26 to 12/12/2014 10:32:26 and there are only 2 tasks that has run m_ARRAYV_SALES_ZIG1_CALL2_VOD__C_OB & m_ZIG2_HCP_MERGE_IB_CN. However I can see another task in between LILLY_C which did not even ran in this date time range. (In actual data there are more than 10 tasks that clutters this chart which does not even fall under this date time range)
Also if you notice at the bottom most right corner time shifted from 09:38 to 19:20. 19:20 is the end time for m_ZIG2_HCP_MERGE_IB_CN task.
Below is my chart options
var chart_options = {
chart: {
renderTo: 'container',
height: 600
},
title: {
},
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
gridLineWidth: 1,
tickInterval: 1 * 3600 * 1000,
dateTimeLabelFormats: {
month: '%b %e, %Y'
}
},
yAxis: {
tickInterval: 1,
gridLineWidth: 1,
labels: {
formatter: function() {
if (tasks[this.value]) {
return tasks[this.value].name;
}
}
},
startOnTick: false,
endOnTick: false,
title: {
text: 'Task'
}
},
rangeSelector: {
selected: 0,
buttons: [ {
type: "minute",
count: 60,
text: "1h"
}, {
type: "minute",
count: 180,
text: "3h"
}, {
type: "minute",
count: 300,
text: "5h"
}],
inputDateFormat: '%m/%d/%Y %H:%M:%S',
inputEditDateFormat: '%m/%d/%Y %H:%M:%S',
inputBoxWidth: 120
},
navigator: {
enabled: false
},
legend: {
enabled: false
},
tooltip: {
shared: false,
formatter: function() {
var str = '';
str += 'Task: ' + this.series.name + '<br>';
str += 'From: ' + Highcharts.dateFormat('%m/%d/%y %H:%M', this.point.from) + '<br>';
str += 'To: ' + Highcharts.dateFormat('%m/%d/%y %H:%M', this.point.to) + '<br>';
return str;
}
},
plotOptions: {
line: {
lineWidth: 10,
marker: {
enabled: true
},
dataLabels: {
enabled: true,
align: 'left',
formatter: function() {
return this.point.options && this.point.options.label;
}
},
states:{
hover:{
lineWidth:10
}
}
},
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
var query = '{ "task_id": "'+this.task_id+'","start_time": '+this.from+',"exclude_interval": '+opExcludeMinutes+',"size": 10 }';
$scope.taskName = this.series.name;
$scope.isTaskSelected = false;
$scope.operationalReportAgentTaskHistoryServiceRequest(query);
}
}
}
}
},
series: seriesData
};
So after a few hours of digging, I have just found out the culprit (or I really hope so). The problem is your definition of yAxis label formatter:
yAxis: {
tickInterval: 1,
gridLineWidth: 1,
labels: {
formatter: function() { // THIS IS THE PROBLEM
if (tasks[this.value]) {
return tasks[this.value].name;
}
}
},
startOnTick: false,
endOnTick: false,
title: {
text: 'Task'
}
},
You don't actually check if you should display the label according to task.intervals (see json.js). A simple update (Plunker) of the formatter seems to work:
yAxis: {
tickInterval: 1,
gridLineWidth: 1,
labels: {
formatter: function () {
console.log("scripts.js - yAxis.labels.formatter", this.value);
if (tasks[this.value]) {
//if (tasks[this.value].name === 'LILLY_C') {
var _xAxis = this.chart.axes[0];
var _task = tasks[this.value];
var _show = false;
// Not optimized for large collections
for (var _i = 0; _i < _task.intervals.length; _i++) {
var _int = _task.intervals[_i];
if (_xAxis.min <= _int.to) {
_show = true;
}
}
console.log("scripts.js - yAxis.labels.formatter",
tasks[this.value].name,
_show,
_xAxis.min,
_xAxis.max,
_task.intervals
);
if (_show) {
return tasks[this.value].name;
} else {
return;
}
//}
//return tasks[this.value].name;
}
}
},
startOnTick: false,
endOnTick: false,
title: {
text: 'Task'
}
},
See Plunker for demo.
Meaning of the yAxis labels is: Show label if you see a run in the graph or if there is a run on the right of the graph. Please modify the condition
if (_xAxis.min <= _int.to) {
as you see fit.
Disclaimer: I don't use Highcharts, so this answer tries to explain the problem and not to suggest a Highcharts-way of solving the problem.
Lessons learned:
yaxis-plugin.js is irrelevant to the problem.
Highstock.js is an open-source library (highstock.src.js). Any debugging is much easier if you debug original source code. Minified code adds unnecessary complexity and guessing. I have downloaded the library and added some console.log() to find out what is going on.
let's say I am generating chart json that might look something like this:
return jsonify({
chart: {
post_url: '/some/url/'
type: column
},
title: {
text: this is a chart
},
tooltip: {
shared: true
},
xAxis: {
categories: [x[0].strftime('%b %y') for x in arr]
},
plotOptions: {
column: {
stacking: normal
}
}
series: [{
data: [[x.thing for x in month].count(True) for month in arr]
}, {
data: [[x.thing for x in month].count(False) for month in arr]
}]
})
In setOptions, I do the following.
Highcharts.setOptions({
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function(el) {
$.post(this.chart.post_url + this.category, function(data) {
console.log(data);
});
}
}
}
}
}
});
However, this does not allow me to click and go to the post url, saying post_url is not defined. So I imagine that data is lost when the chart is rendered.
What's a way around this?
The this in a point.events.click referres to a point object and not a chart object. You can walk backwards to the chart configuration using this.series.chart.userOptions.chart.post_url like so:
point: {
events: {
click: function() {
alert(this.series.chart.userOptions.chart.post_url);
}
}
}
Here's an example fiddle.
If I understand correctly you want to have the series.points go to a URL when you click on them? You are missing an ending comma after your post_url definition and quotes around the type value. That being said I would set the URL in the series options and not the chart options. Then you might need to set it like:
series: [{
post_url: '/some/url/',
data: [[x.thing for x in month].count(True) for month in arr]
}, {
post_url: '/some/url/',
data: [[x.thing for x in month].count(False) for month in arr]
}]
Then in the click event:
events: {
click: function(el) {
$.post(this.post_url + this.category, function(data) {
console.log(data);
});
}
Demo.
If you still want to use the chart.post_url method you need to fix your typos. Demo.
I have some difficulties displaying a graph with Highstock. It seems like I can't have access to the x-axis part where the graph should be displayed. I am new with Highstocks so my code could seem like a mess but my idea was the following:
First access the json file from the server. Convert it in the right format [[datestamp, value], ....]. Then display the graph.
Here is my Json file (file.json):
[{"date":"2013-10-04T22:31:12.000Z","value":30000},{"date":"2013-10-04T22:31:58.000Z","value":35000},{"date":"2013-10-04T22:32:05.000Z","value":60000},{"date":"2013-10-04T22:32:12.000Z","value":45000}]
My code is the following:
$(function() {
chartOjb = new Object();
var mydata = [];
$.getJSON('file.json', function(data) {
$.each(data, function (index, item) {
chartOjb.name = getTimestamp(item.date);
chartOjb.data = item.value;
mydata.push({ x: chartOjb.name, y: parseFloat(chartOjb.data) });
});
$('#container').highcharts('StockChart', {
chart: {
type: 'candlestick',
zoomType: 'x'
},
navigator: {
adaptToUpdatedData: false,
series: {
data: mydata
}
},
scrollbar: {
liveRedraw: false
},
xAxis: {
type: 'datetime',
title: 'Time',
//minRange: 3600 * 1000/15 // one hour
},
rangeSelector : {
selected : 1
},
title : {
text : value
},
series : [{
name : 'Capacité',
data : data,
tooltip: {
valueDecimals: 2
}
}] }); });
});
Thank you very much for your help
Could you add your function getTimestamp()? Maybe there is something wrong.
Keep in mind that:
x-value should be timestamp,
when using a lot of objects { x: x, y: y }, set turboThreshold