简体   繁体   中英

Change highcharts data label position

This is my jsfiddle link http://jsfiddle.net/bb1m6xyk/1/

I want that all my labels like my data: 0 etc are positioned at the base and in center of each zone.

$('#container').highcharts({
    chart: {
      type: 'area'
    },
    yAxis: {
      title: {
        text: 'Percent'
      }
    },
    plotOptions: {
      area: {
        enableMouseTracking: false,
        showInLegend: false,
        stacking: 'percent',
        lineWidth: 0,
        marker: {
          enabled: false
        },
        dataLabels: {
            className:'highlight',
          enabled: true,
          formatter: function () {
            console.log(this);
            return this.point.myData
          }
        }
      }
    },
    series: [{
      name: 'over',
      color: 'none',
      data: overData
    }, {
      id: 's1',
      name: 'Series 1',
      data: data,
      showInLegend: true,
      zoneAxis: 'x',
      zones: zones
    }]
  });

Is this possible? I tried it using className on dataLabels but it doesn't take that into effect.

Any help is appreciated.

There are a few ways to render labels on a chart.

The Renderer

Live example: http://jsfiddle.net/11rj6k6p/

You can use Renderer.label to render the label on the chart - this is a low level approach but it gives you full control how the labels will be rendered. You can loop the zones and set x and y attributes of the labels, eg like this:

const labels = ['l1', 'l2', 'l3', 'l4', 'l5']

function drawLabels() {
  const zonesLabels = this.zonesLabels

  const series = this.get('s1')
  const { yAxis, xAxis } = series
  const y = yAxis.toPixels(0) - 20 // -20 is an additional offset in px


  series.zones.reduce((prev, curr, i) => {
    if (curr.value !== undefined) {
      const x = (xAxis.toPixels(prev.value) + xAxis.toPixels(curr.value)) / 2
      if (!zonesLabels[i]) {
        zonesLabels.push(
          this.renderer.label(labels[i], x, y).add().attr({
            align: 'center',
            zIndex: 10
          })
        )
      } else {
        zonesLabels[i].attr({ x, y })
      }
    }

   return curr
  }, { value: series.dataMin })
}

Then set the function on load - to render the labels, and on redraw - to reposition the labels if the chart size changed.

chart: {
  type: 'area',
  events: {
    load: function() {
      this.zonesLabels = []

      drawLabels.call(this)
    },
    redraw: drawLabels
  }
},

The annotations module

Live example: http://jsfiddle.net/a5gb7aqz/

If you do not want to use the Renderer API, you can use the annotations module which allows to declare labels in a chart config.

Add the module

<script src="https://code.highcharts.com/modules/annotations.js"></script>

Map zones to the labels config object

const labels = ['l1', 'l2', 'l3', 'l4', 'l5']

function annotationsLabels() {
  const zonesLabels = []

  zones.reduce((prev, curr, i) => {
    zonesLabels.push({
      text: labels[i],
      point: {
        x: (prev.value + curr.value) / 2,
        y: 0,
        xAxis: 0,
        yAxis: 0
      }
    })

   return curr
  }, { value: 0 })

  return zonesLabels
}

Set the annotations options

annotations: [{
  labels: annotationsLabels(),
  labelOptions: {
    shape: 'rect',
    backgroundColor: 'none',
    borderColor: 'none',
    x: 0,
    y: 0
  }
}],

Data labels and a new series

Live example: http://jsfiddle.net/wpk1495g/

You can create a new scatter series which will not respond to mouse events and it won't be visible in the legend. The labels can be displayed as data labels .

Map zones to series points

const labels = ['l1', 'l2', 'l3', 'l4', 'l5']

function seriesData() {
  const points = []

  zones.reduce((prev, curr, i) => {
    points.push( {
      x: (prev.value + curr.value) / 2,
      y: 50,
      dataLabels: {
        enabled: true,
        format: labels[i]
      }
    })

    return curr
  }, { value: 0 })

 return points
}

Set the series options in the chart config

, {
  type: 'scatter',
  enableMouseTracking: false,
  showInLegend: false,
  data: seriesData(),
  zIndex: 10,
  color: 'none',
  dataLabels: { style: { textOutline: false }, x: 0, y: 0 }
}

Output

区域标签

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM