Search code examples
javascripttexthighchartsheightspacing

Highcharts: Adjust size of chart-container based on elements within container


When generating Highcharts, I wish to include a string of text in the highcharts-container, so that the text is included in the downloadable image. The problem is that, the amount of text might be changed (and not by me), meaning that the space I reserve for the text might be too small or awkwardly large in the future. My wish is to not have to manually check if the properties of a chart have to be updated each time the text is changed.

My Highcharts-code might look like this (Note: Actual data is unnecessary for this example):

<script type="text/javascript">
var chart = new Highcharts.chart({
    chart: {
        type: 'spline',
        width: 600,
        spacingBottom: 100,
        renderTo: 'chart-container'
    },
    title: {
        text: 'Total number of something from 2000-2010',
        align: 'left'
    },
    subtitle: {
        text: 'Source: Some Source Inc.<br>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
        align: 'left',
        verticalAlign: 'bottom'
    },
    legend: {
        enabled: false
    }
})
</script>
<style>
.highcharts-container {
    border: 2px solid #CCC;
    padding: 10px;
}
text { font-family: Helvetica; }
</style>

In this example, I've made the subtitle-element home to my additional text and set chart.spacingBottom to 100, which makes for comfortable spacing for the amount of text in the subtitle. However, if the amount of text increases, so that the height of the subtitle element is larger than spacingBottom, the trailing text will simply disappear behind the border of the chart-container. The container doesn't appear to pay any mind to any element besides the chart itself, and chart.spacingBottom defaults to 15 if not defined.

What I want to do is to somehow dynamically set chart.spacingBottom (and/or chart.height) depending on the rendered height of the subtitle element, but for some reason, neither pure JS or jQuery seems to be able to get the height of any element in the highcharts-container.

console.log(document.getElementsByClassName("highcharts-subtitle").offsetHeight); returns undefined

$(".highcharts-subtitle").height(); returns integer 0.

I've also tried to include the text by using chart.renderer.text and chart.renderer.label instead of just hijacking the subtitle-element. Getting the height from any of those elements produces the same results, and I've ended up wanting to use subtitle simply because it's less of a hassle to get the placement correct. I'm open to suggestions however.

Any tips or methods that I'm overlooking that should allow me to dynamically change the properties of the chart?


Solution

  • Using getBBox() is the answer to this question, as suggested in the comments.

    You should be able to use getBBox() method for preparing your chart: jsfiddle.net/BlackLabel/oteewvss/4Grzegorz Blachliński

    Another example within events:

    var chart = new Highcharts.chart({
        chart: {
            type: 'spline',
            width: 600,
            renderTo: 'chart-container',
            events: {
                load: function() {
                    this.update({
                        chart: {
                            spacingBottom: this.subtitle.element.getBBox().height
                        }
                    });
                }
            }
        },
        title: {
            text: 'Total number of something from 2000-2010',
            align: 'left'
        },
        subtitle: {
            text: 'Source: Some Source Inc.<br>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
            align: 'left',
            verticalAlign: 'bottom'
        }
    });
    

    Some other useful elements that one can get hold of via the chart element:

    Height of x-axis labels: chart.xAxis[0].labelGroup.element.getBBox().height
    Height of legend: chart.legend.legendHeight