Skip to content

Commit

Permalink
fix: provide geo json data as prop
Browse files Browse the repository at this point in the history
  • Loading branch information
filipgutica committed Jun 18, 2024
1 parent 085d5d7 commit 0622d24
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 42 deletions.
4 changes: 2 additions & 2 deletions packages/analytics/analytics-geo-map/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"build:types": "vue-tsc -p './tsconfig.build.json' --emitDeclarationOnly",
"build:sandbox": "cross-env USE_SANDBOX=true vite build -m production",
"preview": "cross-env USE_SANDBOX=true vite preview",
"lint": "eslint '**/*.{js,jsx,ts,tsx,vue}' --ignore-path '../../../.eslintignore'",
"lint:fix": "eslint '**/*.{js,jsx,ts,tsx,vue}' --ignore-path '../../../.eslintignore' --fix",
"lint": "eslint",
"lint:fix": "eslint --fix",
"stylelint": "stylelint --allow-empty-input './src/**/*.{css,scss,sass,less,styl,vue}'",
"stylelint:fix": "stylelint --allow-empty-input './src/**/*.{css,scss,sass,less,styl,vue}' --fix",
"typecheck": "vue-tsc -p './tsconfig.build.json' --noEmit",
Expand Down
36 changes: 16 additions & 20 deletions packages/analytics/analytics-geo-map/sandbox/App.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
<template>
<div class="sandbox-container">
<KLabel> Fit to country: </KLabel>
<KInput
v-model="fitToCountry"
/>
<KInput v-model="fitToCountry" />
<KMultiselect
v-model="selectedCountries"
:items="items"
label="Pick Something"
/>
<AnalyticsGeoMap
:country-metrics="countryMetrics"
:fit-to-country="fitToCountry"
:initial-zoom="1.6"
/>
<div class="map-container">
<AnalyticsGeoMap
:country-metrics="countryMetrics"
:fit-to-country="fitToCountry"
:geo-json-data="(countryGeoJson as FeatureCollection)"
:initial-zoom="1.6"
/>
</div>
</div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { AnalyticsGeoMap } from '../src'
import countryGeoJson from './countries.geo.json'
import type { FeatureCollection } from 'geojson'
const fitToCountry = ref('')
const selectedCountries = ref<string[]>([])
Expand All @@ -36,18 +39,6 @@ const items = ref([
{ label: 'FR', value: 'FR' },
])
// const countryMetrics = ref<Record<string, number>>({
// US: 4,
// BR: 20,
// RU: 40,
// CN: 99,
// IN: 69,
// ZA: 63,
// RO: 50,
// DE: 30,
// FR: 10,
// })
const countryMetrics = computed(() => {
const metrics: Record<string, number> = {}
selectedCountries.value.forEach((country) => {
Expand All @@ -62,5 +53,10 @@ const countryMetrics = computed(() => {
<style lang="scss" scoped>
.sandbox-container {
height: 900px;
.map-container {
height: 500px;
width: 700px;
}
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@

<script setup lang="ts">
import { ref, onMounted, watch, computed } from 'vue'
import type { PropType } from 'vue'
import { Map, Popup } from 'maplibre-gl'
import type { PropType } from 'vue'
import type { ColorSpecification, DataDrivenPropertyValueSpecification, ExpressionSpecification, LngLatLike } from 'maplibre-gl'
import countriesGeoJson from '../countries.geo.json'
import 'maplibre-gl/dist/maplibre-gl.css'
import type { LongLat } from '../types'
import type { FeatureCollection, Feature, MultiPolygon } from 'geojson'
import 'maplibre-gl/dist/maplibre-gl.css'
const props = defineProps({
countryMetrics: {
type: Object as PropType<Record<string, number>>,
required: true,
},
geoJsonData: {
type: Object as PropType<FeatureCollection>,
required: true,
},
center: {
type: Object as PropType<LongLat>,
required: false,
Expand Down Expand Up @@ -63,41 +66,57 @@ const layerPaint = computed(() => ({
}))
const getColor = (metric: number) => {
if (metric > 80) return '#800026'
if (metric > 60) return '#BD0026'
if (metric > 40) return '#E31A1C'
if (metric > 20) return '#FC4E2A'
return '#FD8D3C'
if (metric > 80) return '#296378'
if (metric > 60) return '#0D8093'
if (metric > 40) return '#009FA9'
if (metric > 20) return '#00BDB7'
return '#0CDCBD'
}
// Simplified coords may be 2 or 3 layers
const flattenPositions = (position: any): number[][] => {
const flat: (number | number[])[] = position.flat(1)
if (Array.isArray(flat[0]) && Array.isArray(flat[0][0])) {
return flattenPositions(flat)
}
return flat as number[][]
}
const goToCountry = (countryCode: string) => {
// Overrides for large spanning countries
if (countryCode === 'RU') {
map.value?.flyTo({ center: [93, 62], zoom: 2.5 })
map.value?.flyTo({ center: [93, 62], zoom: 2 })
return
} else if (countryCode === 'US') {
map.value?.flyTo({ center: [-100, 52], zoom: 2.9 })
map.value?.flyTo({ center: [-100, 42], zoom: 2.9 })
return
} else if (countryCode === 'FR') {
map.value?.flyTo({ center: [2, 47], zoom: 5 })
return
} else if (countryCode === 'NO') {
map.value?.flyTo({ center: [10, 65], zoom: 4.5 })
map.value?.flyTo({ center: [10, 65], zoom: 3.5 })
return
}
const found = (countriesGeoJson as FeatureCollection).features.find((f: Feature) => f.properties?.ISO_A2 === countryCode)
const found = (props.geoJsonData as FeatureCollection).features.find((f: Feature) => f.properties?.ISO_A2 === countryCode)
if (found) {
const coordinates = (found.geometry as MultiPolygon).coordinates
const allCoords = coordinates?.flat(2)
const minLat = Math.min(...allCoords.map((c: number[]) => c[1]))
const minLong = Math.min(...allCoords.map((c: number[]) => c[0]))
// Flatten the coordinates
const allCoords = flattenPositions(coordinates)
const maxLat = Math.max(...allCoords.map((c: number[]) => c[1]))
const maxLong = Math.max(...allCoords.map((c: number[]) => c[0]))
// Extract lats and longs
const lats = allCoords.map((c: number[]) => c[1])
const longs = allCoords.map((c: number[]) => c[0])
// Compute the bounding box
const minLat = Math.min(...lats)
const maxLat = Math.max(...lats)
const minLong = Math.min(...longs)
const maxLong = Math.max(...longs)
map.value?.fitBounds([
[minLong, minLat],
[maxLong, maxLat],
Expand All @@ -118,7 +137,7 @@ onMounted(() => {
map.value.on('load', () => {
map.value?.addSource('countries', {
type: 'geojson',
data: countriesGeoJson as FeatureCollection,
data: props.geoJsonData as FeatureCollection,
})
map.value?.addLayer({
Expand Down
6 changes: 4 additions & 2 deletions packages/analytics/analytics-geo-map/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export function debounce(fn: Function, delay: number) {
export type DebounceFunction = (...args: any[]) => void

export function debounce(fn: DebounceFunction, delay: number) {
let timeoutId: number
return (...args: any) => {
return (...args: any[]) => {
clearTimeout(timeoutId)
timeoutId = window.setTimeout(() => {
fn(...args)
Expand Down

0 comments on commit 0622d24

Please sign in to comment.