Skip to content

Commit

Permalink
feat: geo chart
Browse files Browse the repository at this point in the history
  • Loading branch information
filipgutica committed Jan 8, 2024
1 parent 5ac471b commit bd12895
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 8 deletions.
2 changes: 2 additions & 0 deletions packages/analytics/analytics-chart/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@kong-ui-public/sandbox-layout": "workspace:^",
"@kong/design-tokens": "1.12.3",
"@kong/kongponents": "9.0.0-alpha.73",
"@types/geojson": "^7946.0.13",
"@types/uuid": "^9.0.7",
"file-saver": "^2.0.5",
"lodash.mapkeys": "^4.6.0",
Expand Down Expand Up @@ -78,6 +79,7 @@
"approximate-number": "^2.1.1",
"chart.js": "^4.4.1",
"chartjs-adapter-date-fns": "^3.0.0",
"chartjs-chart-geo": "^4.2.7",
"chartjs-plugin-annotation": "^3.0.1",
"date-fns": "^2.30.0",
"date-fns-tz": "^2.0.0",
Expand Down
9 changes: 9 additions & 0 deletions packages/analytics/analytics-chart/sandbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ const router = createRouter({
name: 'simple',
component: () => import('./pages/ChartDemoSimple.vue'),
},
{
path: '/geo-chart',
name: 'geo-chart',
component: () => import('./pages/GeoChartDemo.vue'),
},
],
})

Expand All @@ -53,6 +58,10 @@ const appLinks: SandboxNavigationItem[] = ([
name: 'Simple Charts',
to: { name: 'simple' },
},
{
name: 'Geo Chart',
to: { name: 'geo-chart' },
},
])

// Provide the app links to the SandboxLayout components
Expand Down
41 changes: 41 additions & 0 deletions packages/analytics/analytics-chart/sandbox/pages/GeoChartDemo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<SandboxLayout
:links="appLinks"
title="Analytics Charts"
>
<template #controls />

<GeoChart
:chart-data="chartData"
/>
</SandboxLayout>
</template>

<script setup lang="ts">
import { inject, onMounted, ref } from 'vue'
import type { SandboxNavigationItem } from '@kong-ui-public/sandbox-layout'
import { GeoChart, type KChartData } from '../../src'
import { topojson, type Feature } from 'chartjs-chart-geo'
const appLinks: SandboxNavigationItem[] = inject('app-links', [])
const chartData = ref<KChartData>()
onMounted(async () => {
const data = await fetch('https://unpkg.com/world-atlas/countries-50m.json').then((r) => r.json())
let countries = topojson.feature(data, data.objects.countries).features
countries = countries.filter(c => c.properties.name !== 'Antarctica')
chartData.value = {
labels: countries.map((c: Feature) => c.properties.name),
datasets: [{
label: 'Countries',
data: countries.map((c: Feature) => ({
feature: c,
value: Math.random() * 100,
})),
}],
}
})
</script>
95 changes: 95 additions & 0 deletions packages/analytics/analytics-chart/src/components/GeoChart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<div class="chart-container">
<canvas
ref="chartCanvas"
/>
</div>
</template>

<script setup lang="ts">
import { ref, computed, toRef } from 'vue'
import type { PropType, Ref } from 'vue'
import composables from '../composables'
import type { KChartData, LegendValues } from '../types'
import type { ChartOptions } from 'chart.js'
import { Chart } from 'chart.js'
import { ChoroplethController, GeoFeature, ColorScale, ProjectionScale } from 'chartjs-chart-geo'
// register controller in chart.js and ensure the defaults are set
Chart.register(ChoroplethController, GeoFeature, ColorScale, ProjectionScale)
const props = defineProps({
chartData: {
type: Object as PropType<KChartData>,
required: false,
default: () => ({ labels: [], datasets: [] }),
},
tooltipTitle: {
type: String,
required: false,
default: '',
},
legendValues: {
type: Object as PropType<LegendValues>,
required: false,
default: null,
},
metricUnit: {
type: String,
required: false,
default: '',
},
syntheticsDataKey: {
type: String,
required: false,
default: '',
},
})
const chartCanvas = ref<HTMLCanvasElement>()
const options = computed<ChartOptions>(() => {
return {
responsive: true,
plugins: {
legend: {
display: false,
},
},
scales: {
projection: {
axis: 'x',
projection: 'mercator',
},
},
x: {
grid: {
display: false,
drawBorder: false,
},
},
y: {
grid: {
display: false,
drawBorder: false,
},
},
}
})
composables.useChartJSCommon(
'choropleth',
chartCanvas,
toRef(props, 'chartData'),
[],
options,
) as Ref<Chart | null>
</script>

<style lang="scss" scoped>
.chart-container {
height: 100%;
width: 100%;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import type { Ref } from 'vue'
import { onMounted, watch, shallowRef, onBeforeUnmount } from 'vue'
import { isNullOrUndef } from 'chart.js/helpers'

type ChartTypeGeo = 'choropleth' | 'bubbleMap'

// Based on
// https://github.com/apertureless/vue-chartjs/blob/e61d0b5ce94d71214300a26876e0f2a12e9a26d6/src/utils.ts#L139
const isSameShape = (oldData: ChartData, newData: ChartData) => {
Expand All @@ -23,7 +25,7 @@ const isSameShape = (oldData: ChartData, newData: ChartData) => {
}

export default function useChartJSCommon<T extends ChartType, D extends ChartData<T>>(
chartType: T,
chartType: T | ChartTypeGeo,
canvas: Ref<HTMLCanvasElement | undefined>,
chartData: Ref<D>,
plugins: Plugin[],
Expand All @@ -34,7 +36,7 @@ export default function useChartJSCommon<T extends ChartType, D extends ChartDat
const createChart = (data: ChartData, options: ChartOptions) => {
if (canvas.value) {
return new Chart(canvas.value, {
type: chartType,
type: chartType as ChartType,
data,
plugins,
options,
Expand Down
3 changes: 2 additions & 1 deletion packages/analytics/analytics-chart/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import AnalyticsChart from './components/AnalyticsChart.vue'
import SimpleChart from './components/SimpleChart.vue'
import TopNTable from './components/TopNTable.vue'
import CsvExportModal from './components/CsvExportModal.vue'
import GeoChart from './components/GeoChart.vue'

export { AnalyticsChart, SimpleChart, TopNTable, CsvExportModal }
export { AnalyticsChart, SimpleChart, TopNTable, CsvExportModal, GeoChart }

export * from './types'
export * from './enums'
Expand Down
2 changes: 1 addition & 1 deletion packages/analytics/analytics-chart/src/types/chart-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ChartTypes, ChartMetricDisplay, ChartTypesSimple } from '../enums'
import type { ChartTooltipSortFn } from './chartjs-options'

// Chart.js extendend interfaces
export type Dataset = ChartDataset & { rawDimension: string, rawMetric?: string, total?: number, lineTension?: number, fill?: boolean }
export type Dataset = ChartDataset & { rawDimension?: string, rawMetric?: string, total?: number, lineTension?: number, fill?: boolean }

export interface KChartData extends ChartData {
datasets: Dataset[]
Expand Down
103 changes: 99 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bd12895

Please sign in to comment.