I have the following chart here:
what I'd like to do is shift the X axis so that the path only reaches the half of the width and the rest is blank (planning to put some plotlines there of some future events) - any ideas how to do it? Cheers :)
To achieve this you simply need to give your x axis a max property.
max: Number
The maximum value of the axis. If null, the max value is automatically calculated. If the endOnTick option is true, the max value might be rounded up.
– xAxis.max - Highstock API
They give a demo of this here: http://jsfiddle.net/gh/get/jquery/2/highcharts/highcharts/tree/master/samples/stock/xaxis/min-max/
In your case, if you're wanting your current data to end half way along the x axis, you need to set the max to the difference between where the data starts and where the data currently ends on top of the point the data currently ends.
As you haven't specified any code yourself, I'm going to use dummy values. If your x axis data starts at 5 and ends at 8, the difference between 5 and 8 is 3, so you need to add that to 8 to offset the chart:
xAxis: {
max: 11 // (8 - 5 + 8)
}
Related
Is there a simple way in current highcharts version of getting the last value in the Y axis?
I already know how to get the highest value with getExtremes(), but I need the last value in the Y axis to feed the last value of a time series into a gauge. Additionaly I would like to calculate current yearly speed and feed it in another gauge, by calculating the difference between the last value and the value exactly one year earlier. Additionally the same as before for an acceleration gauge by calculating the speed difference between the current speed and the speed last year.
I am not sure if you want to get the last yAxis label value or the last point value, but here is an example of how to achieve it:
// last label value
var data = mainChart.yAxis[0].max;
/* // the last point value
var data = mainChart.series[0].points[mainChart.series[0].points.length - 1].y
*/
Demo: https://jsfiddle.net/BlackLabel/1702dogs/
I'm making a c3 chart that has grouped data, and I'd like to have a y-axis grid line that shows a maximum value, that the grouped data combined should not exceed.
So, the y-axis grid line could be called "Maximum"
I know how to make the grid, but it doesn't always show because the grouped data might be way below the grid value. But I want the grid to always show.
I looked at padding for the y-axis, but it's uses pixels and is hard to get accurate.
Is there a away to just set the y-axis to show like 5 values greater than whatever the y-axis grid line is?
Unfortunately, C3 does not have a setting for "set Y axis to maximum of yvalue or largest data". However, let's assume you have added a grid line using a method like below. You can then set the y-axis padding and maximum value using the settings shown here:
grid: {
y: {
lines: [{ value: 20 }],
}
},
axis: {
y: {
padding: {top:5, bottom,0},
max: 20
}
}
In this case I have set the max value to be the same as the gridline value and used padding to create a small space above it. This will handle the case where your data is below the gridline. However, if your data exceeds the (gridline+padding) total then the chart won't grow to accommodate that data because the max setting is fixed. So, you will need to dynamically change this max value using javascript if your data is greater than the max value by finding the maximum value in your data and setting max above that if it exceeds your gridline value, something like this...
if(highValue > gridlineValue)
chart.axis.max(highValue);
else
chart.axis.max(gridlineValue);
I just noticed that your data never exceeds the gridline, so you can go with the first part of this answer. I've left the rest in here in case someone else wants a more dynamic solution. Note that you could also just use the max value without padding if you wanted to set it explicitly to a value higher than the gridline.
As of this writing, there actually is a way to reset the y-max to be dynamic, after setting it to specific max. You do so by setting max to undefined, like so: chart.axis.max(undefined);.
Here, have a working jsfiddle.
I'm using Highstock (v4.2.3) to present data in a StockChart with a number of different Y axes, all plotted against time on the X axis. The data has gaps in it, and I'd like to depict those gaps, but when I turn on gapSize (with any value other than zero), there's a weird quirk that causes line rendering issues--when using the navigator to zoom in on certain date ranges (not all), in some cases (whose pattern I've yet to discern) the chart fails to fully render the line across the entire x axis.
This annotated screenshot depicts the issue.
When I turn gapSize off (or explicitly set it to zero), this problem goes away. Note that the gaps themselves appear correctly on the chart (when navigating to a date range that doesn't present the line rendering issue).
plotOptions: {
series: {gapSize:2}
}
Any ideas?
jsFiddle with your issue:
http://jsfiddle.net/2N52H/109/
As you can read in our API:
http://api.highcharts.com/highstock#plotOptions.line.gapSize
A gap size of 5 means that if the distance between two points is
greater than five times that of the two closest points, the graph will
be broken
As far as I know data you have has random gaps so you will never know what is the distance between two closest points. For example if you will have data in every one hour, distance between two closest points will be 15 minutes and your gapSize will be set to 2, you will see only your closest points.
When you are using zoom sometimes your visible data closest distance is changing so the gaps are changing as well.
See this example:
http://jsfiddle.net/2N52H/111/
Maybe you can use xAxis.ordinal parameter to visualise your gaps:
http://api.highcharts.com/highstock#xAxis.ordinal
You can also change standard functionallity by using wrapper. Here you can read about it:
http://www.highcharts.com/docs/extending-highcharts/extending-highcharts
For example you can change gappedPath function:
(function(H) {
H.wrap(H.Series.prototype, 'gappedPath', function(proceed) {
var gapSize = this.options.gapSize,
xAxis = this.xAxis,
points = this.points.slice(),
i = points.length - 1;
if (gapSize && i > 0) { // #5008
// extension for ordinal breaks
while (i--) {
if (points[i + 1].x - points[i].x > gapSize) {
points.splice( // insert after this one
i + 1,
0, {
isNull: true
}
);
}
}
}
return this.getGraphPath(points);
})
}(Highcharts))
example:
http://jsfiddle.net/2N52H/113/
Kind regards.
We're attempting to display two series of data on the same chart. The first series (ie: number of quotations) can only contain positive integers (and 0). The second series (ie: sales value) can contain both positive and negative float values (in case you're wondering, the negative values result from the issuing of credit notes).
As indicated on the attached image, the problem we're having is that when the second series contains negative values, the 0-point "base line" of the two series of data is no longer shared.
We've tried setting the "min" options of the Y axes to 0, but then we lose out the insight on negative values.
We've also tried setting the min of the first series to be equal to the minimum extreme of the second series, but unfortunately this doesn't scale the columns very nicely (since the values of each Y axis are on completely different scales, ie: 10s vs 1000s).
How can we configure the chart so that the 0-point "base line" is shared? In other words, how would we make the blue columns start at the same base line as the green 0 point?
Update
Linger's answer is a step in the right direction. Setting the min and tickinterval for both axes does the trick. However the values need to be determined dynamically based on variable data, which is where I am now stuck.
Any tips on how these min and tickinterval values can be determined before I generate the chart?
I've done some thinking about it in the mean time. The values associated with the left axis (blue / quotations) are always positive and start from zero. Thus it is the right axis (green / sales) that dictates the number of ticks to show below the zero point. Now since highcharts automatically determines the best scale for both blue and green, all I need to do is find a way to set the left axis' minimum value like so (excuse the pseudo-code):
var factor = right_axis.min / right_axis.tickinterval;
left_axis.min = factor * left.tickinterval;
Note: I have seen the reference API has a setExtremes() method under Axis, but this would require me to first initialise the chart, and then go back and update its left axis. I am hoping to do this before drawing the chart. Perhaps I'm overlooking something obvious?
Thanks.
You can control what you are asking for with a combination of tickInterval and min on the yaxis as demonstrated in this jsfiddle mock up.
EDIT
In your code while reading in the XML you will have to keep track of what the lowest value is and also the highest value on the sales side. Then decide how you want to display those values if they meet a certain value. After that use if statements to set the values. Here is a couple of examples.
Low less than -50 and greater -90
With High less than 400
Primary Axis: min: -2, tickInterval: 1,
Secondary Axis: min: -100, tickInterval: 50
Example
Low less than -50 and greater -90
With High greater than 400
Primary Axis: min: -1, tickInterval: 1,
Secondary Axis: min: min: -100, tickInterval: 100,
Example
To figure out what the min on the Primary Axis should be you simply divide the min on the Secondary Axis by its tickInterval. Then the tickInterval for the Primary Axis would always be 1.
You can also calculate second axis tick positions based on the max series value related to this axis and the first axis ticks positions to get the same amount of ticks and 0 line shared.
Using axis.update() method update tick positions in the second axis using property tickPositions.
Example with a load event. Notice, that when you add points dynamically you have to make those calculations and update tick positions each time your first axis ticks will change:
chart: {
type: 'column',
events: {
load: function() {
var chart = this,
yAxis = this.yAxis,
max = yAxis[1].dataMax,
positiveTicksAmount = 0,
negativeTicksAmount = 0,
tickPositions = [],
tickInterval,
min,
i;
yAxis[0].tickPositions.forEach(function(tick) {
if (tick > 0) {
positiveTicksAmount++;
} else if (tick < 0) {
negativeTicksAmount++;
}
});
tickInterval = max / positiveTicksAmount;
for (i = negativeTicksAmount; i > 0; i--) {
tickPositions.push(-tickInterval * i);
}
for (i = 0; i <= positiveTicksAmount; i++) {
tickPositions.push(
tickInterval * i
);
}
yAxis[1].update({
tickPositions: tickPositions
});
}
}
},
Jsfiddle examples:
https://jsfiddle.net/wchmiel/84q0sxrt/
http://jsfiddle.net/wchmiel/nuj7fagh/
Api reference:
https://api.highcharts.com/class-reference/Highcharts.Axis#update
https://api.highcharts.com/highcharts/yAxis.tickPositions
I'm making a simple JavaScript graphing library using the canvas element. I really suck at math so I'm stuck with a simple issue.
If I have a number - for example 30000, and I want to plot it relatively to graph's height which is 400. How do I calculate the y value for that?
You would want to figure out your max for the graph. Say, in this case 50000. Then, take your height and divide it by the max (so 400/50000) to get a ratio multiplier. Any number you want to plot you multiply by that ratio and that should give you a number that fits on your space. Is that what you're asking for?
For that you need to first find out the maximum and minimum values that you need to plot. For example, in this list of (x,y) coordinates: [(1,3),(2,10),(3,0),(4,-10)], the max value is 10 and the min value is -10. This gives you a span of (max-min = 10-(-10) = ) 20.
Notice that you can now translate the set of y values into a number in the range [0,max-min] (i.e. [0,20] in this case). Here, a value of 0 will get plotted as a 0 in the graph and a value of 20 will get plotted as 400. Also, a value of 20/2 will be plotted as 400/2. Thus, a value of 20/x is plotted as 400/x. This means that any value can now be plotted as 400*value/20.
So, to translate a given value n to its corresponding y value on the graph, simply convert n to (n-min)*400/(max-min).