Skip to content

Commit

Permalink
feat(chart): add documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
adenvt committed Sep 6, 2022
1 parent 6090011 commit a33dff9
Show file tree
Hide file tree
Showing 7 changed files with 348 additions and 71 deletions.
37 changes: 24 additions & 13 deletions components/chart/Chart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,18 @@ import {
watch,
PropType,
shallowRef,
onBeforeUpdate,
onBeforeUnmount,
toRef,
computed,
} from 'vue-demi'
import loadData from './adapter/index'
export type TypeVariant = 'bar' | 'line' | 'pie'
import getAdapter, { ChartType } from './adapter/index'
export type LegendPosition = 'none' | LayoutPosition
export default defineComponent({
props: {
variant: {
type : String as PropType<TypeVariant>,
type : String as PropType<ChartType>,
default: 'line',
},
legend: {
Expand All @@ -43,24 +41,44 @@ export default defineComponent({
const variant = toRef(props, 'variant')
const legend = toRef(props, 'legend')
const data = computed(() => {
return getAdapter(variant.value).getDatasets(slots.default())
})
function createChart () {
if (instance.value)
instance.value.destroy()
instance.value = new Chart(canvas.value, {
type : variant.value,
data : loadData(variant.value, slots.default()),
data : data.value,
options: {
plugins: {
legend: {
display : legend.value !== 'none',
position: legend.value !== 'none' ? legend.value : undefined,
labels : {
color: '#9CA3AF',
font : {
family: 'DM Sans',
size : 12,
weight: '600',
},
},
},
},
...getAdapter(variant.value).getStyle(),
},
})
}
watch(data, (newData) => {
if (instance.value) {
instance.value.data = newData
instance.value.update()
}
})
watch([variant, legend], () => {
createChart()
})
Expand All @@ -69,13 +87,6 @@ export default defineComponent({
createChart()
})
onBeforeUpdate(() => {
if (instance.value) {
instance.value.data = loadData(variant.value, slots.default())
instance.value.update()
}
})
onBeforeUnmount(() => {
if (instance.value)
instance.value.destroy()
Expand Down
2 changes: 1 addition & 1 deletion components/chart/ChartSet.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default defineComponent({
name : 'ChartSet',
props: {
name: {
type : String,
type : [String, Number],
required: true,
},
},
Expand Down
2 changes: 1 addition & 1 deletion components/chart/ChartVal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default defineComponent({
name : 'ChartVal',
props: {
name: {
type : String,
type : [String, Number],
required: true,
},
value: {
Expand Down
17 changes: 13 additions & 4 deletions components/chart/adapter/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { ChartData } from 'chart.js/auto'
import { ChartData, ChartOptions } from 'chart.js/auto'
import { VNode } from 'vue-demi'
import Line from './line'
import Pie from './pie'

export type ChartType = 'line' | 'bar' | 'pie'

const CHART_ADAPTER_MAP: Record<ChartType, (vnode: VNode[]) => ChartData> = {
export interface ChartAdapter {
getStyle: () => ChartOptions,
getDatasets: (vnodes: VNode[]) => ChartData,
}

const CHART_ADAPTER_MAP: Record<ChartType, ChartAdapter> = {
line: Line,
bar : Line,
pie : Pie,
}

export default function getDatasets (type: ChartType, vnodes: VNode[]): ChartData {
return CHART_ADAPTER_MAP[type](vnodes)
export function defineAdapter (adapter: ChartAdapter): ChartAdapter {
return adapter
}

export default function getAdapter (type: ChartType): ChartAdapter {
return CHART_ADAPTER_MAP[type]
}
83 changes: 59 additions & 24 deletions components/chart/adapter/line.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,72 @@
import { ChartDataset, ChartData } from 'chart.js'
import { startCase } from 'lodash'
import { Slots, VNode } from 'vue-demi'
import { defineAdapter } from '.'
import { colorHash } from '../../avatar/utils/color-hash'
import { findAllChildren } from '../../utils/vnode'

export default function getDatasets (vnodes: VNode[]): ChartData {
const sets = findAllChildren(vnodes, 'ChartSet')
const datasets = new Map<string, ChartDataset>()
const labels = [] as string[]
export default defineAdapter({
getDatasets (vnodes: VNode[]): ChartData {
const sets = findAllChildren(vnodes, 'ChartSet')
const datasets = new Map<string, ChartDataset>()
const labels = [] as string[]

for (const set of sets) {
const values = findAllChildren((set.children as Slots).default(), 'ChartVal')
for (const set of sets) {
const values = findAllChildren((set.children as Slots).default(), 'ChartVal')

for (const value of values) {
const item = datasets.get(value.props.name)
const color = value.props.color ?? colorHash(value.props.name).at(1)
for (const value of values) {
const item = datasets.get(value.props.name)
const color = value.props.color ?? colorHash(value.props.name).at(1)

if (item) {
item.data.push(value.props.value);
(item.borderColor as string[]).push(color);
(item.backgroundColor as string[]).push(color)
} else {
datasets.set(value.props.name, {
label : startCase(value.props.name),
data : [value.props.value],
borderColor : [color],
backgroundColor: [color],
})
if (item) {
item.data.push(value.props.value);
(item.borderColor as string[]).push(color);
(item.backgroundColor as string[]).push(color)
} else {
datasets.set(value.props.name, {
label : startCase(value.props.name),
data : [value.props.value],
borderColor : [color],
backgroundColor: [color],
})
}
}

labels.push(startCase(set.props.name))
}

labels.push(startCase(set.props.name))
}
return { labels, datasets: [...datasets.values()] }
},

return { labels, datasets: [...datasets.values()] }
}
getStyle () {
return {
scales: {
x: {
ticks: {
color: '#9CA3AF',
font : {
family: 'DM Sans',
size : 12,
weight: '600',
},
},
grid: { borderColor: '#BFBFBF' },
},
y: {
ticks: {
color: '#9CA3AF',
font : {
family: 'DM Sans',
size : 12,
weight: '600',
},
},
grid: {
borderColor: '#BFBFBF',
borderDash : [4],
},
},
},
}
},
})
53 changes: 30 additions & 23 deletions components/chart/adapter/pie.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
import { ChartData, ChartDataset } from 'chart.js'
import { startCase } from 'lodash'
import { Slots, VNode } from 'vue-demi'
import { defineAdapter } from '.'
import { colorHash } from '../../avatar/utils/color-hash'
import { findAllChildren } from '../../utils/vnode'

export default function getDatasets (vnodes: VNode[]): ChartData {
const sets = findAllChildren(vnodes, 'ChartSet')
const datasets = new Map<string, ChartDataset>()
const labels = [] as string[]
export default defineAdapter({
getDatasets (vnodes: VNode[]): ChartData {
const sets = findAllChildren(vnodes, 'ChartSet')
const datasets = new Map<string, ChartDataset>()
const labels = [] as string[]

for (const set of sets) {
const values = findAllChildren((set.children as Slots).default(), 'ChartVal')
for (const set of sets) {
const values = findAllChildren((set.children as Slots).default(), 'ChartVal')

for (const value of values) {
const item = datasets.get(set.props.name)
const color = value.props.color ?? colorHash(value.props.name).at(1)
for (const value of values) {
const item = datasets.get(set.props.name)
const color = value.props.color ?? colorHash(value.props.name).at(1)

if (item) {
item.data.push(value.props.value);
(item.backgroundColor as string[]).push(color)
} else {
datasets.set(set.props.name, {
label : startCase(set.props.name),
data : [value.props.value],
backgroundColor: [color],
})
}
if (item) {
item.data.push(value.props.value);
(item.backgroundColor as string[]).push(color)
} else {
datasets.set(set.props.name, {
label : startCase(set.props.name),
data : [value.props.value],
backgroundColor: [color],
})
}

labels.push(startCase(value.props.name))
labels.push(startCase(value.props.name))
}
}
}

return { labels, datasets: [...datasets.values()] }
}
return { labels, datasets: [...datasets.values()] }
},

getStyle () {
return {}
},
})
Loading

0 comments on commit a33dff9

Please sign in to comment.