Sagar Rabadiya
Sagar Rabadiya

Reputation: 4321

Highcharts with range out of bound value highlight with different color

enter image description here

I want to highlight this kind of range whose value goes out side of areaspline range.

I tried using zones (zones can't work here as I need to find mid intersection point) and custom rendered but I am not able to detect the mid point of the range and line series intersection point,

Is there any options for clipping series on each other in highcharts? I can have 2 series on top of each other but only problem is I can't use zIndex as it will move entire series on top of each other which I don't want

for example this is data and fiddle which I want to highlight points that are not in range but it should be accurate on xaxis and yaxis without looking 2 different series

var ranges = [
        [1246406400000, 14.3, 27.7],
        [1246492800000, 14.5, 27.8],
        [1246579200000, 15.5, 29.6],
        [1246665600000, 16.7, 30.7],
        [1246752000000, 16.5, 25.0],
        [1246838400000, 17.8, 25.7],
        [1246924800000, 13.5, 24.8],
        [1247011200000, 10.5, 21.4],
        [1247097600000, 9.2, 23.8],
        [1247184000000, 11.6, 21.8],
        [1247270400000, 10.7, 23.7],
        [1247356800000, 11.0, 23.3],
        [1247443200000, 11.6, 23.7],
        [1247529600000, 11.8, 20.7],
        [1247616000000, 12.6, 22.4],
        [1247702400000, 13.6, 19.6],
        [1247788800000, 11.4, 22.6],
        [1247875200000, 13.2, 25.0],
        [1247961600000, 14.2, 21.6],
        [1248048000000, 13.1, 17.1],
        [1248134400000, 12.2, 15.5],
        [1248220800000, 12.0, 20.8],
        [1248307200000, 12.0, 17.1],
        [1248393600000, 12.7, 18.3],
        [1248480000000, 12.4, 19.4],
        [1248566400000, 12.6, 19.9],
        [1248652800000, 11.9, 20.2],
        [1248739200000, 11.0, 19.3],
        [1248825600000, 10.8, 17.8],
        [1248912000000, 11.8, 18.5],
        [1248998400000, 10.8, 16.1]
    ],
    averages = [
        [1246406400000, 35],
        [1246492800000, 12],
        [1246579200000, 23],
        [1246665600000, 23.8],
        [1246752000000, 21.4],
        [1246838400000, 21.3],
        [1246924800000, 18.3],
        [1247011200000, 15.4],
        [1247097600000, 16.4],
        [1247184000000, 80],
        [1247270400000, 17.5],
        [1247356800000, 17.6],
        [1247443200000, 17.7],
        [1247529600000, 16.8],
        [1247616000000, 17.7],
        [1247702400000, 16.3],
        [1247788800000, 5],
        [1247875200000, 18.1],
        [1247961600000, 17.2],
        [1248048000000, 14.4],
        [1248134400000, 13.7],
        [1248220800000, 15.7],
        [1248307200000, 14.6],
        [1248393600000, 15.3],
        [1248480000000, 15.3],
        [1248566400000, 15.8],
        [1248652800000, 15.2],
        [1248739200000, 14.8],
        [1248825600000, 60],
        [1248912000000, 15],
        [1248998400000, 13.6]
    ];


Highcharts.chart('container', {

    title: {
        text: 'July temperatures'
    },

    xAxis: {
        type: 'datetime',
        accessibility: {
            rangeDescription: 'Range: Jul 1st 2009 to Jul 31st 2009.'
        }
    },

    yAxis: {
        title: {
            text: null
        }
    },

    tooltip: {
        crosshairs: true,
        shared: true,
        valueSuffix: '°C'
    },

    series: [{
        name: 'Temperature',
        data: averages,
        zIndex: 1,
        marker: {
            fillColor: 'white',
            lineWidth: 2,
            lineColor: Highcharts.getOptions().colors[0]
        }
    }, {
        name: 'Range',
        data: ranges,
        type: 'arearange',
        lineWidth: 0,
        linkedTo: ':previous',
        color: Highcharts.getOptions().colors[0],
        fillOpacity: 0.3,
        zIndex: 0,
        marker: {
            enabled: false
        }
    }]
});

check this fiddle

Upvotes: 2

Views: 363

Answers (1)

Sagar Rabadiya
Sagar Rabadiya

Reputation: 4321

in case some one is wondering how to achieve that I have achieved it using mask applied to svg something like

const lineSeries = this.series[1];
  if (lineSeries) {
    const areaSeries = this.series[2];

    const renderer = areaSeries.group.renderer;
    const existingGroup = renderer.boxWrapper.element.getElementById(
      lineSeries.options.guid
    );
    if (existingGroup) {
      existingGroup.remove();
    }
    const group = renderer.g().add();
    group.element.id = lineSeries.options.guid;

    const clipPath = renderer.createElement("mask");

    clipPath.element.id = `mask-${lineSeries.options.guid}`;
    renderer
      .createElement("rect")
      .attr("height", this.clipBox.height)
      .attr("width", this.clipBox.width)
      .attr("x", this.clipBox.x)
      .attr("y", this.clipBox.y)
      .attr("fill", "white")
      .add(clipPath);
    renderer
      .createElement("path")
      .attr("fill", "black")
      .attr("d", areaSeries.area.element.getAttribute("d"))
      .add(clipPath);

    clipPath.add(group);
    lineSeries.group.element.setAttribute(
      "mask",
      `url(#mask-${lineSeries.options.guid})`
    );
    lineSeries.group.element.childNodes[0].setAttribute(
      "mask",
      `url(#mask-${lineSeries.options.guid})`
    );
  }

here is updated js fiddle https://jsfiddle.net/samcoolone70/p5s981td/

Upvotes: 1

Related Questions