JSFiddle - React, Tailwind, and code Playground

by longmatthewh

HTML

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

<div id="container"></div>

CSS

#container {
  min-width: 300px;
  max-width: 800px;
  height: 300px;
  margin: 1em auto;
}

JavaScript

/*
PROBLEM:
In the function below...
 - pointLabel is of type PointLabelObject
 - pointLabel.point is of type Point
 
When using Typescript and typing the function params like this...

const offsetPointValue = (pointLabel:HighCharts.PointLabelObject) => {

...I can't access shapeArgs without casting the Point object as any like this...

(pointLabel.point as any).shapeArgs

*/
const offsetPointValue = (pointLabel) => {
  const value = pointLabel.y;
  const minSeriesHeightWhereLabelFitsInside = 12;
  const shape = pointLabel.point.shapeArgs;

  if (shape.height > minSeriesHeightWhereLabelFitsInside) {
    return `<div>${value}</div>`;
  }
  const labelRightOffset = -1 * (Math.floor(shape.width / 2) + 1);
  const labelTopOffset = -7;
  return `<div style='position:absolute;width:100%;right:${labelRightOffset}px;top:${labelTopOffset}px;'>-${value}</div>`;
}


const [clip, gridLineColor, xAxisOffset] = [false, "transparent", 2];

const seriesConfig = {
  type: "column",
  clip: clip,
}

const seriesData = [{
  ...seriesConfig,
  data: [1, 4, 3, 5],
}, {
  ...seriesConfig,
  data: [2, 1, 5, 4],
}, {
  ...seriesConfig,
  data: [3, 2, 1, 2],
}];

const categories = ['Apples', 'Pears', 'Bananas', 'Oranges'];

Highcharts.chart('container', {
  chart: {
    spacingRight: 20,
  },
  xAxis: {
    categories: categories,
    offset: xAxisOffset,
  },
  yAxis: {
    gridLineColor: gridLineColor,
    stackLabels: {
      enabled: false,
    },
  },
  plotOptions: {
    column: {
      stacking: "normal",
      borderColor: "#000",
      borderWidth: 3,
      dataLabels: {
        enabled: true,
        useHTML: true,
        crop: false,
        allowOverlap: false,
        formatter: function() {
          return offsetPointValue(this);
        },
      },
    },
    series: {
      stacking: "normal",
    },
  },
  series: seriesData,
  legend: {
    alignColumns: false,
    itemWidth: 0,
    itemMarginBottom: 22,
    symbolHeight: 16,
    symbolWidth: 16,
    symbolPadding:...