Search code examples
javascripthighchartshighcharts-ng

How to display last data point value in a tag on Y Axis in line chart of highChartjs


I want to print end point value of chart as colorful tag like following image: enter image description here

and i'm tried as following methods : Solution 1 was successful on candlestick chart but couldn't work on line chart :

Solution 1(JsFiddle):

   $(function() {
      const drawLabel = function() {
        const chart = this
        const renderer = this.renderer
        const pathStr = 'M0 12 L12 0 L64 0 L64 24 L12 24 Z'
        const path = pathStr.split(' ')
        const colors = Highcharts.getOptions().colors
        console.log(this.series)
        const points = this.series[0].groupedData
        const lastPoint = points[points.length - 1]

        // Delete old paths
        //console.log(chart.labelBg, chart.labelTxt)
        !chart.labelBg && (chart.labelBg = renderer.path(path))
        !chart.labelTxt && (chart.labelTxt = renderer.text(lastPoint.high))

        // Create new label path
        chart.labelBg
          .attr({ zIndex: 1, fill: colors[2] })
          .translate(570, lastPoint.plotClose + 65)
          .add()
        chart.labelTxt
          .attr({ zIndex: 2 })
          .translate(583, lastPoint.plotClose + 81)
            .add()
      }

      const options = {
        chart: {
          spacingRight: 75,
          events: {
            dataLoad: drawLabel,
            redraw: drawLabel
          }
        },
        rangeSelector: {
          selected: 1
        },
        title: {
          text: 'AAPL Stock Price'
        },
        series: [{
          type: 'candlestick',
     //doesn't work on    type:'line'
          name: 'AAPL Stock Price',
          data: [],
          dataGrouping: {
            units: [
              [
                'week', // unit name
                [1] // allowed multiples
              ],
              [
                'month', [1, 2, 3, 4, 6]
              ]
            ]
          }
        }]
      }
      const url = 'https://www.highcharts.com/samples/data/jsonp.php?a=e&filename=aapl-ohlc.json&callback=?'
      const chart = Highcharts.stockChart('container', options)
      $.getJSON(url, function(data) {
        chart.series[0].setData(data)
          // Execute callback
        if (chart.options.chart.events && chart.options.chart.events.dataLoad) {
          const dataLoad = chart.options.chart.events.dataLoad.bind(chart)
          dataLoad(data)
        }
      })
    })

in solution 2 I couldn't get last point position and set it into label :

Solution 2 (in JsFiddle):

var chart=Highcharts.chart('container', {
  series: [{
    data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
  }],
  annotations: [{
    labels: [{


/*      point: function(){
         if(this.Highcharts && this.Highcharts.charts){
     let points = this.Highcharts.charts[0].series[0].points;

          return  {
          x:points[points.length - 1].plotX,
          y::points[points.length - 1].plotY,
          } 

         } */



     /*  }, */
     //Top solution has error 

     point:{x:710.96078431373-30,y:215.9424-10},
        /*  point:{x:311,y:121}  */
      overflow: 'none',
      shape: 'rect',

      formatter: function() {
      console.log(this.series.chart.series[0].points[11])

        let points = this.series.chart.series[0].points;

        return 'Last value: ' + points[points.length - 1].y
      } 
    }]
  }]
});

Solution

  • I think that you should be able to achieve what you want by creating a custom label via using SVGRenderer.

    events: {
      render() {
        let chart = this,
          points = chart.series[0].points,
          lastPoint = points[points.length - 1],
          x = lastPoint.plotX + chart.plotLeft,
          y = lastPoint.plotY + chart.plotTop;
    
       if(chart.lastLabel){
        chart.lastLabel.destroy()
       }
       chart.lastLabel =  chart.renderer.label(lastPoint.y, x + 20, y - 12, 'callout', x, y)
          .css({
            color: '#FFFFFF'
          })
          .attr({
            fill: 'rgba(0, 0, 0, 0.75)',
            padding: 8,
            r: 5,
            zIndex: 6
          }).add()
      }
    }
    

    Demo: https://jsfiddle.net/BlackLabel/yxL60nr9/1/

    API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#label

    API: https://api.highcharts.com/highcharts/chart.events.render

    Let me know if it is what you had in mind.