diff --git a/README.md b/README.md index 4390325..90de7a7 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,17 @@ Install via npm using `npm install vue-world-map` ## Usage -This component is most useful in creating a heat map for various countries. And -will color countries differently based on a props passed. +This component is most useful when creating a heat map for countries with interpolation between two colors. The component requires a prop of `countryData` to be passed to it, which is a JS -object formatted like so. +object formatted like so: ``` javascript { US: 100, CA: 120, UK: 400, + unknown: 999, } ``` @@ -28,6 +28,8 @@ Where the key is a country's [ISO 3166 Code](https://en.wikipedia.org/wiki/ISO_3166) and the value is a numerical value associated with it. +Keys that have a country code of `unknown` will not have their values parsed. + ## API | Props | Description | Optional | diff --git a/src/App.vue b/src/App.vue index c3a5a4f..93379e7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,26 +1,14 @@ diff --git a/src/Map.vue b/src/Map.vue index 89009cb..594fb0c 100644 --- a/src/Map.vue +++ b/src/Map.vue @@ -1,190 +1,236 @@ + + diff --git a/src/dynamic-map-css.js b/src/dynamic-map-css.js deleted file mode 100644 index f7eae34..0000000 --- a/src/dynamic-map-css.js +++ /dev/null @@ -1,46 +0,0 @@ -// We multiply this unit by the (value of a country - min) to get the -// decimal value to provide to the Chroma scale instance. -const getColorScaleUnit = (min, max) => 1 / (max - min); - -const getMaxAndMinCountryDataValues = (countryData) => { - let min, max; - - Object.keys(countryData).forEach((key) => { - if (key === 'unknown') return; - - const value = countryData[key]; - - if (value < min || min === undefined) min = value; - if (value > max || max === undefined) max = value; - }); - - return { min, max }; -}; - -export const getBaseCss = ({ defaultCountryFillColor, countryStrokeColor }) => ( - `.vue-world-map .land{fill:${defaultCountryFillColor};stroke:${countryStrokeColor};}` -); - -export const getDynamicMapCss = (countryData, chromaScale) => { - const { min, max } = getMaxAndMinCountryDataValues(countryData); - const colorScaleUnit = getColorScaleUnit(min, max); - const css = []; - - Object.keys(countryData).forEach((key) => { - if (key === 'unknown') return; - - const value = countryData[key]; - const scaleValue = colorScaleUnit * (value - min); - const hex = chromaScale(scaleValue).hex(); - - css.push(`.vue-world-map #${key} { fill: ${hex}; }`); - }); - - return css; -}; - -export const getCombinedCssString = (baseCss, dynamicCss) => { - dynamicCss.push(baseCss); - - return dynamicCss.join(' '); -}; diff --git a/src/dynamic-map-helpers.js b/src/dynamic-map-helpers.js new file mode 100644 index 0000000..4f50f29 --- /dev/null +++ b/src/dynamic-map-helpers.js @@ -0,0 +1,18 @@ +// We multiply this unit by the (value of a country - min) to get the +// decimal value to provide to the Chroma scale instance. +export const getColorScaleUnit = (min, max) => 1 / (max - min); + +export const getMaxAndMinCountryDataValues = (countryData) => { + let min, max; + + Object.keys(countryData).forEach((key) => { + if (key === 'unknown') return; + + const value = countryData[key]; + + if (value < min || min === undefined) min = value; + if (value > max || max === undefined) max = value; + }); + + return { min, max }; +}; diff --git a/test/dynamic-map-css.spec.js b/test/dynamic-map-css.spec.js deleted file mode 100644 index 38bcd57..0000000 --- a/test/dynamic-map-css.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import { - getDynamicMapCss, - getBaseCss, - getCombinedCssString, -} from '@/dynamic-map-css'; - -describe('getDynamicMapCss', () => { - const fakeChromaScale = (scaleValue) => ({ - hex: () => `${scaleValue} hex`, - }); - - const countyData = { - US: 4, - CA: 7, - GB: 8, - IE: 14, - unknown: 1337, - }; - - const expectedResult = [ - '.vue-world-map #US { fill: 0 hex; }', - '.vue-world-map #CA { fill: 0.30000000000000004 hex; }', - '.vue-world-map #GB { fill: 0.4 hex; }', - '.vue-world-map #IE { fill: 1 hex; }', - ]; - - const result = getDynamicMapCss(countyData, fakeChromaScale); - - it('should return the correct hex values', () => { - expect(result).toEqual(expectedResult); - }); -}); - -describe('getBaseCss', () => { - const props = { - defaultCountryFillColor: 'foo', - countryStrokeColor: 'bar', - }; - - const expectedResult = '.vue-world-map .land{fill:foo;stroke:bar;}'; - const result = getBaseCss(props); - - it('should return the css string', () => { - expect(result).toEqual(expectedResult); - }); -}); - -describe('getCombinedCssString', () => { - const baseCss = 'foo'; - const dynamicCss = ['bar', 'baz']; - const expectedResult = 'bar baz foo'; - const result = getCombinedCssString(baseCss, dynamicCss); - - it('should return the combined css string', () => { - expect(result).toEqual(expectedResult); - }); -}); diff --git a/test/dynamic-map-helpers.spec.js b/test/dynamic-map-helpers.spec.js new file mode 100644 index 0000000..0570374 --- /dev/null +++ b/test/dynamic-map-helpers.spec.js @@ -0,0 +1,37 @@ +import { + getColorScaleUnit, + getMaxAndMinCountryDataValues, +} from '@/dynamic-map-helpers'; + +describe(getColorScaleUnit, () => { + const min = 4; + const max = 14; + + const expectedResult = 0.1; + const result = getColorScaleUnit(min, max); + + it('should return the correct scaling', () => { + expect(result).toEqual(expectedResult); + }); +}); + +describe(getMaxAndMinCountryDataValues, () => { + const countyData = { + US: 4, + CA: 7, + GB: 8, + IE: 14, + unknown: 1337, + }; + + const expectedResult = { + min: 4, + max: 14, + }; + + const result = getMaxAndMinCountryDataValues(countyData); + + it('should return the min and max country values', () => { + expect(result).toEqual(expectedResult); + }); +});