2019-11-16 10:21:14 +03:00

128 lines
3.1 KiB
Vue

<template>
<div :id="id" class="world-map"></div>
</template>
<script>
import 'd3';
import * as d3 from 'd3';
import 'topojson';
import { throttle } from '@/util/throttle';
export default {
name: 'world-map',
props: {
mapData: {
type: Object,
default: () => ({})
},
points: {
type: Array,
default: () => []
}
},
data() {
return {
id: this.randomString(),
color1: '#f6f9fc',
color2: '#adb5bd',
highlightFillColor: '#ced4da',
borderColor: 'white',
highlightBorderColor: 'white',
bubbleHighlightFillColor: '#11cdef',
bubbleFillColor: '#fb6340'
};
},
methods: {
generateColors(length) {
return d3
.scaleLinear()
.domain([0, length])
.range([this.color1, this.color2]);
},
generateMapColors() {
let mapDataValues = Object.values(this.mapData);
let maxVal = Math.max(...mapDataValues);
let colors = this.generateColors(maxVal);
let mapData = {};
let fills = {
defaultFill: '#EDF0F2'
};
for (let key in this.mapData) {
let val = this.mapData[key];
fills[key] = colors(val);
mapData[key] = {
fillKey: key,
value: val
};
}
return {
mapData,
fills
};
},
async initVectorMap() {
let DataMap = await import('datamaps');
DataMap = DataMap.default || DataMap
let { fills, mapData } = this.generateMapColors();
let worldMap = new DataMap({
scope: 'world',
element: document.getElementById(this.id),
fills,
data: mapData,
responsive: true,
geographyConfig: {
borderColor: this.borderColor,
borderWidth: 1,
borderOpacity: 1,
highlightFillColor: this.highlightFillColor,
highlightBorderColor: this.highlightBorderColor,
highlightBorderWidth: 1,
highlightBorderOpacity: 1
}
});
let bubbleOptions = {
radius: 2,
borderWidth: 4,
highlightBorderWidth: 4,
fillKey: this.bubbleFillColor,
fillColor: this.bubbleFillColor,
borderColor: this.bubbleFillColor,
highlightFillColor: this.bubbleHighlightFillColor,
highlightBorderColor: this.bubbleHighlightFillColor
}
let bubblePoints = this.points.map(point => {
return {
...bubbleOptions,
...point
}
})
worldMap.bubbles(bubblePoints, {
popupTemplate: function(geo, data) {
return '<div class="hoverinfo">' + data.name
}
});
let resizeFunc = worldMap.resize.bind(worldMap);
window.addEventListener(
'resize',
() => {
throttle(resizeFunc, 40);
},
false
);
},
randomString() {
let text = "";
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
for (let i = 0; i < 5; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
},
async mounted() {
this.initVectorMap();
}
};
</script>
<style></style>