Advanced timeline

author(s): Torstein Hønsi

by jpeter06

HTML

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

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

CSS

#container, .highcharts-data-table table {
    min-width: 310px; 
    max-width: 900px;
    margin: 1em auto;
}

#container {
    height: 480px;
}

.highcharts-data-table table {
	font-family: Verdana, sans-serif;
	border-collapse: collapse;
	border: 1px solid #EBEBEB;
	margin: 10px auto;
	text-align: center;
	width: 100%;
	max-width: 500px;
}
.highcharts-data-table caption {
    padding: 1em 0;
    font-size: 1.2em;
    color: #555;
}
.highcharts-data-table th {
	font-weight: 600;
    padding: 0.5em;
}
.highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption {
    padding: 0.5em;
}
.highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) {
    background: #f8f8f8;
}
.highcharts-data-table tr:hover {
    background: #f1f7ff;
}

JavaScript

const formatDate = Intl.DateTimeFormat('en-US').format;

Highcharts.chart('container', {

	chart: {
    events: {
      load: function() {
        var chart = this,
						annotations = chart.annotations;
						
				annotations.forEach(function(annotation) {
					annotation.labels.forEach(function(label) {
						var element = label.graphic.element;
						element.onmouseenter = function(event) {
							var text = label.options.customTooltipText,
									color = label.options.borderColor;

							chart.customTooltip = chart.renderer.label(text, 0, 0).attr({
                'stroke-width': 1,
                zIndex: 8,
                stroke: color,
                padding: 8,
                r: 3,
                fill: 'rgb(247, 247, 247)'
              }).add();
							
							var flagBox = label.graphic.absoluteBox,
									customTooltipBox = chart.customTooltip.getBBox();
							
							chart.customTooltip.attr({
								x: flagBox.x + flagBox.width / 2 - customTooltipBox.width / 2,
								y: flagBox.y - customTooltipBox.height - 5,
							});
						}
						element.onmouseleave = function(event) {
							if (chart.customTooltip) {
								chart.customTooltip.destroy();
								chart.customTooltip = undefined;
							}
						}
					});
				});
      }
    }
  },

  xAxis: {
    type: 'datetime',
    minTickInterval: 365 * 24 * 36e5
  },
	
  tooltip: {
    useHTML: true,
    shared: true
  },
	
  plotOptions: {
    series: {
      marker: {
        enabled: false
      }
    }
  },
	
  annotations: [{
    draggable: false,
    labels: [{
			text: 'A',
			customTooltipText: 'Anomaly detected',
      point: {
        xAxis: 0,
        yAxis: 0,
        x: 1351728000000,
        y: 50
      },
    }, {
			text: 'B',
			customTooltipText: 'Anomaly end',
      point: {
        xAxis: 0,
        yAxis: 0,
        x: 1398902400000,
        y: 70
      },
    }],
    labelOptions: {
      align: 'right',
      backgroundColor: 'rgb(224, 34, 0)',
      borderColor:...