I have two highcharts on my page. A bar graph and a column graph. The column graph xaxis has 50 categories. The bar graph yaxis also has 50 categories. When i zoom in on the column graph the yaxis of the bar graph does not zoom the same way.
I figured out that it had to do with the value zooming gives. So is there a way to convert the xaxis extremes tot yaxis extremes so that my zoomin wil be the same on both graphs?
This is how i set the extremes:
events: {
selection: function (event) {
var xMin;
var yMin;
var xMax;
var yMax;
if (event.xAxis) {
xMin = event.xAxis[0].min;
xMax = event.xAxis[0].max;
yMin = xMin;
yMax = xMax;
if (incomeChart != undefined)
incomeChart.xAxis[0].setExtremes(xMin, xMax, true);
if (timeLine != undefined)
timeLine.yAxis[0].setExtremes(xMin, xMax, true);
Related
I have created a line chart in Google Sheets using data pulled from an API. The data changes every hour, so the min and max values of the data to chart also changes.
I would like to know if there is a script that can lookup up min and max from a column of data and use those values to dynamically set min/max for the Y axis.
Currently the only way I can see to change Y axis min max is manually in the chart editor, but the inputs only accept numbers, not formulas, so the min max is rigid.
// Only applies to first y axis
// Only applies to charts on active spreadsheet
// Allows for multiple series
// Takes approx 3 seconds per 10 charts to run
// Change Sheet1 for your sheet name
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1')
var config = {
// y-axis max is this factor higher than your chart's max value
// For example if your max value is 100 and scaleUpBuffer is 0.1,
// the y-axis max value will be set to 100 * (1 + 0.1) = 110
scaleUpBuffer: 0.0001,
// y-axis min is this factor lower than your chart's min value
scaleDownBuffer: 0.0001,
// If / when google fix goes through,
// set this to true and run fixCharts() to get default scaling back
// This sets min and max y axis values to null (the default)
restoreDefault: false,
}
function fixCharts() {
var minMaxY1;
sheet.getCharts().forEach(function (chart) {
minMaxY1 = config.restoreDefault ? [null, null] : getChartMinMaxY(chart, config);
updatedChart = chart
.modify()
.setOption('vAxes', {0: {viewWindow: {min: minMaxY1[0], max: minMaxY1[1]}}})
.build();
sheet.updateChart(updatedChart);
})
}
function getChartMinMaxY(chart, config) {
var chartRangeArray,
y1 = [];
chart.getRanges().forEach(function(chartRange) {
chartRangeArray = chartRange.getValues();
chartRangeArray.forEach(function(row) {
for (var i=1;i<row.length;i++) {
// loops all series, assumes all on 1st y axis
if (typeof row[i] == 'number') {
// ignores blanks, headers, junk strings etc.
y1.push(row[i]);
}
}
});
});
return [
Math.min.apply(null, y1) * (1 - config.scaleDownBuffer),
Math.max.apply(null, y1) * (1 + config.scaleUpBuffer)
];
}
To preface, I am using the extended logarithm functions for negative and small numbers here:
/**
* Custom Axis extension to allow emulation of negative values on a
logarithmic
* Y axis. Note that the scale is not mathematically correct, as a true
* logarithmic axis never reaches or crosses zero.
*/
(function (H) {
// Pass error messages
H.Axis.prototype.allowNegativeLog = true;
// Override conversions
H.Axis.prototype.log2lin = function (num) {
var isNegative = num < 0,
adjustedNum = Math.abs(num),
result;
if (adjustedNum < 10) {
console.log('adjustedNum: ', adjustedNum);
adjustedNum += (10 - adjustedNum) / 10;
}
result = Math.log(adjustedNum) / Math.LN10;
if (adjustedNum < 10) console.log('result: ', result);
return isNegative ? -result : result;
};
H.Axis.prototype.lin2log = function (num) {
var isNegative = num < 0,
absNum = Math.abs(num),
result = Math.pow(10, absNum);
if (result < 10) {
result = (10 * (result - 1)) / (10 - 1);
}
return isNegative ? -result : result;
};
}(Highcharts));
So if I have a y-axis with a dataMin of 0.22 and a dataMax of 2.34 using a log scale, the only ticks I get back are [0,1] designating 0 and 10, the bottom and top of the chart, with no tick marks in between.
1) Is there a way I can specify how many ticks I want in a log chart (tickAmount: 5 would not work)?
2) Is there a way I can tighten the range over which ticks fall? (like in this case, it sets the axis with data values between 0 and 10 even though my data series only falls between 0.22 and 2.34).
Thanks!
1.
tickPositions and tickPositioner options allow you to control where exactly the ticks will fall.
2.
You can try adjusting the tickInterval option: http://jsfiddle.net/BlackLabel/8v3xuyot/
yAxis: {
type: 'logarithmic',
tickInterval: 0.2
}
API references:
https://api.highcharts.com/highcharts/yAxis.tickInterval
https://api.highcharts.com/highcharts/yAxis.tickPositioner
https://api.highcharts.com/highcharts/yAxis.tickPositions
I HV multi line chart, I want the shared tooltip to be at the top of the graph ( so that it doesn't covers up the space of graph) , but I want it to have fixed 'y'
And x coordinate to be Free.
So that user can hover over the graph and the tooltip comes at the top of that point ( x coordinate).
Is there a way where I can fix only the y coordinate of the tooltip position?
You can use the tooltip.positioner function. http://api.highcharts.com/highcharts/tooltip.positioner
tooltip: {
positioner: function (labelWidth, labelHeight, point) {
return { x: point.plotX, y: 15 };
},
shadow: false,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.8)'
},
http://jsfiddle.net/nt9x5tjj/
The callback receives a point object that contains plotX and plotY positions. Fix the y value to some number and return point.plotX as the x value.
How can I calculate the height of a bar chart so that for different number of bars, highcharts always use the same height for a single bar. Without setting any height the size of the bars are to large for a minor number and to thin and missing labels for larger number of bars.
You can do it by dynamic change of height of your chart in dependence on your data length.
http://api.highcharts.com/highcharts#chart.height
chart: {
marginTop: 40,
marginBottom: 80,
height: data.length * 20 + 120 // 20px per data item plus top and bottom margins
}
jsFiddle made by Torstein Hønsi:
http://jsfiddle.net/highcharts/jMX8G/
Similar Topic:
https://highcharts.uservoice.com/forums/55896-highcharts-javascript-api/suggestions/3456724-size-height-of-bar-graph-based-on-contents-when-co
You can also see custom function I wrote. Inside it I am iterating over all of my series data and making a sum of all visible data. Then I am setting the height of my chart with width of my column (passed in function parameter), number of columns, marginBottom and plotTop of my chart.
at the end if this size is different than previous size of chart I am setting new size of chart with Chart.setSize():
http://api.highcharts.com/highcharts#Chart.setSize
example:
http://jsfiddle.net/izothep/d3ezek8t/1/
I have a similar set up that I use, I will post here for posterity:
http://jsfiddle.net/jlbriggs/kpu5d1qf/
Uses a set of variables to define the chart/bar sizing parameters, and works from there.
//count the data points
var barCount = chartData.length;
//specify chart properties that will be used to calculate the total height
var pointWidth = 20;
var marginTop = 60;
var marginRight = 10;
var marginBottom = 50;
var marginLeft = 100;
var groupPadding = 0;
var pointPadding = 0.3;
var chartHeight = marginTop
+ marginBottom
+ ((pointWidth * barCount) * (1 + groupPadding + pointPadding));
And in the chart options, for example:
chart: {
type : 'bar',
marginTop : marginTop,
marginRight : marginRight,
marginBottom : marginBottom,
marginLeft : marginLeft,
height : chartHeight
},
So you can edit all of the properties that might affect the height of the chart outside of the chart options, and all are accounted for when calculating the final height.
I want to enforce that the axis of my bubble chart to starts at 0. In any other chart type I would set
yAxis: {
min:0
}
But this can cause bubbles with an y value near zero to be clipped.
All I could come up with so far is to add an invisible dummy series to force the axis to start at 0.
See http://jsfiddle.net/kzoon/jd3c9/ for my problem and workaround.
Has anyone a better solution to this problem?
How about using tick positioner? It allows you to programmatically set tick positions. Take a look into the docs: http://api.highcharts.com/highcharts#yAxis.tickPositioner
Sample function can work like this:
Find axis min and max values
If min is greater than 0, use 0 as min:
Add ticks every "20" unless we achieve max value
Here you can find the code:
yAxis: {
tickPositioner: function () {
var positions = [],
min = Math.floor(this.min / 10) * 10,
max = Math.ceil(this.max / 10) * 10,
step = 20,
tick;
if (min > 0)
min = 0;
tick = min;
while (tick < max + step) {
positions.push(tick);
tick += step;
}
return positions;
}
},
and working demo on jsfiddle: http://jsfiddle.net/2ABFW/
You can use startWithTick: http://jsfiddle.net/jd3c9/8/
yAxis: {
startWithTick: true
}
Now your y-axis will display the next tick under 0 (-20 in this case) and no bubble will be clipped.