v2 first commit
This commit is contained in:
127
resources/assets/js/components/WorldMap/WorldMap.vue
Normal file
127
resources/assets/js/components/WorldMap/WorldMap.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<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>
|
Reference in New Issue
Block a user