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.
Related
I want to put some images as SVG on each point in Gantt chart, I've tried something like below:
function (chartt) { // on complete
chartt.renderer.image('imageURL.png',100,100,30,30)
.add();
}
But after running this code, the image will be shown on the corner of the page. I want to draw images on each point in the chart and set their position related to its point.
Live Demo: https://jsfiddle.net/meysamm22/x41wdu5z/
You need to use the right x and y attributes, calculate them based on plotX and plotY point's properties:
function(chartt) { // on complete
var points = chartt.series[0].points,
width = 30,
height = 30;
points.forEach(function(point) {
chartt.renderer.image(
'https://www.highcharts.com/images/employees2014/Torstein.jpg',
point.plotX + chartt.plotLeft + point.shapeArgs.width / 2 - width / 2,
point.plotY + chartt.plotTop - height / 2,
width,
height
)
.attr({
zIndex: 5
})
.add();
});
});
Live demo: https://jsfiddle.net/BlackLabel/r4ph3ykz/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#image
I would like bar width equal to 30 pixels.
barData.barWidth let me change it but this is proportional to chart width and number of bars to display, which display a big bar on iPad for only one element.
Do you have an idea?
Thanks.
You Can not fix BarSize directly in ios-charts but you can change the default ratio width of the bar.
By default barWidth ratio is 0.85 so based on this it will cover 85% area of the chart if you have only 1 Bar on the chart and if you have 2 it will calculate the ratio based on Bar count so you can set approximate bar width with this property.
Default value:
/// **default**: 0.85
open var barWidth = Double(0.85)
You can set:
let chartData = BarChartData(dataSet: chartDataSet)
chartData.barWidth = Double(0.01)
chartData.barWidth = Double(0.10)
chartData.barWidth = Double(0.25)
chartData.barWidth = Double(0.30)
chartData.barWidth = Double(0.50)
like that you will achieve your fix width between 0.01 to 1.00.
Hope this will helps!
Assuming chart width is fixed:
step 1: find the ratio for required width in scenario where there is only one element on x-axis (for me it was 0.05)
step 2: set the bar width to this ratio multiplied by element count on x-axis
data.barWidth = 0.05 * Double(xArray.count)
This will work because max width for a single bar is inversely proportional to number of elements on x-axis
For variable chart width you will need an additional factor for bar width correction: (original chart width/current chart width)
You can add a chartView to the scrollView, then set the chartView.widthand scrollView.contentsize
width = values.count * fixedWidth
chartView.width = width
and
scrollView.contentSize = {width,scrollView.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.
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);
I want to show the tooltip on the right side of the cursor.
I looked in the documentation/examples but I can't find a way to force the tooltips to stay on the right side of the cursor.
Can anyone tell me how to do it?
With tooltip positioner I only can set a default position.
Tooltip positioner is much more than just default position. The function arguments contain info about your point position & tooltip dimensions, using which it should be fairly simple to position it to the right.
Highchart/stock allows you to define your alternate positioner as follows
tooltip:{
positioner:function(boxWidth, boxHeight, point){
...
}
}
Note that you have three arguments (boxWidth, boxHeight, point) at your disposal, these seem to be sufficient for most of the use cases to calculate a desired tooltip position. boxWidth and boxHeight are the width and height that your tooltip will require, hence you can use them for edge cases to adjust your tooltip and prevent it from spilling out of the chart or even worse getting clipped.
The default tooltip positioner that comes with highstock is as follows (Source)
/**
* Place the tooltip in a chart without spilling over
* and not covering the point it self.
*/
getPosition: function (boxWidth, boxHeight, point) {
// Set up the variables
var chart = this.chart,
plotLeft = chart.plotLeft,
plotTop = chart.plotTop,
plotWidth = chart.plotWidth,
plotHeight = chart.plotHeight,
distance = pick(this.options.distance, 12), // You can use a number directly here, as you may not be able to use pick, as its an internal highchart function
pointX = point.plotX,
pointY = point.plotY,
x = pointX + plotLeft + (chart.inverted ? distance : -boxWidth - distance),
y = pointY - boxHeight + plotTop + 15, // 15 means the point is 15 pixels up from the bottom of the tooltip
alignedRight;
// It is too far to the left, adjust it
if (x < 7) {
x = plotLeft + pointX + distance;
}
// Test to see if the tooltip is too far to the right,
// if it is, move it back to be inside and then up to not cover the point.
if ((x + boxWidth) > (plotLeft + plotWidth)) {
x -= (x + boxWidth) - (plotLeft + plotWidth);
y = pointY - boxHeight + plotTop - distance;
alignedRight = true;
}
// If it is now above the plot area, align it to the top of the plot area
if (y < plotTop + 5) {
y = plotTop + 5;
// If the tooltip is still covering the point, move it below instead
if (alignedRight && pointY >= y && pointY <= (y + boxHeight)) {
y = pointY + plotTop + distance; // below
}
}
// Now if the tooltip is below the chart, move it up. It's better to cover the
// point than to disappear outside the chart. #834.
if (y + boxHeight > plotTop + plotHeight) {
y = mathMax(plotTop, plotTop + plotHeight - boxHeight - distance); // below
}
return {x: x, y: y};
}
With all the above information, I think you have sufficient tools to implement your requirement by simply modifying the function to make float to right instead of the default left.
I will go ahead and give you the simplest implementation of positioning tooltip to right, you should be able to implement the edge cases based on the aftermentioned default tooltip positioner's code
tooltip: {
positioner: function(boxWidth, boxHeight, point) {
return {x:point.plotX + 20,y:point.plotY};
}
}
Read more # Customizing Highcharts - Tooltip positioning
The better solution to get your tooltip always on the right side of the cursor is the following:
function (labelWidth, labelHeight, point) {
return {
x: point.plotX + labelWidth / 2 + 20,
y: point.plotY + labelHeight / 2
};
}