From d3a5ffaeb9704884d0db2e87587cd0a4ef819445 Mon Sep 17 00:00:00 2001 From: dqmrf Date: Sat, 4 Jul 2026 14:49:53 +0200 Subject: [PATCH 1/3] M02: Create map chart --- .../02-maps-overview/index.html | 21 +- .../highcharts-maps/02-maps-overview/main.js | 192 ++++++++++++++++-- 2 files changed, 187 insertions(+), 26 deletions(-) diff --git a/highcharts-api/highcharts-maps/02-maps-overview/index.html b/highcharts-api/highcharts-maps/02-maps-overview/index.html index b5dab4f..4c23a66 100644 --- a/highcharts-api/highcharts-maps/02-maps-overview/index.html +++ b/highcharts-api/highcharts-maps/02-maps-overview/index.html @@ -2,19 +2,24 @@ - - - + + + - - - -
+ + + + + +
-
+
+
+ +
diff --git a/highcharts-api/highcharts-maps/02-maps-overview/main.js b/highcharts-api/highcharts-maps/02-maps-overview/main.js index 2168650..55c48b9 100644 --- a/highcharts-api/highcharts-maps/02-maps-overview/main.js +++ b/highcharts-api/highcharts-maps/02-maps-overview/main.js @@ -1,21 +1,177 @@ -Highcharts.getJSON( - 'https://code.highcharts.com/mapdata/custom/world-continents.geo.json', - geojson => { - - const data = [ - ['af', 10], - ['eu', 10], - ['sa', 10] - ]; +(async () => { + const topojson = await fetch( + 'https://code.highcharts.com/mapdata/custom/world-continents.topo.json' + ).then(res => res.json()); Highcharts.mapChart('container', { - series: [{ - name: 'World map', - data, - type: 'map', - mapData: geojson, - showInLegend: false - }] + chart: { + height: 600, + map: topojson, + events: { + load() { + const chart = this; + + // Reset View & Selection button + const resetViewBtn = document.getElementById('reset-view'); + resetViewBtn.addEventListener('click', function() { + chart.selectedContinent?.update({ color: '#3651d5' }, false); + chart.selectedContinent = null; + + const { zoom, center } = chart.options.mapView; + chart.mapView.update({ zoom, center }); + }); + + // Line around South America + const x1 = -83, y1 = -55, x2 = -33, y2 = 13; + chart.addSeries({ + type: 'mapline', + enableMouseTracking: false, + color: '#e27800', + lineWidth: 2, + data: [{ + geometry: { + type: 'LineString', + coordinates: [ + [x1, y1], + [x2, y1], + [x2, y2], + [x1, y2], + [x1, y1] + ] + } + }] + }); + + // Custom SVG + chart.customLabel = chart.renderer + .label('SVG', 0, 0) + .attr({ zIndex: 3 }) + .css({ color: 'red' }) + .add(); + + chart.customLabel.coords = { x: -64, y: -20 }; + }, + render() { + const { mapView, customLabel, plotLeft, plotTop } = this; + + // Update custom label. + if (customLabel) { + const { x, y } = mapView.projectedUnitsToPixels(customLabel.coords); + + customLabel.attr({ + x: x + plotLeft - customLabel.width / 2, + y: y + plotTop - customLabel.height / 2 + }); + } + } + } + }, + title: { + text: 'Highcharts maps overview' + }, + mapView: { + zoom: 1.6, + center: [0, 40] + }, + mapNavigation: { + enabled: true, + enableButtons: false + }, + legend: { + enabled: false + }, + plotOptions: { + series: { + states: { + inactive: { + enabled: false + } + }, + } + }, + series: [ + { + name: 'OSM TWM', + type: 'tiledwebmap', + provider: { + type: 'OpenStreetMap', + theme: 'OpenTopoMap', + subdomain: 'a' + } + }, + { + data: [ + ['af', 10], + ['eu', 10], + ['sa', 10] + ], + color: '#3651d5', + borderColor: 'blue', + nullColor: 'transparent', + events: { + click(e) { + const chart = this.chart; + const currentPoint = e.point; + + if (chart.selectedContinent) { + chart.selectedContinent.update({ color: '#3651d5' }, false); + } + chart.selectedContinent = currentPoint; + currentPoint.update({ color: 'transparent' }, false); + chart.mapView.fitToBounds(currentPoint.bounds); + } + } + }, + { + type: 'mapbubble', + maxSize: 30, + enableMouseTracking: false, + color: '#ffffff92', + data: [{ + name: 'Dodoma', + lat: -6.18953, + lon: 35.76462, + z: 10 + }] + + }, + { + type: 'mappoint', + name: 'Mappoints', + enableMouseTracking: false, + color: '#0ced5e', + data: [{ + name: 'Accra', + id: 'accra', + lat: 5.55124, + lon: -0.18402 + }, { + name: 'Dodoma', + id: 'dodoma', + lat: -6.18953, + lon: 35.76462 + }] + }, + { + type: 'flowmap', + linkedTo: ':previous', + minWidth: 4, + maxWidth: 10, + growTowards: true, + enableMouseTracking: false, + fillColor: '#0ced5e', + color: '#0ced5e', + weight: 10, + markerEnd: { + width: '60%', + height: '60%' + }, + data: [{ + from: 'accra', + to: 'dodoma' + }] + } + ] }); - } -); + +})(); From 806d409b7053886c6eca9e443f55f47a22d04dd6 Mon Sep 17 00:00:00 2001 From: dqmrf Date: Wed, 8 Jul 2026 09:37:50 +0200 Subject: [PATCH 2/3] M02: Created SVG circle instead of 'mapbubble' series. --- .../highcharts-maps/02-maps-overview/main.js | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/highcharts-api/highcharts-maps/02-maps-overview/main.js b/highcharts-api/highcharts-maps/02-maps-overview/main.js index 55c48b9..4928182 100644 --- a/highcharts-api/highcharts-maps/02-maps-overview/main.js +++ b/highcharts-api/highcharts-maps/02-maps-overview/main.js @@ -42,7 +42,7 @@ }] }); - // Custom SVG + // Custom SVG label chart.customLabel = chart.renderer .label('SVG', 0, 0) .attr({ zIndex: 3 }) @@ -50,9 +50,29 @@ .add(); chart.customLabel.coords = { x: -64, y: -20 }; + + // Custom SVG circle + const r = 6; + chart.customCircle = chart.renderer + .circle(0, 0, r) + .attr({ + stroke: '#424242', + fill: '#ffffff92', + zIndex: 3 + }) + .css({ + pointerEvents: 'none' + }) + .add(); + + chart.customCircle.baseR = r; + chart.customCircle.lonLat = { + lat: -6.18953, + lon: 35.76462 + } }, render() { - const { mapView, customLabel, plotLeft, plotTop } = this; + const { mapView, customLabel, customCircle, plotLeft, plotTop } = this; // Update custom label. if (customLabel) { @@ -63,6 +83,18 @@ y: y + plotTop - customLabel.height / 2 }); } + + // Update custom circle. + if (customCircle) { + const projected = mapView.lonLatToProjectedUnits(customCircle.lonLat); + const { x, y } = mapView.projectedUnitsToPixels(projected); + + customCircle.attr({ + x: x + plotLeft, + y: y + plotTop, + r: customCircle.baseR * mapView.zoom + }); + } } } }, @@ -122,19 +154,6 @@ } } }, - { - type: 'mapbubble', - maxSize: 30, - enableMouseTracking: false, - color: '#ffffff92', - data: [{ - name: 'Dodoma', - lat: -6.18953, - lon: 35.76462, - z: 10 - }] - - }, { type: 'mappoint', name: 'Mappoints', From 12745f662fb128c38f79478318eac092d799ccaf Mon Sep 17 00:00:00 2001 From: dqmrf Date: Wed, 8 Jul 2026 09:45:28 +0200 Subject: [PATCH 3/3] M02: Fixed mapline configuration. --- highcharts-api/highcharts-maps/02-maps-overview/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts-api/highcharts-maps/02-maps-overview/main.js b/highcharts-api/highcharts-maps/02-maps-overview/main.js index 4928182..4a0337b 100644 --- a/highcharts-api/highcharts-maps/02-maps-overview/main.js +++ b/highcharts-api/highcharts-maps/02-maps-overview/main.js @@ -26,9 +26,9 @@ chart.addSeries({ type: 'mapline', enableMouseTracking: false, - color: '#e27800', lineWidth: 2, data: [{ + color: '#e27800', geometry: { type: 'LineString', coordinates: [