Highcharts Bar Chart Auto Height - highcharts

I have a highcharts 3d Bar chart and I need the height to automatically size depending on how many bars are on the chart. We may only need 1 or we may need 100. the current problem is that it always expands to fill the page. So If I have one it will be a huge bar and if I have 100 it will be all smashed together. I need it to grow as it has data.
I have done searching and see this http://jsfiddle.net/wkkAd/149/ demo.
Here is my chart with that demo: http://jsfiddle.net/a40a0bjy/2/
The issue is that I neeed to to grow as it has more bars. Right now, it expands to 100% of my page height.
I set the bar height hoping that it would stop the chart from growing bigger but it does not work.
Using:
pointWidth: 30//width of the column bars irrespective of the chart size
If I do that, it will just have the 30 width bars with all kinds of space and the chart still expands to fill the entire page height.
Update: This is what I want to do. http://jsfiddle.net/highcharts/jMX8G/
If you remove some of that data the charts automatically is smaller, while keeping the same size bar heights.
This issue with that demo is that my data is much more complex than that demos. Here it is:
var data = [{
name: 'Not Complete',
data: [{
y: 5,
drilldown: {
TaskID: 343434545252,
name: 'somename'
}
},
{
y: 3,
drilldown: {
TaskID: 343434545252,
name: 'somename'
}
},
{
y: 4,
drilldown: {
TaskID: 343434545252,
name: 'somename'
}
},
{
y: 7,
drilldown: {
TaskID: 343434545252,
name: 'somename'
}
},
{
y: 2,
drilldown: {
TaskID: 343434545252,
name: 'somename'
}
}]
}, {
name: 'Clean Up',
data: [2, 2, 3, 2, 1]
}, {
name: 'Complete',
data: [3, 4, 4, 2, 5]
}];
Now the denmo uses this:
height: data.length * 20 + 120 // 20px per data item plus top and bottom margins
But I do not know how or what to get the length of for my data.

Related

Highcharts unevenly spaced x-axis with category labels

I'm trying to plot some sparse values over a few hundred x-axis category labels. The labels represent points along a geographical entity, so it is necessary to space them according to the actual distance between each point.
I can easily make x-axis categories and plot the values against them, but each category is evenly spaced. If I change to using a complex marker with {x, y, name} properties, the categories are only displayed if they match the tick interval. If a category doesn't match the tick interval, then a number is displayed.
I can produce the following:
with this small fake sample of data, JSFiddle:
...
xAxis: {
type: 'category'
},
series: [{
name: 'Series 1',
data: [
{x:1, y:null, name: 'AB1.1'},
{x:4, y:1, name: 'AB1.2'},
{x:5, y:null, name: 'AB1.3'},
{x:11, y:1, name: 'AB1.4'},
{x:14, y:null, name: 'AB1.5'},
{x:14, y:null, name: 'AB1.6'},
{x:19, y:1, name: 'AB1.7'},
{x:27, y:1, name: 'AB1.8'},
{x:28, y:null, name: 'AB1.9'},
{x:30, y:1, name: 'AB2'},
{x:37, y:1, name: 'AB2.1'},
{x:37, y:1, name: 'AB2.2'},
{x:38, y:1, name: 'AB2.3'},
]
}]
...
As you can see, the x-axis at this zoom level shows:
0, 3, 6, 9, 12, 15, 18, 21, 24, AB1.8, AB2, 33, 36, 39
What I want is for the x-axis to show any of the actual labels (so long as the markers are placed relative to their distance, just like the x-values of the plot); but no generated numbers.
In reality, I have multiple series with around 1,000 points each, but they will all be on the same geographical entity so they all share the same categories. (JSFiddle with much more fake data). I can also guarantee that x-values are whole numbers.
I have already tried specifying various x-axis options around ticks, minimum ticks etc. but highcharts still wants to extrapolate evenly spaced labels.
Thanks!
I have got the results I want (JSFiddle) by setting xAxis.tickPositions dynamically on zoom. To begin with, I pick about 35 x-Axis positions to display my markers (an arbitrary number but I picked something that worked for my fixed-width chart size).
Then, on zoom, I update the chart to display about 30 markers that are within the new zoom level.
This way I always have a good number of markers displayed, and they are unevenly spaced because that's what my actual data is like.
Zoomed out (L) and zoomed in (R):
this is an array of all x-axis points that have a marker-a few thousand
allTicks = [1, 6, 9, 9, ...]
a function to select 30 points from the given array
function selectTickPositions(tickPositions) {
const maxTicks = 30;
if (tickPositions.length <= maxTicks) return tickPositions; // return all
let mod = Math.round(tickPositions.length / maxTicks);
// always select the first and the last, and then up to 30 more
return tickPositions.filter((val, idx) => idx == 0 || idx == tickPositions.length - 1 || idx % mod == 0);
}
setup the chart options:
let theChart = Highcharts.chart('container', {
chart: {
...
events: {
// the selection event is fired when a zoom selection is made
selection: (event) => {
let ticks;
if (event.xAxis) {
let min = event.xAxis[0].min;
let max = event.xAxis[0].max;
ticks = selectTickPositions(allTicks.filter(t => t >= min && t <= max));
} else {
ticks = selectTickPositions(allTicks);
}
theChart.update({
xAxis: {
tickPositions: ticks
}
});
return true;
}
}
},
...
xAxis: {
type: 'category',
tickPositions: selectTickPositions(allTicks)
},
});
I am not sure if I understand your requirement very well, but here is my attempt of showing just a xAxis.labels if the label is a category string.
Demo: https://jsfiddle.net/BlackLabel/4xdjw5L7/
xAxis: {
type: 'category',
endOnTick: true,
startOnTick: true,
labels: {
formatter() {
if (typeof this.value !== 'number') {
return this.value
}
}
}
},
API: https://api.highcharts.com/highcharts/xAxis.labels.formatter
Let me know if this is an expected output.

Fixed height/width of bars in highcharts

I'm new with highcharts and what I'm trying to achieve is to have fixed bar height/width and fixed spacing between bars in highcharts. Either there are 20 bars or only 3 of them, the bar height/width and space between bars should remain the same. And the highchart itself should be with fixed height, f.e. 300px. I'm not sure this is doable, but here is an example of what I'm trying to achieve:
https://imgur.com/BmyZjvb
https://imgur.com/OMiZZ2R
Yes, you need to only set fixed axis extremes:
xAxis: {
min: 0,
max: 4
},
yAxis: {
min: 0,
max: 100
}
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/5011/
API Reference:
https://api.highcharts.com/highcharts/xAxis.min
https://api.highcharts.com/highcharts/xAxis.max
I don't know if there is a better solution, but this is one solution:
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', '', '', '']
},
series: [
{
data: [5, 3, 4, 0, 0, 0]
}
],
http://jsfiddle.net/aabramya/jfdv3z65/7/

Highcharts display priority of overlapping labels

When data labels overlap in Highcharts, only one data label is displayed. This seems to be handled randomly. See fiddle:
http://jsfiddle.net/lamarant/rmxLd1d4/
$(function () {
$('#container').highcharts({
title: {
text: 'Label Test'
},
series: [{
type: 'line',
data: [ 10, 10, 10, 10, 10, 10, 50],
dataLabels: {
enabled: true,
color: 'blue',
zIndex: 10
},
zIndex: 10
},
{
type: 'line',
data: [ 11, 11, 11, 11, 11, 11, 49],
dataLabels: {
enabled: true,
color: 'red',
zIndex: 10
},
zIndex: 20
}]
});
});
Notice that the first data label displayed in the chart is from the second series while the rest are from the first series.
I tried setting the priority of the label display using zIndex in both series and series.dataLabel with no luck.
Is there any way to set it so that a designated series always takes priority when Highcharts determines which label to display?
One possible fix is supplying a labelrank for each point, which is used to evaluate their sorting order. If you supply this rank for each point in a series, that series should be considered "above" series without such a rank (or with a lower rank integer value).
In code, manually for each point:
series: [{
data: [
{ y: 11, labelrank: 1 },
{ y:11, labelrank: 1 }
// ...
],
// ...
}]
In code, using the callback function (JSFiddle):
$('#container').highcharts({
// Options ...
}, function() {
var mySeriesIndex = 1;
// For each point in the preferred series
for(i = 0; i < this.series[mySeriesIndex].points.length; i++)
// Set a labelrank
this.series[mySeriesIndex].points[i].labelrank = 1;
});
My current take on the issue itself is this:
With the current implementation of the overlap logic it seems to me that this is a bit of an unintended behavior. The source code uses Array.sort in a way that shifts the positions of the point labels, since Array.sort is not guaranteed to be stable (same-value items wont retain their original order).
If you check your example in Firefox it should work as intended (their implementation of Array.sort is different), while in Chrome it doesn't (not stable). You could hope that this little feature is fixed.

Shared Crosshair Highlighting /w Non-sequential Series

I have two lines of date data. One line plots a point sequentially every day. The other line plots non-sequental points that fall on one of the days of the previous line.
The problem is that the crosshair functionality behaves weirdly when I do this. See the example linked below. You will notice that although the tooltip and point highlighting shows for the proper point, the crosshair gets stuck on the non-sequential point along the x-axis, even though this is not the current position of my mouse on the chart. The exception to this is when you hover your mouse directly across the line. The crosshair follows the mouse properly then.
See example here: http://jsfiddle.net/2H9m3/1/
$(function () {
$('#container').highcharts({
tooltip: {
shared: true,
crosshairs: true
},
xAxis: {
type: "datetime", maxPadding: 0, minPadding: 0
},
yAxis: {
min: 0
},
series: [{
name: 'Line',
data: GenerateData(10, 50)
}, {
name: "Events",
color: "#EF4B68",
lineWidth: 0,
marker: {
enabled: true,
symbol: "triangle",
radius: 6
},
data: [
[5 * 86400000, 0],
[21 * 86400000, 0]
]
}]
});
});
function GenerateData(min, max) {
var data = [];
for (i = 0; i < (30 * 86400000); i = i + 86400000) {
data.push([i, GetRandomInt(min, max)]);
}
return data;
}
function GetRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
I am not sure if this is a bug or something that I am doing wrong.
The issue here is subtle. It is actually caused by the fact that the tooltip is linked over the top-most series. Since you are creating your linear series first then your non-sequential series the top-most series is the 2 points. So, in order to recapture the 'tooltip` and your crosshair you have to hover closer to the series that is behind the non-sequential series.
Fixes:
Make the non-sequential series the first one you add.
Give an index value to whichever series you want on top that is larger than the least-full series.
I went with option 2:
series: [{
name: 'Line',
index: 1,
data: GenerateData(10, 50)
}, {
name: "Events",
index: 0,
color: "#EF4B68",
lineWidth: 0,
marker: {
enabled: true,
symbol: "triangle",
radius: 6
},
data: [
[5 * 86400000, 0],
[21 * 86400000, 0]
]
}]
Example here.
Looks like a bug in new crosshairs core.
Reported to devs: https://github.com/highslide-software/highcharts.com/issues/2816
Thanks!

highcharts and different yAxis for different categories

I'm trying to use highcharts to draw column chart with the following data:
- I have three categories: apples, oranges, peaches
- I have three data series for it: [1, 10, 100], [2, 9, 120], [1, 11, 150]
As you can see y values for different categories have completely different scales and I would like to show them accordingly. I'd like to show three groups of three columns, like this:
1, 2, 1 --- 10, 9, 11 --- 100, 120, 150
But also make sure first group is not completely squeezed into the ground because of the lower values.
Is it possible with highcharts?
You may want to take a look at the dual-axis chart example. Basically, you just need to make sure that you define your data in separate series, with different y-axes.
var chart = new Highcharts.Chart({
//...
yAxis: [
//your yAxis definitions
],
series: [{
name: "Apples",
yAxis: 0, //the index of the yAxis definition you want to use
data: [1,2,1]
}, {
name: "Oranges",
data: [10,9,11]
}, {
name: "Peaches",
data: [100,120,150]
}]
})

Resources