Skip to content

Commit

Permalink
refactor(chart): useSimpleChart
Browse files Browse the repository at this point in the history
  • Loading branch information
jiwangyihao committed Oct 6, 2024
1 parent af417b7 commit 87012eb
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 46 deletions.
34 changes: 8 additions & 26 deletions extensions/chart/src/barChart.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script setup lang="ts">
import { defineWidget } from '@vue-motion/core'
import { onMounted, provide, ref, watchEffect } from 'vue'
import { onMounted, ref, watchEffect } from 'vue'
import type { DateTime } from 'luxon'
import type { Growable } from '@vue-motion/lib'
import { Rect as VMRect } from '@vue-motion/lib'
import type { ChartLayoutConfig } from './chartLayout.vue'
import BaseSimpleChart from './baseSimpleChart.vue'
import type { BaseChartDataSet, BaseChartOptions, BaseChartStyle, ChartStyle, Color } from '.'
import { useSimpleChart } from './utils/useSimpleChart.ts'
import type { BaseChartOptions, BaseChartStyle, Color } from '.'
import { ColorEnum, DataUtil } from '.'
/**
Expand All @@ -26,33 +25,16 @@ export interface BarChartOptions extends BaseChartOptions, Growable {
barPercentage?: number
}
export interface BaseChartData {
/**
* @property string[] labels
* @description
* labels is an array of strings that represent the labels of the chart, which are displayed on the index-axis.
* It is optional.
* If not provided, the labels will be generated automatically.
*/
labels?: string[] | DateTime[]
datasets: BaseChartDataSet<BarChartStyle>[]
style?: ChartStyle
}
const props = withDefaults(defineProps<BarChartOptions>(), {
gridAlign: true,
categoryPercentage: 0.8,
barPercentage: 0.8,
})
const options = defineWidget<BarChartOptions>(props)
const data = ref<BaseChartData>({
labels: options.labels,
datasets: [],
})
provide('chartData', data)
const layoutConfig = ref<ChartLayoutConfig>({})
provide('chartLayoutConfig', layoutConfig)
const {
options,
data,
layoutConfig,
} = useSimpleChart<BarChartOptions>(props)
const barSets = ref<{
width: number
Expand Down
23 changes: 6 additions & 17 deletions extensions/chart/src/baseSimpleChart.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<script setup lang="ts">
import { widget } from '@vue-motion/lib'
import { defineWidget } from '@vue-motion/core'
import type { DateTime } from 'luxon'
import type { Ref } from 'vue'
import { inject, provide, ref } from 'vue'
import type { ChartLayoutConfig } from './chartLayout.vue'
import { withDefaults } from 'vue'
import ChartLayout from './chartLayout.vue'
import type { BaseChartOptions, ChartStyle } from './baseChart.ts'
import type { BaseChartDataSet } from './chartDataset.vue'
import { useSimpleChart } from './utils/useSimpleChart.ts'
/**
* BaseSimpleChartOptions
Expand Down Expand Up @@ -35,7 +33,7 @@ export interface BaseSimpleChartData {
*/
datasets: BaseChartDataSet<ChartStyle>[]
/**
* @property BaseChartStyle style
* @property ChartStyle style
* @description
* style is an object that defines the style of the chart.
*/
Expand All @@ -45,18 +43,9 @@ export interface BaseSimpleChartData {
const props = withDefaults(defineProps<BaseSimpleChartOptions>(), {
gridAlign: true,
})
const options = defineWidget<BaseSimpleChartOptions>(props)
let data = inject<Ref<BaseSimpleChartData>>('chartData')
data ??= ref<BaseSimpleChartData>({
labels: options.labels,
datasets: [],
})
provide('chartData', data)
let layoutConfig = inject<Ref<ChartLayoutConfig>>('chartLayoutConfig')
layoutConfig ??= ref<ChartLayoutConfig>({})
provide('chartLayoutConfig', layoutConfig)
const {
options,
} = useSimpleChart<BaseSimpleChartOptions>(props)
</script>

<template>
Expand Down
16 changes: 13 additions & 3 deletions extensions/chart/src/chartLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { type Ref, inject, ref, watchEffect } from 'vue'
import type { DateTimeUnit } from 'luxon'
import { DateTime } from 'luxon'
import stringWidth from 'string-width'
import type { BaseChartData, BaseChartOptions, Color, DateTimeFormatOptions } from '.'
import type { BaseSimpleChartData } from './baseSimpleChart.vue'
import type { BaseChartOptions, Color, DateTimeFormatOptions } from '.'
import { ColorEnum, DataUtil } from '.'
export interface ChartLayoutOptions extends BaseChartOptions, Growable {
Expand Down Expand Up @@ -75,11 +76,13 @@ const props = withDefaults(defineProps<ChartLayoutOptions>(), {
})
const options = defineWidget(props)
const data = inject<Ref<BaseChartData>>('chartData', ref({ datasets: [] }))
const data = inject<Ref<BaseSimpleChartData>>('chartData', ref({ datasets: [] }))
const layoutConfig = inject<Ref<ChartLayoutConfig>>('chartLayoutConfig', ref({}))
const legendWidthPrefix = ref([0])
const onload = ref(false)
function generateAxisRange(axis: ChartAxis, data: number[]) {
const minDataValue = Math.min(...data, typeof axis.suggestedMin === 'number' ? axis.suggestedMin : Number.NEGATIVE_INFINITY)
const maxDataValue = Math.max(...data, typeof axis.suggestedMax === 'number' ? axis.suggestedMax : Number.POSITIVE_INFINITY)
Expand Down Expand Up @@ -140,6 +143,13 @@ function generateDateAxisRange(axis: ChartAxis, data: DateTime[]) {
}
watchEffect(() => {
if (data.value.datasets.length === 0)
return
if (data.value.datasets.some(dataset => (dataset.data.length === 0)))
return
onload.value = true
data.value.datasets.forEach((dataset) => {
dataset.data.forEach((dataUnit, index) => {
if (!DataUtil.indexNumber(dataUnit) && data.value.labels && (data.value.labels[index] as DateTime).isValid) {
Expand Down Expand Up @@ -284,7 +294,7 @@ watchEffect(() => {
</script>

<template>
<g v-bind="widget(options)">
<g v-if="onload" v-bind="widget(options)">
<!-- Index Axis -->
<Line
:from="layoutConfig.indexAxis === 'x' ? [0, layoutConfig.height!] : [0, layoutConfig.height!]"
Expand Down
27 changes: 27 additions & 0 deletions extensions/chart/src/utils/useSimpleChart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineWidget } from '@vue-motion/core'
import type { Ref } from 'vue'
import { inject, provide, ref } from 'vue'

import type { BaseSimpleChartData, BaseSimpleChartOptions } from '../baseSimpleChart.vue'

Check failure on line 5 in extensions/chart/src/utils/useSimpleChart.ts

View workflow job for this annotation

GitHub Actions / type-check

Module '"*.vue"' has no exported member 'BaseSimpleChartData'. Did you mean to use 'import BaseSimpleChartData from "*.vue"' instead?

Check failure on line 5 in extensions/chart/src/utils/useSimpleChart.ts

View workflow job for this annotation

GitHub Actions / type-check

Module '"*.vue"' has no exported member 'BaseSimpleChartOptions'. Did you mean to use 'import BaseSimpleChartOptions from "*.vue"' instead?
import type { ChartLayoutConfig } from '../chartLayout.vue'

Check failure on line 6 in extensions/chart/src/utils/useSimpleChart.ts

View workflow job for this annotation

GitHub Actions / type-check

Module '"*.vue"' has no exported member 'ChartLayoutConfig'. Did you mean to use 'import ChartLayoutConfig from "*.vue"' instead?

export function useSimpleChart<T extends BaseSimpleChartOptions>(props: T) {
const options = defineWidget<T>(props)

let data = inject<Ref<BaseSimpleChartData>>('chartData')
data ??= ref<BaseSimpleChartData>({
labels: (options as BaseSimpleChartOptions).labels,
datasets: [],
})
provide('chartData', data)
let layoutConfig = inject<Ref<ChartLayoutConfig>>('chartLayoutConfig')
layoutConfig ??= ref<ChartLayoutConfig>({})
provide('chartLayoutConfig', layoutConfig)

return {
props,
options: options as ReturnType<typeof defineWidget<T>>,
data,
layoutConfig,
}
}

0 comments on commit 87012eb

Please sign in to comment.