So I’ve been using coronavirus-map for my daily update; but I’ve also been making my own Vue plugin for Google Maps and thought I’d test it out. It’s a great example for someone who is either learning Vue (intermediate) or wanting a starting point for their own (COVID) map.
This is the result: Repository (code) | Live Demo
Very basic setup using the Vue CLI and default preset (Babel and ESLint).
We’re just using the App.vue file with components so we don’t need the generated Views folder or the HelloWorld.vue component. We also don’t have assets so you can delete the Assets folder too.
npm install x5-gmaps
module.exports = { transpileDependencies: ['x5-gmaps'] }
import x5GMaps from 'x5-gmaps'
Vue.use(x5GMaps, { key: GOOGLE_KEY, libraries: ['visualization'] }
To pass data between components we will use an EventBus rather than Vuex (which you would use for any project larger than this). I’ve called it bus.js and all it contains is:
import Vue from 'vue'
export const EventBus = new Vue()
We will only have one “view” (App.vue), but it will be made from two components: WorldMap.vue and MapOptions.vue.
To simplify things, we will separate out the map overlay from WorldMap.vue. This overlay is the heatmap component that ships with x5-gmaps, and we’ll call it HeatMap.vue.
We start with two Vue data properties: covidDataRaw
(raw data we download) and type
(what type of data we’re mapping).
data: () => ({
covidDataRaw: [],
type: 'active'
}),
When the component is created()
we’ll get our COVID data using fetch() on Muhammad Mustadi’s covid-19-api. We’re also going to use the EventBus to listen and respond to “type” changes (coming from MapOptions.vue).
created() {
// Get data
fetch('https://covid19.mathdro.id/api/confirmed')
.then(response => response.json())
.then(data => (this.covidDataRaw = data))
.catch(e => console.error(e))
// Listen for type change
EventBus.$on('changeType', type => (this.type = type))
}
*Note: In the repository code I have a backup data set that’s called if it can’t connect to the primary one, and resolves as an empty array if there’s a problem with that one too.
The COVID data set downloaded is almost perfect, but needs a little change before we can use it in the heatmap component; so we make a computed property items
that returns a modified (and smaller) array.
We can also set heatmap color gradients depending on what type is selected.
computed: {
items() {
return this.covidDataRaw.map(e => ({
lat: e.lat,
lng: e.long,
active: e.active,
confirmed: e.confirmed,
deaths: e.deaths,
recovered: e.recovered
}))
},
colors() {
if (this.type === 'recovered') return ['white', 'blue']
if (this.type === 'deaths') return ['red', 'black']
return ['green', 'yellow', 'red']
}
}
Finally, we can add all of this into the heatmap component with a few extra props to get it looking good:
<gmaps-heatmap :items="items"
:weightProp="type"
:dissipating="false"
:colors="colors"
:maxIntensity="20000" />
Nothing special in WorldMap.vue, just the x5-gmaps map component with the heatmap we just created inside. The options center the map, set the zoom, and turn off all of Google Map’s controls and buttons.
Similarly, MapOptions.vue is very basic. A group of radio buttons fixed in the top left corner that allow the selection of which type of data you map.
The one interesting thing is the use of the EventBus. The Vue data property type
is what the radio button group is connected to, so we add a watcher for type
and $emit the event the heatmap component is listening for, giving it our new value for type
.
data: () => ({
type: 'active'
}),
watch: {
type(newVal) {
EventBus.$emit('changeType', newVal)
}
}
All the components are now ready, so we can put them in App.vue. It’s extremely basic and all we do is add the WorldMap component and MapOptions component inside a wrapper div that is fixed to full-screen.
You should be able to run npm run serve
and see our goal realised.
This is of course an extremely basic map. Improvements include:
… But those things are for another tutorial — or even better, for you to create and share!
I am still developing my x5-gmaps plugin; but it’s been built in a way you can add your own components so you don’t have to wait for me! If you do use it, please give it a star 🌟 and say what you’d like to see or share a component you’ve made for/with it.
Oh and claps 👏. I love claps.
Any questions, please ask here, Github, or contact me at chisnall.io.
☞ JavaScript Programming Tutorial Full Course for Beginners
☞ Learn JavaScript - Become a Zero to Hero
☞ E-Commerce JavaScript Tutorial - Shopping Cart from Scratch