Setting xAxis.min breaks area display in two-point highcharts - javascript
Please have a look at the following fiddle: http://jsfiddle.net/gy3bV/1/.
That's a "shortened" version of a bug I am trying to fix in my project.
The fiddle code is as simple as this (mine is more complicated, but the issue is reflected here):
$(function () {
var chartOptions = {
xAxis: {
categories: ['Jan', 'Feb'],
min: 0
},
series: [{
type: 'area',
data: [0, 10],
name: 'Area'
}]
};
$('#container0').highcharts(chartOptions);
chartOptions.xAxis.min = 1;
$('#container1').highcharts(chartOptions);
});
So, when min = 0, it draws a valid chart with the first point at xaxis (0 level) and the second one at the level of 10. When min = 1, I expect it to just hide the first point and to draw the area as if it goes from hidden ('Jan', 0) to visible ('Feb', 10). However, it just draws a horizontal line at the level of 10.
It behaves as expected with >2 points: http://jsfiddle.net/gy3bV/2/
It does not work when I am passing full coordinates as series (data: [['Jan', 0], ['Feb', 10]]): http://jsfiddle.net/gy3bV/3/
I proved that it is not related to first point being 0 - the same results with any other value. It is also not related to using type: 'area' - the same behavior with line.
Ideas? What may I be doing wrong? Could that be a highcharts bug?
Thanks!
Your first "working" example has:
xAxis: { categories: ['Jan', 'Feb', 'Mar'] }
series: [{ data: [0, 10, 15] }]
While the "broken" example has:
xAxis: { categories: ['Jan', 'Feb'] }
series: [{ data: [['Jan', 0], ['Feb', 10]] }]
The problem arises when you have min: 1, and only two values. That means that the graph only shows a single point, which means the x-axis doesn't have any span at all (it shows from 0.999 to 1.001). Because you are so far zoomed in the graph appears to be completely horizontal, as the other points are "lightyears" away on the x-axis, while having rather similar y-values.
In this JSFiddle you can see what appears to be a rather strange animation of the process. However, if we go slowly, it becomes more clear that the other points are infact there, just far far away. Take note of how the y-axis never changes, so the points have to be moved so far out that the y-axis difference can't be spotted:
JSFiddle zoom in
JSFiddle zoom out
You will have to make sure that your x-axis spans more than a single value, for example with min: 1, max: 2 or adding more points. If you want to be true to the values being dates you should consider changing to type: 'datetime'.
Related
Highcharts with custom scaling in upper regions
I would like to know how to achieve a custom scale for a chart in Highcharts. I want to display a boxplot which has very high whiskers. The normal values to display are between 500 and 1000 but there are some anomalies which are about 6000 on y-axis. This is causing the whole chart to be squeezed and the scaling is so small that you can't determine the boxplots correctly. I would like to increase the tick-size between 1000 and 6000 to decrease the heigt of the chart.
Highcharts provides breaks functionality that seems to be ideal for your case: https://api.highcharts.com/highcharts/yAxis.breaks Another approach is to change the yAxis type to logarithmic: https://api.highcharts.com/highcharts/yAxis.type EDIT The discussion in the comments section reveals that the OP needs rather custom y axis formatting than breaks functionality. Here's how to approach this issue: The problem here is that axes in Highcharts can only have either constant or logarythmic scales. Your example shows irregular scale - the values are not in constant or logarythmic order ([0, 3, 10, 30, 150]). Here's what I've done to mimic that kind of look and behaviour: I set tickPositions to [0, 1, 2, 3, 4] - these are the actual values that appear on the chart. As you can see the distance between all these numbers is constant: 1. Then I used formatter to display corresponding number from ranges array for each label. yAxis: { tickPositions: [0, 1, 2, 3, 4], labels: { formatter: function() { return ranges[this.pos]; } } }, Before I passed the data to the chart constructor I converted all the values so that they're between 0 and 4: series: [{ data: [2, 120].map(function(val) { var range = findRange(val); var y = range.index + (val - range.low) / (range.high - range.low); return { y: y, originalValue: val }; }) }] Finally I used originalValue property in tooltip.format string to print to the user the number before the conversion. tooltip: { pointFormat: "<span style='color:{point.color}'>\u25CF</span> {series.name}: <b>{point.originalValue}</b><br/>" }, This example is simplified to the line series case but can be easily adjusted to boxplot series. The code serves only for the example purposes and should be improved - it's easy to cause an error within it. Live working demo: https://jsfiddle.net/kkulig/ytjz1jej/ API references: https://api.highcharts.com/highcharts/tooltip.pointFormat https://api.highcharts.com/highcharts/yAxis.tickPositions https://api.highcharts.com/highcharts/xAxis.labels.formatter
C3 Bar Graph x-axis labels are too congested
I have created a Bar graph using C3 JS plugin, The graph is working fine but the problem is with the x-axis labels looks too congested like as shown below Working JSFiddle My Code is as given below var chart = c3.generate({ bindto: "#chart", data: { x : 'x', columns: [ ['x', "2016-04-01","2016-04-08","2016-04-15","2016-04-22","2016-04-29","2016-05-06","2016-05-13","2016-05-20","2016-05-27","2016-06-03","2016-06-10","2016-06-17","2016-06-24","2016-07-09","2016-07-10","2016-07-11","2016-07-12","2016-07-13","2016-07-15","2016-07-16","2016-07-17","2016-07-18","2016-07-19","2016-07-20","2016-07-21","2016-07-22","2016-07-23","2016-07-24","2016-07-25","2016-07-26","2016-07-27","2016-07-28","2016-07-29","2016-07-30","2016-07-31","2016-08-01","2016-08-02","2016-08-03","2016-08-04","2016-08-05","2016-08-06","2016-08-07","2016-08-08","2016-08-09","2016-08-10","2016-08-11","2016-08-12","2016-08-13","2016-08-14","2016-08-15","2016-08-16","2016-08-17","2016-08-18","2016-08-19","2016-08-20","2016-08-21","2016-08-22","2016-08-23","2016-08-24","2016-08-25","2016-08-26","2016-08-27","2016-08-28","2016-08-29","2016-08-30","2016-08-31","2016-09-01","2016-09-02","2016-09-03","2016-09-04","2016-09-05","2016-09-06","2016-09-07","2016-09-08","2016-09-09","2016-09-10","2016-09-11","2016-09-12","2016-09-13","2016-09-14","2016-09-15","2016-09-16","2016-09-17","2016-09-18","2016-09-19","2016-09-20","2016-09-21","2016-09-22","2016-09-23","2016-09-24","2016-09-25","2016-09-26","2016-09-27","2016-09-28","2016-09-29","2016-09-30","2016-10-01","2016-10-02","2016-10-03","2016-10-04","2016-10-05","2016-10-06","2016-10-07","2016-10-08","2016-10-09","2016-10-10","2016-10-11","2016-10-12","2016-10-13","2016-10-14","2016-10-15","2016-10-16","2016-10-17","2016-10-18","2016-10-19","2016-10-20","2016-10-21","2016-10-22","2016-10-23","2016-10-24","2016-10-25","2016-10-26","2016-10-27","2016-10-28","2016-10-29","2016-10-30","2016-10-31","2016-11-01","2016-11-02","2016-11-03","2016-11-04","2016-11-09"], ['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2500,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2696,2748,2748,2694,2694,2694,2694,2694,2694,2694,2668,2668,2668,2668,2576,2572,2572,3043,3084,3084,3084,3084,3084,3156,3521,3521,3550,3542,3542,3573,3580,3629,3579,3584,3542,2757,2791,2696,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3415,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3414,3369,3376,3371,3373,3371,3379,3363,3373,3347,3348,3382,3402,3410,3434,2579,2579,2369], ['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,2375,2425,2475,2500,2500,2087,2087,2087,2087,2091,2087,1767,1767,1767,1633,1498,1498,1642,1637,1633,1609,1841,1713,1702,1862,1888,1888,1888,1949,1976,1977,2014,2014,2014,1946,1966,1973,2224,2252,2318,2318,2318,2327,2373,2513,2535,2543,2534,2539,2823,2849,2990,3142,3142,3108,2513,2687,2678,2856,2860,2861,2862,2866,2869,2870,2875,2874,2874,2874,2879,2885,2886,2883,2889,2896,2895,2899,2903,2909,2911,2913,2913,2913,2916,2922,2933,2937,2943,2942,2943,2947,1811,1826,1837,1840,1840,1841,1843,1511,1854,1853,1851,1852,1853,1849,1852,1874,1857,1883,1886,1888,1904,1903,1924,1947,2060,2068,2068,2082,1582,1344,836,839,788] ], type: 'bar' }, axis: { x: { type: 'category', tick: { rotate: -60, multiline: false }, height: 130 } } }); Can anyone please tell me some solution for this What I did to solve it I have used timeseries type instead of category type, after that the label issue got resolved but the graph was been plottted with more white spaces for the month of march like as shown below Working JSFiddle
You can use c3's tick count setting for this, so here we say 20 labels. However there is an added gotcha in that ticks that now resolve to a fractional category value won't show - i.e. the 2nd equally spaced tick out of 20 may be the 2.6667th element in the x category axis - so you need to have a little format function that adjusts for this, otherwise you just get the end and start labels. (Or you could figure out a tick count that divides into your data count + 1 as a whole number.) tick: { format: function (x) { var cats = this.api.categories(); return cats[Math.round(x)]; }, count: 20, rotate: -60, multiline: false }, http://jsfiddle.net/fz0t10yb/7/
One of the possible solution could be to use x-axis labels at required indexes only & leaving others blank. ['x', "2016-04-01","","","","2016-04-29","","","",...] ['pv1', 2500,2500,2500,2500,2500,2500,2500,2500,...] ['pv2', 1750,1750,1750,1750,1825,1850,1975,2150,...] You can position labels so that it would capture the date and at same time it looks good also.
How can I create a horizontal stacked bar chart with labels on the bars themselves as well as labels above the bars?
I'm trying to create a horizontal stacked bar chart with labels on the bars themselves (currently using dataLabels) as well as labels just above the bars. Here is a JSFiddle I've created that somewhat resembles what I am trying to accomplish. In this example I've placed the labels using plotLine labels, but I'm having a difficult time figuring out how to place the bars correctly in my real use case as I get the data for the bars through Ajax calls. JSFiddle I've experimented with stackLabels, plotLine labels as well as plotBand labels but to no avail. How can I place labels above the bars correctly every time?
I would use plotBands instead of plotLines - you can better control the alignment within the band, which can be set to cover the same portion of the graph as the bar itself. An example. Using your series data: var series = [{ name: 'John', data: [5] }, { name: 'Jane', data: [2] }, { name: 'Joe', data: [3] }] We can loop through and build a plotBands array from the same data: var bands = [], prevData = 0; $.each(series, function(i,ser) { var point = ser.data[0], name = ser.name; bands.push({ from: prevData, to: (prevData + point), color: 'rgba(255,255,255,0)', label: { text: name, align: 'center' } }); prevData = (prevData+point); }); To make this match the order of the series as plotted, we need to set reversedStacks: false on the yAxis, as by default, Highcharts reverses the order of the series. Then we populate the plotBands with our generated array: yAxis: { reversedStacks: false, plotBands: bands } In this way you can make use of the full feature set of the plotBands label properties. Updated fiddle: http://jsfiddle.net/jlbriggs/xwzfjbhe/4/ And this adjusts to fit however many data points you have, provided you keep the same format (series.name, series.data[0]): http://jsfiddle.net/jlbriggs/xwzfjbhe/5/ There are a number of other ways you can go about this as well, including: The labels property: http://api.highcharts.com/highcharts/labels The renderer function: http://api.highcharts.com/highcharts/Renderer
Highcharts blank chart with x and y axis
I want to use highcharts creating a blank chart with no datas but x and y axis. How to do it? var chart = new Highcharts.Chart({ chart: { renderTo: 'container' }, yAxis: { labels: { formatter: function() { return this.value +' km'; } } }, series: [{ data: [] }] }); it returns But I want to display y-axis with label.
You can put in your min/max values for the xAxis and yAxis and use null for all data. Forked from #ZaheerAhmed's response above as I figure it deserves a spot as an alternative solution without needing to hide the data after the fact. i.e. yAxis: { min: 1, max: } , xAxis: { min: 1, max: 50 }, series: { data:[null,null] }
You can put data and hide the series after setting property ignoreHiddenSeries : false Here is Working Demo If you hide the series Y-Axis will still be visible.
FWIW, it seems that highcharts has this functionality built in yAxis.showEmpty Unfortunately, the fiddle listed in the documentation doesn't work, and there is a related open highcharts issue on the matter: no hide y axis
Setting min and max for xAxis and yAxis is not a good solution! Because if the data is loaded later (When it's resolved), then you won't have auto calculated min and max. In Highcharts API, it's said: If null, the max value is automatically calculated So you should set min and max back to null when the data is loaded. But in my case setting it to null or even deleting the option, didn't result in automatic calculating (Seems strange). What I did instead was setting charts.showAxes to true! That's it. Take a look at the demo provided by Highcharts Important: You of course need to set series to something like this: series: [ { data: [null, null, null] }, { data: [null, null, null] } ] Note: Make sure xAxis.showEmpty and yAxis.showEmpty are set true (which is true by default).
Highcharts - show every other x-axis category
I have Highcharts set up to display a graph with a bunch of xAxis categories. This is all working fine, but I would like to be able to skip some of the xAxis categories, so not everything one is shown. You can see an example of this working within Campaign Monitor's reporting section (screenshot: http://screencast.com/t/Y2FjNzQ4Y). Any idea how I can achieve this same layout?
It seems like the xAxis:labels:step value is what should be used to accomplish this: xAxis: { categories: ['JAN', 'FEB', 'MAR', 'APR', 'MAY'], labels:{ step: 2 // this will show every second label } }, Step Axis Labels Super late, but I figure this can help someone out.
xAxis: { categories: categoriesname, labels: { style: { color: '#000', font: '9px Trebuchet MS, Verdana, sans-serif' } }, **tickInterval: TickInterval,**// SET THIS tickPixelInterval: 80, tickmarkPlacement: 'on' },
You can set the xAxis type as 'datetime' then set the pointInterval and PointStart in the plotoptions. Code example: var chart; $(document).ready(function () { chart = new Highcharts.Chart({ "xAxis": { "type": "datetime" "plotOptions": { "line": { "pointInterval": 86400000, "pointStart": 1282408923000 } }, }); }); The figures you see for pointInterval and Start are in millisecionds which you can generate using getTime() The interval in your case would be 86400000ms which is one day. The library displays appropriate intervals based on your data interval.
here is my ugly solution :) I'm using array as queue. http://javascript.about.com/library/blqueue.htm if you fill point datas to the queue, you can to set datas for your chart series. var myQueue = new Array(); var myPoint = [x, y]; myQueue.push(myPoint); chart.series[0].setData(myQueue); my X axis is not a datetime, it's an integer first var x = 0; x value should be always increment when you need a new point. http://dl.dropbox.com/u/3482121/picture/highcharts/PM/Screenshot.png