External legends

author(s):

by findango

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/numeral.js/2.0.4/numeral.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script>

function stringify(value) {
	return typeof value === 'object'
    	? JSON.stringify(value, null, 2)
        : value;
}

function log() {
    var args = Array.prototype.slice.call(arguments, 0);
    document.getElementById('output').innerHTML += args.map(stringify).join(" ") + "\n";
}

function clearLog() {
	document.getElementById('output').innerHTML = '';
}
</script>

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

<pre id="output"></pre>

CSS

#container, #legend {
    display: inline-block;
    vertical-align: top;
}

#container {
    height: 170px;
}

#legend {
    background-color: white;
    height: 155px;
    width: 100px;
    padding: 5px;
    padding-top: 10px;
}

.legend-item {
    font-size: 10px;
    font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif;
    color: #687177;
    margin-bottom: 2px;
}

.legend-item span {
    margin-right: 5px;
}

.legend-marker {
    display: inline-block;
    width: 7px;
    height: 7px;
}

.legend-value {
    float: right;
    color: #333;
}

.legend-time {
    font-size: 10px;
    font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif;
    color: #687177;
    float: right;
    margin-right: 5px;
}

JavaScript

function legendItem({name, color, value, offset}) {
    return '' +
        '<div class="legend-item">' + 
            '<span class="legend-marker" style="background-color: ' + color + ';"></span>' +
            '<span class="legend-name">' + name + '</span>' +
            '<span class="legend-value">' + value + '</span>' + 
         '</div>';
}

function formatTime(millis) {
	return moment.unix(Math.floor(millis/1000)).format('HH:mm:ss');
}

function renderLegend(points) {
    // sort the legend by the final value of the series (fancy!)
    points.sort((a, b) => {
        const a_val = a.series.points.slice(-1)[0].y;
        const b_val = b.series.points.slice(-1)[0].y;
        return b_val - a_val;
    });

    const legend = $('#legend');
    legend.empty();

    points.forEach(point => {
        legend.append(legendItem({
            name: point.series.name,
            color: point.series.color,
            value: numeral(point.y).format('0.00 a'),
            offset: point.series.points.slice(-1)[0].plotY + 10
        }));
    });

	if (points[0].point) {
        legend.append(
    	    '<div class="legend-time">' + 
    	        formatTime(points[0].point.category) + 
            '</div>'
        );
    }
}

function initLegend() {
    const finalPoints = this.series.map(s => {
        return s.points.slice(-1)[0];
    })
    renderLegend(finalPoints);
}

function tooltipFormatter() {
    const points = this.points.slice();
    renderLegend(points);
    // hide the actual tooltip
    return false;
}

Highcharts.chart('container',
{
  "chart": {
    "type": "column",
    "height": 170,
    "plotBorderWidth": 1,
    "plotBorderColor": "#e9eCf0",
    "marginRight": 5,
    "marginLeft": 70,
    "events": {
        "load": initLegend
    },
    "zoomType": "x",
  },
  "title": {
    "text": null
  },
 "legend": {
   "enabled": false
//   "x": -5,
//   "y": -10,
//   "margin": 5,
//   "symbolWidth": 10,
//   "itemMarginTop": 5,
//   "itemStyle": {
//    ...