From 7eac93ba07b894b67b1ef9a7e82dfb3ce1e3ac9b Mon Sep 17 00:00:00 2001 From: Mat Schaffer Date: Sun, 27 Dec 2020 15:45:00 +0900 Subject: [PATCH 1/3] Add reversible legend option Fixes https://github.com/panodata/grafana-map-panel/issues/85 --- src/partials/editor.html | 16 +++++++++++----- src/worldmap.ts | 13 ++++++++++--- src/worldmap_ctrl.ts | 5 +++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/partials/editor.html b/src/partials/editor.html index c862ec7..8942b22 100644 --- a/src/partials/editor.html +++ b/src/partials/editor.html @@ -413,11 +413,17 @@
Appearance
-
- - + +
+ + +
+ + +
diff --git a/src/worldmap.ts b/src/worldmap.ts index 4408531..2a0b97f 100644 --- a/src/worldmap.ts +++ b/src/worldmap.ts @@ -126,11 +126,18 @@ export default class WorldMap { case ColorModes.threshold.id: default: return () => { - const thresholds = this.ctrl.data.thresholds; + const thresholds = this.ctrl.data.thresholds.slice(); + const colors = this.ctrl.settings.colors.slice(); + + if (this.ctrl.settings.reverseLegend) { + thresholds.reverse(); + colors.reverse(); + } + let legendHtml = ''; legendHtml += '
' + '< ' + thresholds[0] + @@ -138,7 +145,7 @@ export default class WorldMap { for (let index = 0; index < thresholds.length; index += 1) { legendHtml += '
' + thresholds[index] + (thresholds[index + 1] ? '–' + thresholds[index + 1] + '
' : '+'); diff --git a/src/worldmap_ctrl.ts b/src/worldmap_ctrl.ts index ae4a80f..194a2a5 100644 --- a/src/worldmap_ctrl.ts +++ b/src/worldmap_ctrl.ts @@ -38,6 +38,7 @@ const panelDefaults = { unitSingular: '', unitPlural: '', showLegend: true, + reverseLegend: false, legendContainerSelector: null, showZoomControl: true, showAttribution: true, @@ -549,6 +550,10 @@ export default class WorldmapCtrl extends MetricsPanelCtrl { this.render(); } + toggleLegendDirection() { + this.map.legend.update(); + } + refreshOverlay() { this.map.overlay.remove(); this.map.overlay = null; From c6af9edcd5e8ee75e48865baa1743ae8ce1faf71 Mon Sep 17 00:00:00 2001 From: Mat Schaffer Date: Sun, 27 Dec 2020 17:21:31 +0900 Subject: [PATCH 2/3] Rework to handle ranges correctly --- src/worldmap.ts | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/worldmap.ts b/src/worldmap.ts index 2a0b97f..0f705c8 100644 --- a/src/worldmap.ts +++ b/src/worldmap.ts @@ -126,31 +126,33 @@ export default class WorldMap { case ColorModes.threshold.id: default: return () => { - const thresholds = this.ctrl.data.thresholds.slice(); - const colors = this.ctrl.settings.colors.slice(); + const thresholds = this.ctrl.data.thresholds; + const colors = this.ctrl.settings.colors; - if (this.ctrl.settings.reverseLegend) { - thresholds.reverse(); - colors.reverse(); - } + let labels: string[] = []; + + labels.push(` +
+ + < ${thresholds[0]} +
+ `); - let legendHtml = ''; - legendHtml += - '
' + - '< ' + - thresholds[0] + - '
'; for (let index = 0; index < thresholds.length; index += 1) { - legendHtml += - '
' + - thresholds[index] + - (thresholds[index + 1] ? '–' + thresholds[index + 1] + '
' : '+'); + labels.push(` +
+ + ${thresholds[index]} + ${thresholds[index + 1] ? '– ' + thresholds[index + 1] : '+'} +
+ `); } - this.legend._div.innerHTML = legendHtml; + + if (this.ctrl.settings.reverseLegend) { + labels.reverse(); + } + + this.legend._div.innerHTML = labels.join(''); }; } } From b3cf3d85d15c7cd489973604792d029e682593fa Mon Sep 17 00:00:00 2001 From: Mat Schaffer Date: Sun, 3 Jan 2021 22:46:34 +0900 Subject: [PATCH 3/3] Use html assertions for tests Let's us clean up the generation code a bit without having to worry about whitespace. --- src/worldmap.test.ts | 79 ++++++++++++++++++++++++-------------------- src/worldmap.ts | 11 ++++-- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/worldmap.test.ts b/src/worldmap.test.ts index 903007e..8518acb 100644 --- a/src/worldmap.test.ts +++ b/src/worldmap.test.ts @@ -375,12 +375,14 @@ describe('Worldmap', () => { it('should create a legend with two legend values', () => { expect(worldMap.legend).toBeDefined(); - expect(worldMap.legend._div.outerHTML).toBe( - '
' + - '
' + - ' < 2
2+
' + - '
' - ); + let elements = [...worldMap.legend._div.querySelectorAll('.legend-item')]; + expect(elements.length).toEqual(2); + + let labels = elements.map(e => e.textContent.trim()); + expect(labels).toEqual(['< 2', '2+']); + + let colors = elements.map(e => e.querySelector('i').style.getPropertyValue('background')); + expect(colors).toEqual(['red', 'blue']); }); }); @@ -404,11 +406,14 @@ describe('Worldmap', () => { it('should create a legend with three legend values', () => { expect(worldMap.legend).toBeDefined(); - expect(worldMap.legend._div.outerHTML).toBe( - '
' + - ' < 2
2–4
' + - '
4+
' - ); + let elements = [...worldMap.legend._div.querySelectorAll('.legend-item')]; + expect(elements.length).toEqual(3); + + let labels = elements.map(e => e.textContent.trim()); + expect(labels).toEqual(['< 2', '2 – 4', '4+']); + + let colors = elements.map(e => e.querySelector('i').style.getPropertyValue('background')); + expect(colors).toEqual(['red', 'blue', 'green']); }); }); @@ -420,12 +425,15 @@ describe('Worldmap', () => { it('should create a legend with four legend values', () => { expect(worldMap.legend).toBeDefined(); - expect(worldMap.legend._div.outerHTML).toBe( - '
' + - ' < 2
2–4
' + - '
4–6
' + - '
6+
' - ); + + let elements = [...worldMap.legend._div.querySelectorAll('.legend-item')]; + expect(elements.length).toEqual(4); + + let labels = elements.map(e => e.textContent.trim()); + expect(labels).toEqual(['< 2', '2 – 4', '4 – 6', '6+']); + + let colors = elements.map(e => e.querySelector('i').style.getPropertyValue('background')); + expect(colors).toEqual(['red', 'blue', 'green', '']); }); }); @@ -438,12 +446,15 @@ describe('Worldmap', () => { it('should create a legend with four legend values', () => { expect(worldMap.legend).toBeDefined(); - expect(worldMap.legend._div.outerHTML).toBe( - '
' + - ' < 2
2–4
' + - '
4–6
' + - '
6+
' - ); + + let elements = [...worldMap.legend._div.querySelectorAll('.legend-item')]; + expect(elements.length).toEqual(4); + + let labels = elements.map(e => e.textContent.trim()); + expect(labels).toEqual(['< 2', '2 – 4', '4 – 6', '6+']); + + let colors = elements.map(e => e.querySelector('i').style.getPropertyValue('background')); + expect(colors).toEqual(['red', 'blue', 'green', '']); }); }); @@ -456,12 +467,15 @@ describe('Worldmap', () => { it('should create a legend with four legend values', () => { expect(worldMap.legend).toBeDefined(); - expect(worldMap.legend._div.outerHTML).toBe( - '
' + - ' *
some cat
' + - '
other cat
' + - '
asdf
' - ); + + let elements = [...worldMap.legend._div.querySelectorAll('.legend-item')]; + expect(elements.length).toEqual(4); + + let labels = elements.map(e => e.textContent.trim()); + expect(labels).toEqual(['*', 'some cat', 'other cat', 'asdf']); + + let colors = elements.map(e => e.querySelector('i').style.getPropertyValue('background')); + expect(colors).toEqual(['red', 'blue', 'green', '']); }); }); @@ -488,12 +502,7 @@ describe('Worldmap', () => { it('we should find the respective element at the appropriate place in the DOM', () => { expect(worldMap.legend).toBeDefined(); - expect($('.shared-map-legend')[0].innerHTML).toBe( - '
' + - ' < 2
2–4
' + - '
4–6
' + - '
6+
' - ); + expect($('.shared-map-legend')[0].innerHTML).toContain('legend-item'); }); }); diff --git a/src/worldmap.ts b/src/worldmap.ts index 0f705c8..a69e3d5 100644 --- a/src/worldmap.ts +++ b/src/worldmap.ts @@ -139,12 +139,17 @@ export default class WorldMap { `); for (let index = 0; index < thresholds.length; index += 1) { + let next = '+'; + + if (thresholds[index + 1]) { + next = ' – ' + thresholds[index + 1]; + } + labels.push(`
- ${thresholds[index]} - ${thresholds[index + 1] ? '– ' + thresholds[index + 1] : '+'} -
+ ${thresholds[index]}${next} +
`); }