Rodolfo
Rodolfo

Reputation: 338

Highcharts Angular - How to set chart width and height with percentages?

I'm trying to set chart width and height according to the space around it. The chart is currently in a modal and I would like it to occupy the entire space. In order to do that I would need the width and height to be set with percentages but I'm not able to do that. The chart size seems to be set to a default value that can't be changed unless I do it in the options of the chart like this:

chartOptions: Options = {
    title: {
      text: 'CDF of the most frequent update frequency',
      style: {
        color: 'whitesmoke'
      }
    },
    chart: {
      zoomType: 'x',
      backgroundColor: {
            linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
            stops: [
                [0, '#2a2a2b'],
                [1, '#3e3e40']
            ]
        },
      borderColor: 'black',
      borderWidth: 2,
      width: 1000,
      height: 500
    },

This allows me to only set the size with pixels and that's not what I need. This is how the html page is set up:

<h4 mat-dialog-title>
        <mat-toolbar class="task-header">
            <span class="titolo">Most Frequent Update Frequency CDF</span>
            <button mat-icon-button mat-dialog-close class="icona">
                <mat-icon mat-list-icon>close</mat-icon>
            </button>
        </mat-toolbar>
</h4>
<mat-dialog-content>
  <highcharts-chart [Highcharts]="Highcharts" [options]="chartOptions"></highcharts-chart>
</mat-dialog-content>


Upvotes: 0

Views: 3645

Answers (1)

tao
tao

Reputation: 90113

Remove both width and height from highchart's chart config object. They both default to null and here's the behavior (taken from documentation):

  • height: By default (when null) the height is calculated from the offset height of the containing element, or 400 pixels if the containing element's height is 0.
  • width: By default (when null) the width is calculated from the offset width of the containing element.

The only thing left to do is to set explicit height and width on the containing <mat-dialog-content>. Here's why they need to be explicit:

  • by default, the MatDialog component is trying to render as small as possible, but enough to fit the content.
  • Highcharts, on the other hand, is trying to grow into the available space.

So we have a parent trying to shrink down on the child and a child trying to grow into the parent.
Meaning: you need to provide explicit sizes to MatDialog, or the parent will shrink on the child and the child won't have space to grow in (actually, there is a min-width on the dialog and the chart also defaults the height to 400px when it detects a 0 height - to counter the shrinking parents).

Probably the most convenient way to set explicit sizes on the dialog is by placing a custom class on this particular MatDialog instance, using panelClass option in the second param of .open(). e.g:

const dialogRef = this.dialog.open(HighchartsDialogComponent, {
  panelClass: 'highcharts-modal'
});

Now you could use CSS to set the explicit size of the modal: e.g:

.cdk-overlay-pane.highcharts-modal {
   /*
    use any valid CSS explicit sizing: %, px, em, vw,...
    don't use `auto` (not explicit - will result into `0`)
    */
   width: 80vw;
   height: 80vh;
}

Side note: by default, .cdk-overlay-pane injects some inline styles, among which a max-width: 80vw;. If you want your chart to be wider than that, you'll have to override it using !important from CSS.

Another side note: MatDialog provides options to set height and width via config (where we specified panelClass). If set, they are passed as inline styles to the same panel element.

I prefer my CSS in stylesheets, not in config options, as it comes with the added benefit of allowing @media queries. But if you prefer the config, it works as well.

Upvotes: 2

Related Questions