Lightning Map
// Start at this time let currentTime = Date.UTC(2022, 6, 3, 20); // Get the data class of a lightning strike based on the time ago const getDataClass = (now, datetime) => { if (now - datetime > 20 * 60000) { return 3; } if (now - datetime > 10 * 60000) { return 2; } if (now - datetime > 60000) { return 1; } return 0; }; // Parse the data which comes in the ualf format, a subset of CSV const parseData = () => { const ualf = document.getElementById('data').innerText, lines = ualf.split('\n'); const data = lines .map(line => { const values = line.split(' '); const p = { lon: parseFloat(values[9]), lat: parseFloat(values[8]), datetime: Date.UTC( values[1], parseInt(values[2], 10) - 1, values[3], values[4], values[5], values[6] ), peakCurrent: parseFloat(values[10]), cloudIndicator: Boolean(+values[21]), z: Math.round(parseFloat(values[10])), colorValue: 0 }; return p.cloudIndicator ? undefined : p; }) .filter(p => p !== undefined) .sort((a, b) => a.datetime - b.datetime); return data; }; const ualf = parseData(); // Get the data for the initial time const getInitialData = time => ualf.slice( ualf.findIndex(p => p.datetime > time - 30 * 60000), ualf.findLastIndex(p => p.datetime <= time) ).map(p => { p.colorValue = getDataClass(time, p.datetime); return p; }); const displayTime = time => { document.getElementById('report-time').innerText = Highcharts.dateFormat( '%[BeYHM]', time ); }; (async () => { // Load the map const topology = await fetch( 'https://code.highcharts.com/mapdata/custom/europe.topo.json' ).then(response => response.json()); // Create the chart const chart = Highcharts.mapChart('container', { chart: { map: topology, height: '80%', margin: 0, backgroundColor: '#222', animation: false }, accessibility: { enabled: false }, title: { text: 'Lightning strikes', align: 'left', style: { color: 'rgba(255,255,196,1)' } }, subtitle: { text: 'Source: <a href="https://frost.met.no/api.html#!/lightning/getLightning" style="color: inherit">frost.met.no</a>', align: 'left', style: { color: '#aaa' } }, legend: { align: 'right', verticalAlign: 'top', layout: 'vertical', itemStyle: { color: '#ddd' } }, mapView: { center: [12, 56.8], zoom: 7, projection: { rotation: [-15] } }, colorAxis: { dataClasses: [{ from: 0, to: 0, color: 'rgba(255,255,196,1)', name: '< 1 min' }, { from: 1, to: 1, color: 'rgba(255,196,0,1)', name: '1 - 10 min' }, { from: 2, to: 2, color: 'rgba(196,128,0,1)', name: '10 - 20 min' }, { from: 3, to: 3, color: 'rgba(196,64,0,1)', name: '20 - 30 min' }] }, series: [{ name: 'Map', nullColor: '#444', borderColor: '#666', dataLabels: { enabled: true, nullFormat: '{point.name}', style: { color: '#888', textOutline: 'none', fontSize: '16px', fontWeight: 'normal' } } }, { name: 'Lightning strike', id: 'lightnings', type: 'mapbubble', animation: false, data: getInitialData(currentTime), tooltip: { pointFormat: '{point.datetime:%Y-%m-%d %H:%M:%S}' }, minSize: 4, maxSize: 8, marker: { lineWidth: 0, radius: 3 }, colorKey: 'colorValue' }] }); displayTime(currentTime); // Update the colors of the data points const updateColors = time => { let redraw = false; // Modify older points chart.get('lightnings').points.forEach(p => { let colorValue; if (time - p.options.datetime > 30 * 60000) { p.remove(); } else { colorValue = getDataClass(time, p.options.datetime); } if (colorValue && colorValue !== p.options.colorValue) { p.update({ colorValue }, false); redraw = true; } }); return redraw; }; // For the strongest lightning strikes, light up the chart with a temporary // flash const flash = point => { const pos = chart.mapView.lonLatToPixels(point); chart.renderer.circle(pos.x, pos.y, point.z * 2) .attr({ fill: { radialGradient: { cx: 0.5, cy: 0.5, r: 0.5 }, stops: [ [0, 'rgba(255, 255, 0, 0.25)'], [0.1, 'rgba(255, 255, 0, 0.125)'], [1, 'rgba(255, 255, 0, 0)'] ] }, zIndex: 10 }) .add() .animate( { opacity: 0 }, { duration: 250 }, function () { this.destroy(); } ); }; if (updateColors(currentTime)) { chart.redraw(); } // The remainder of the data after currentTime let data = ualf.slice(ualf.findIndex(p => p.datetime > currentTime)); const endTime = data.at(-1).datetime, step = 10000, series = chart.get('lightnings'); let timer; const pause = () => { clearTimeout(timer); document.getElementById('play-pause').textContent = '▶︎'; }; // Add the lightning strikes for the last n minutes const addPoints = time => { const rangeInput = document.getElementById('date-range'); // Internal Highcharts CI sample verification if (!rangeInput) { return; } currentTime = time; let redraw = false; displayTime(time); rangeInput.value = time; if (updateColors(time)) { redraw = true; } // Add new points const points = []; while (data[0] && data[0].datetime <= time) { points.push(data.shift()); } points.forEach(point => { redraw = true; series.addPoint(point, false); if (point.z > 10) { flash(point); } }); if (redraw) { chart.redraw(); } if (time + step <= endTime) { timer = setTimeout(() => addPoints(time + step), 25); } else { pause(); } }; const play = () => { document.getElementById('play-pause').textContent = '▮▮'; data = ualf.slice(ualf.findIndex(p => p.datetime > currentTime)); timer = setTimeout(() => addPoints(currentTime + step), 25); }; const setUpInputs = () => { // Range input const input = document.getElementById('date-range'); input.min = ualf[0].datetime; input.max = ualf.at(-1).datetime; input.value = currentTime; input.addEventListener('input', () => { pause(); currentTime = Number(input.value); chart.series[1].setData(getInitialData(input.value)); displayTime(currentTime); }); // Play/pause document.getElementById('play-pause').addEventListener( 'click', function () { if (this.textContent === '▶︎') { play(); } else { pause(); } } ); }; setUpInputs(); // eslint-disable-next-line no-underscore-dangle if (!window.__karma__) { // CI tests // Wait a bit for Visual review tool setTimeout(() => play(), 100); } })();
MapsGeneral
Install with NPM
The official Highcharts NPM package comes with support for CommonJS and contains Highcharts, and its Stock, Maps and Gantt packages.
npm install highcharts --save
See more installation optionsDownload our library
The zip archive contains Javascript files and examples. Unzip the zip package and open index.html in your browser to see the examples.
DownloadBuy a license
You can download and try out all Highcharts products for free. Once your project/product is ready for launch, purchase a commercial license.
See License Pricing