how to make a div match a dynamically created google chart height
Asked Answered
E

3

14

I have a page that dynamically loads a google timeline chart onto a div. The timeline increases in height as you add items on to it. If the chart is smaller than the div, it will be visible with empty space at the bottom. If the chart is larger, it will show scrollbars on the side.

What I would like is for the container div to always show the full chart or, another way, I would like the container div height to dynamically match the height of the chart.

I have tried to approximate the average size of each chart line and then adjust the div height when I load the chart with:

$("#gantt_chart").height(data['num_contents']*46);

But, although that somehow works, it's far from perfect because the approximation on height starts to accumulate with each additional line and the empty space at the bottom of the div increases which is not an elegant solution at all.

How would I ensure that the container div always shows the full chart?

I hope this is clear enough.

Many thanks.

Excel answered 30/5, 2014 at 11:13 Comment(4)
is that jquery? you may want to add the tag to the question if it isResumption
Added jquery tag. thank you for the recommendation.Excel
on the css change the div height to height: auto; so it will automatically resize the height.Franek
Many thanks for the pointers. Adding $('#container_div').css('height','auto'); after the chart is drawn is not helping. Adding style="height:auto;" to the div when the page is loaded also did not help.Excel
C
16

The chart determines its height by either checking the height option passed into the draw call, or by checking the container height if the height option is not specified. I would suggest using the option instead of changing the div height via jQuery. I find the best method for dynamically calculating the chart height is to take the height of a row (typically 41px) times the number of rows, plus some padding for the top and bottom:

var height = data.getNumberOfRows() * 41 + 30;
Cottingham answered 31/5, 2014 at 23:48 Comment(5)
Thank you. After hours investigating, this is the most effective solution I could find.Excel
Some time ago, but I was wondering how this works if a row spans multiple lines. Are you still working with Google charts? Any idea maybe?Femininity
It's been a few years since I've used the Visualization API, so I am a bit rusty with it. Are you referring to the case where you have multiple rows in the DataTable that are rendered onto one row in the chart (like a Timeline chart)? If so, I believe you can group the data in your DataTable with the google.visualization.data.group method (by the first column, in the case of a timeline chart) to get the number of rendered rows.Cottingham
Great solution! I used that for the Google Gantt Chart. But I saw that the height of the row of the Gantt is 42, not 41. Thanks anyway!Orola
I was switching a project from Plotly to GoogleCharts in the hope that this dynamic height option would be easier. I ended up just using your idea and updated the height item in the plotly layout object and it worked for me as well. ThanksPuppy
A
3

Though in the doc they have shown to adjust height of div from where we are specifying the id of timeline but I recommend you to have set the height from the internal method.

// set the height for padding(padding height)
var pH = 40;

// get total height of rows (row height)
var rH = dataTable.getNumberOfRows() * 15;

// total chart height (chart height)
var cH = rH + pH;

// Now set this chart height to the timeline via option object
// apart from height, other attributes are just optional
var options = {
   height: chartHeight,
   colors: ['#339900', '#e6e600', '#B00000'],
   tooltip: {
        isHtml: true
   },
   timeline: {
        colorByRowLabel: false
   },
   avoidOverlappingGridLines: true
};
Agler answered 10/5, 2016 at 5:43 Comment(0)
B
0

Been trying to do the same thing myself. The top answer wasn’t exactly right and caused an inner scroll bar to appear at times.

Here’s what worked for me:

var barLabelFontSize = 12;                                          //default font size for bar labels
try{barLabelFontSize = options.timeline.barLabelStyle.fontSize;     //bar height is dependent on the bar label's font size that you set...
}catch(e){}
var barHeight = barLabelFontSize * 1.196;                           //found in google api as: this.PU = 1.916 * this.UF.fontSize;
var barMargin = barLabelFontSize * 0.75;                            //found in google api as: this.Rfa = .75 * this.UF.fontSize;
var rowHeight = barHeight + barMargin * 2;                          //found in google api as: b.height = 2 * this.Rfa + this.PU (+additional complication for grouped bars, if anyone wants to try work that out it was: b.height = 2 * this.Rfa + this.PU * a.SI.length + this.Qfa * (a.SI.length - 1); (where Qfa is 0.583 * font size, and a.SI.length is the number of grouped bars displayed on the row) 
var chartAreaHeight = rowHeight * dataTable.getNumberOfRows();
var axisHeight = 24;                                                //worked out by querying: document.getElementById('timelineChart') getElementsByTagName('svg')[0].getBBox().height;
var whiteSpaceHeight = 28;                                          //trail-and-error to find how much whitespace was required to stop a scroll bar appearing, 27 works too, but I rounded up to play it safe
var chartHeight = chartAreaHeight + axisHeight + whiteSpaceHeight;

You can also reverse engineer this to set the height of the bars using the bar label font size.

Belike answered 2/10, 2017 at 14:53 Comment(1)
I gave up on trying to achieve a dynamic one and settled for fixed category sizes (week, month etc). I do however have on thing to add to your answer which can improve it slightly. Your solution won't work when you have more than one bar per row as the .getNumberOfRows counts all of the rows in the dataTable, not the rows in the actual graph. dataTable.getDistinctValues(0).length This will do it if you have the label string in the first element of the array.Acrodrome

© 2022 - 2024 — McMap. All rights reserved.