Skip to content

Commit

Permalink
Refactored structure
Browse files Browse the repository at this point in the history
  • Loading branch information
victorgarciaesgi committed Feb 14, 2022
1 parent 6185f22 commit d11ba8a
Show file tree
Hide file tree
Showing 19 changed files with 250 additions and 128 deletions.
11 changes: 0 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,6 @@ This package is a rewrite of [vue-chartjs](https://github.com/apertureless/vue-c

[Full documentation](https://vue-chart-3.netlify.app/)

# ⚠️ Breaking changes and new versions numbers

In previous versions, `vue-demi` was used. It worked really well, but as the project advanced, they were a lot of problems with vue-related typescript definitions, tests and conflict between dependencies.

This new system will keep `vue-chart-3` working for both Vue 2 & 3 with designated versions (`2.x` and `3.x` respectively), but each one designed for their specific Vue version.

Code wise, there is not big breaking changes. But the Vue 3 version will have improved type checking for components template (with Volar extension).

For Vue 3 users, nothing changes.
For Vue 2 users, you will have to keep `2.x` version of `vue-chart-3`

# Installation

## For Vue 3
Expand Down
27 changes: 27 additions & 0 deletions docs/components/hooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,30 @@ Then you can use the `barChartProps` to fill the props of the component
```html
<BarChart v-bind="barChartProps" />
```

## Custom hook

If you have created a custom Chart component, you can also create your custom hook

```ts
import {defineChartComponent, defineChartHook} from 'vue-chart-3';

const MatrixChart = defineChartComponent('matrix-chart', 'matrix');
const useMatrixChart = defineChartHook('matrix');

export default defineComponent({
...,
components: {
MatrixChart
},
setup() {
const { matrixChartProps, matrixChartRef } = useMatrixChart({
chartData: {}, //...
plugins: []
});

return { matrixChartProps, matrixChartRef }
}
})

```
14 changes: 0 additions & 14 deletions docs/guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,6 @@

vue-chart-3 is rewrite of `vue-chartjs` for [Chart.js 3](https://www.chartjs.org/) for Vue 2 & 3, but written in Typescript and Vue Composition API.

::: warning

# Breaking changes and new versions numbers

In previous versions, `vue-demi` was used. It worked really well, but as the project advanced, they were a lot of problems with vue-related typescript definitions, tests and conflict between dependencies.

This new system will keep `vue-chart-3` working for both Vue 2 & 3 with designated versions (`2.x` and `3.x` respectively), but each one designed for their specific Vue version.

The usage of components of hooks is unchanged for both versions.

Code wise, there is not big breaking changes. But the Vue 3 version will have improved type checking for components template (with Volar extension).

:::

# Installation

## For Vue 3
Expand Down
29 changes: 15 additions & 14 deletions src/components.ts → src/core/component.builder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Chart, ChartData, ChartDataset, ChartOptions, ChartType, Plugin } from 'chart.js';
import * as Chartjs from 'chart.js';

import cloneDeep from 'lodash-es/cloneDeep';
import isEqual from 'lodash-es/isEqual';
import {
Expand All @@ -11,22 +10,24 @@ import {
onMounted,
PropType,
ref,
Ref,
shallowRef,
watch,
ShallowRef,
} from 'vue';
import { ChartPropsOptions } from './types';
import { pascalCase } from './utils';
import { StyleValue } from './vue.types';

export type ComponentData<T extends ChartType> = {
canvasRef: Ref<HTMLCanvasElement | undefined>;
renderChart: () => void;
chartInstance: ShallowRef<Chart<T> | null>;
canvasId: string;
};

import type { StyleValue } from '../misc';
import { pascalCase } from '../utils';
import type { ChartPropsOptions, ComponentData } from './component.types';

/** Builder method to create a component based on Chart.js chart type
*
* @param chartName the id of the chart component
* @param chartType the Chart.js chart type to use
*
* @example
*
* ```ts
* const MatrixChart = defineChartComponent('matrix-chart', 'matrix');
* ```
*/
export const defineChartComponent = <TType extends ChartType = ChartType>(
chartName: string,
chartType: TType
Expand Down
18 changes: 10 additions & 8 deletions src/types.ts → src/core/component.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { Chart, ChartData, Plugin, ChartType, ChartOptions } from 'chart.js';
import { PropType, Ref } from 'vue';
import { StyleValue } from './vue.types';
import { Chart, ChartData, ChartType, Plugin } from 'chart.js';
import { PropType, Ref, ShallowRef } from 'vue';
import { StyleValue } from '../misc';

export type ComponentData<T extends ChartType> = {
canvasRef: Ref<HTMLCanvasElement | undefined>;
renderChart: () => void;
chartInstance: ShallowRef<Chart<T> | null>;
canvasId: string;
};

export type ChartPropsOptions<TType extends ChartType> = {
options: { type: PropType<Record<string, any>>; required: false };
Expand All @@ -17,11 +24,6 @@ export type ChartPropsOptions<TType extends ChartType> = {
onChartRender: { type: PropType<(chartInstance: Chart<TType>) => void> };
};

export interface HookOptions<TType extends ChartType, TJSX = false>
extends ChartPropsOptions<TType> {
ref?: TJSX extends true ? Ref<any> : string;
}

export type ChartProps<TType extends ChartType> = {
options?: Record<any, any>;
chartId?: string;
Expand Down
2 changes: 2 additions & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './component.builder';
export * from './component.types';
65 changes: 65 additions & 0 deletions src/exports/component.exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { defineChartComponent } from '../core/component.builder';

/**
* A bar chart provides a way of showing data values represented as vertical bars. It is sometimes used to show trend data, and the comparison of multiple data sets side by side.
*
* {@link - https://www.chartjs.org/docs/latest/charts/bar.html}
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const BarChart = defineChartComponent('bar-chart', 'bar');

/**
* Pie and doughnut charts are probably the most commonly used charts. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
*
* {@link - https://www.chartjs.org/docs/latest/charts/doughnut.html }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const DoughnutChart = defineChartComponent('doughnut-chart', 'doughnut');

/**
* A line chart is a way of plotting data points on a line. Often, it is used to show trend data, or the comparison of two data sets.
*
* {@link - https://www.chartjs.org/docs/latest/charts/line.html }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const LineChart = defineChartComponent('line-chart', 'line');

/**
* Pie and doughnut charts are probably the most commonly used charts. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
*
* {@link - https://www.chartjs.org/docs/latest/charts/doughnut.html#pie }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const PieChart = defineChartComponent('pie-chart', 'pie');

/**
* Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.
*
* {@link - https://www.chartjs.org/docs/latest/charts/polar.html }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const PolarAreaChart = defineChartComponent('polar-chart', 'polarArea');

/**
* A radar chart is a way of showing multiple data points and the variation between them.
*
* {@link - https://www.chartjs.org/docs/latest/charts/radar.html }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const RadarChart = defineChartComponent('radar-chart', 'radar');

/**
* A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles.
*
* {@link - https://www.chartjs.org/docs/latest/charts/bubble.html }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const BubbleChart = defineChartComponent('bubble-chart', 'bubble');

/**
* Scatter charts are based on basic line charts with the x axis changed to a linear axis. To use a scatter chart, data must be passed as objects containing X and Y properties. The example below creates a scatter chart with 4 points.
*
* {@link - https://www.chartjs.org/docs/latest/charts/scatter.html }
* {@link - https://vue-chart-3.netlify.app/components/#list-of-all-components}
*/
export const ScatterChart = defineChartComponent('scatter-chart', 'scatter');
57 changes: 57 additions & 0 deletions src/exports/hooks.exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { defineChartHook } from '../hooks';

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const useDoughnutChart = defineChartHook('doughnut');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const useBarChart = defineChartHook('bar');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const useLineChart = defineChartHook('line');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const usePieChart = defineChartHook('pie');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const usePolarAreaChart = defineChartHook('polarArea');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const useRadarChart = defineChartHook('radar');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const useBubbleChart = defineChartHook('bubble');

/**
* {@link - https://vue-chart-3.netlify.app/components/hooks/#guide}
*
* ❗️ Still in beta, API can change in future updates
*/
export const useScatterChart = defineChartHook('scatter');
2 changes: 2 additions & 0 deletions src/exports/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './component.exports';
export * from './hooks.exports';
59 changes: 0 additions & 59 deletions src/hooks.ts

This file was deleted.

39 changes: 39 additions & 0 deletions src/hooks/hooks.builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Chart, ChartData, ChartType, Plugin } from 'chart.js';
import { computed, ref, unref } from 'vue';
import type { StyleValue } from '../misc';
import { MaybeRef } from '../utils';
import type { ChartHookReturnType } from './hooks.types';

export const defineChartHook = <TType extends ChartType = ChartType, TJSX = false>(
chartType: TType
) => {
return (params: {
chartData: MaybeRef<ChartData<TType>>;
options?: MaybeRef<Record<string, any>>;
width?: number;
height?: number;
cssClasses?: string;
styles?: StyleValue;
plugins?: Plugin[];
onLabelsUpdate?: () => void;
onChartUpdate?: (chartInstance: Chart<TType>) => void;
onChartDestroy?: () => void;
onChartRender?: (chartInstance: Chart<TType>) => void;
}): ChartHookReturnType<TType, TJSX> => {
const CHART_REF_NAME = `${chartType}ChartRef`;
const jsxRef = {
[CHART_REF_NAME]: ref(null),
};
const reactiveProps = computed(() => ({
...params,
ref: CHART_REF_NAME,
chartData: unref(params.chartData),
options: unref(params.options),
}));

return {
[`${chartType}ChartProps`]: reactiveProps,
[CHART_REF_NAME]: ref(null),
};
};
};
19 changes: 19 additions & 0 deletions src/hooks/hooks.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { ChartType } from 'chart.js';
import type { ComponentPublicInstance, ExtractPropTypes, Ref } from 'vue';
import type { ChartPropsOptions, ComponentData } from '../core';

export interface HookOptions<TType extends ChartType, TJSX = false>
extends ChartPropsOptions<TType> {
ref?: TJSX extends true ? Ref<any> : string;
}

type DumbTypescript = 0;

export type ChartHookReturnType<TType extends ChartType, TJSX = false> = {
[K in DumbTypescript as `${TType}ChartRef`]: Ref<ComponentPublicInstance<
ChartPropsOptions<TType>,
ComponentData<TType>
> | null>;
} & {
[K in DumbTypescript as `${TType}ChartProps`]: Ref<ExtractPropTypes<HookOptions<TType, TJSX>>>;
};
2 changes: 2 additions & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './hooks.builder';
export * from './hooks.types';
Loading

0 comments on commit d11ba8a

Please sign in to comment.