0

Good morning, I'm facing this problem using HighCharts in an angular application. We are trying to draw a graph which is supposed to be changing over time, but at the beggining it's flat, you can take this as an example: https://highcharts-angular-basic-line-y7uwai.stackblitz.io

as you can see when the graph is flatten the line isn't drawn using a linear gradient. Why is this happening? Is it because when there isn't any progression no linear gradient can be drawn?

What's even stranger is that when I don't use the types offered by the library and I insert an object as any type in the highchart component it seems to work when setting the linearGradient as an array:

color: {
    linearGradient: [0,0,0,300],
    stops: [
        [0, "#66CC00"],
        [1, "#cc0019"],
    ],
}
      

enter image description here

any help with this is highly appreciated.

1 Answers1

1

This is a direct issue in the engines we can not fix: https://github.com/highcharts/highcharts/issues/1677 (reported as radial gradient, but it's a general issue with gradients).

As you noticed, defining gradient as an array don't cause such an issue. It is because start/end positions are differently calculated in that case - they have to be declared as pixels on the chart, not as a range of 0 to 1 as in the case of gradient defined as an object.

Based on the following example, 400 means 400px:

Highcharts.chart('container', {
  series: [{
    type: 'line',
    color: {
      linearGradient: [0, 0, 400, 0], // x1: 0, y1: 0, x2: 400, y2: 0
      stops: [
        [0, '#ff0000'],
        [1, '#0000ff']
      ]
    },
    data: [1, 1, 1, 1]
  }]
});

It is possible to use linear gradients defined as an object, but it needs of overwriting the default gradientUnits to the userSpaceOnUse - which will represent values as pixels as well.

import { Component } from '@angular/core';
import * as Highcharts from 'highcharts';

interface LinearGradientColorObject {
  x1: number;
  y1: number;
  x2: number;
  y2: number;
  gradientUnits: string;
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  Highcharts: typeof Highcharts = Highcharts;

  chartOptions: Highcharts.Options = {
    series: [
      {
        type: 'line',
        color: {
          linearGradient: {
            x1: 0,
            y1: 0,
            x2: 400,
            y2: 0,
            gradientUnits: 'userSpaceOnUse',
          } as LinearGradientColorObject,

          stops: [
            [0, '#ff0000'],
            [1, '#0000ff'],
          ],
        },
        data: [1, 1, 1, 1],
      },
    ],
  };
}

Demo TS: https://stackblitz.com/edit/highcharts-angular-line-1qpecs?file=src%2Fapp%2Fapp.component.ts

Demo JS: https://jsfiddle.net/BlackLabel/p4y1br2e/

Article about colors in Highcharts:

https://www.highcharts.com/docs/chart-design-and-style/colors

magdalena
  • 2,657
  • 1
  • 7
  • 12
  • Thanks a lot magdalena, I'll tell my team about this. Have a nice day! – victor garcia exposito Mar 21 '23 at 08:01
  • Now that I think about it, could you change the type of the property linearGradient to take an array of 4 positions as a type? When you use that method with typescript you get an error that says that the type is not assignable to GradientColorObject, maybe you can declare it as GradientColorObject | [a:number, b:number, c:number, d:number] – victor garcia exposito Mar 21 '23 at 10:03
  • Actually, it is possible to use it as an object. Since the problem is caused by the default `gradientUnits` for linear gradients defined as an object, we can just overwrite it. I edited the post with a second solution – magdalena Mar 21 '23 at 13:16