├── .browserslistrc
├── .gitignore
├── .prettierignore
├── README.md
├── babel.config.js
├── index.js
├── index.ts
├── jest.config.js
├── package-lock.json
├── package.json
├── prettier.config.js
├── public
├── favicon.ico
└── index.html
├── src
├── App.tsx
├── App.vue
├── assets
│ ├── bar.png
│ ├── bubble.png
│ ├── doughnut.png
│ ├── line.png
│ ├── logo.png
│ ├── pie.png
│ ├── polar.png
│ ├── radar.png
│ └── scatter.png
├── components
│ ├── BaseChart.js
│ ├── BaseChart.tsx
│ ├── BaseChart.vue
│ ├── Chart.vue
│ ├── RandomChart.vue
│ ├── example
│ │ └── ChartWthLocalData.vue
│ └── minxins.ts
├── main.ts
├── shims-tsx.d.ts
└── shims-vue.d.ts
├── tests
└── unit
│ └── example.spec.ts
└── tsconfig.json
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | src/assets
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue3-chart-v2
2 | vue3-chart-v2 is a wrapper for [Chart.js](https://github.com/chartjs/Chart.js) in Vue 3. You can easily create reuseable chart components. Inspired by vue-chartjs
3 |
4 | [](https://www.npmjs.com/package/vue3-chart-v2)
5 |
6 | ## Looking for the documentation?
7 | Head over here ==> [vue3-chart-v2](https://vue3-chart-v2.netlify.app/)
8 |
9 | ## Prerequisite
10 | - Vue 3 is required
11 |
12 | ## Install
13 |
14 | - **npm** `npm install vue3-chart-v2 chart.js --save`
15 | - **yarn** `yarn add vue3-chart-v2 chart.js`
16 |
17 | ## How to use
18 |
19 | You need to import the component and then either use `extends` or `mixins` and add it.
20 |
21 | You can import each module individual.
22 |
23 | ```js
24 | import { Bar } from 'vue3-chart-v2'
25 | ```
26 |
27 | Just create your own component.
28 |
29 | // MonthlyChart.vue
30 | ```vue
31 |
53 | ```
54 |
55 | Then simply import and use your own extended component and use it like a normal vue component
56 |
57 | ```vue
58 |
59 |
60 |
61 |
62 |
73 | ```
74 | ## Another Example with options
75 | You can overwrite the default chart options as props. Just pass the options object as a second parameter to the render method
76 |
77 | ```js
78 | // MonthlyChart.vue
79 | import { defineComponent } from 'vue'
80 | import { Line } from 'vue3-chart-v2'
81 |
82 | export default defineComponent({
83 | name: 'MonthlyChart',
84 | extends: Line,
85 | props: {
86 | chartData: {
87 | type: Object,
88 | required: true
89 | },
90 | chartOptions: {
91 | type: Object,
92 | required: false
93 | },
94 | },
95 | mounted () {
96 | this.renderChart(this.chartData, this.chartOptions)
97 | }
98 | })
99 | ```
100 |
101 | Then simply use it in your vue app
102 |
103 | ```vue
104 |
105 |
106 |
107 |
108 |
119 | ```
120 | ## Available Charts
121 |
122 | ### Bar Chart
123 |
124 | 
125 |
126 | ### Line Chart
127 |
128 | 
129 |
130 | ### Doughnut
131 |
132 | 
133 |
134 | ### Pie
135 |
136 | 
137 |
138 | ### Radar
139 |
140 | 
141 |
142 | ### Polar Area
143 |
144 | 
145 |
146 | ### Bubble
147 |
148 | 
149 |
150 | ### Scatter
151 |
152 | 
153 |
154 | ## Build Setup
155 |
156 | ``` bash
157 | # install dependencies
158 | npm install
159 |
160 | # serve with hot reload at localhost:8080
161 | npm run dev
162 |
163 | # run unit tests
164 | npm run test:unit
165 | ```
166 |
167 | ## Contributing
168 |
169 | 1. Fork it (https://github.com/vutran6853/vue3-chart-v2/fork )
170 | 2. Create your feature branch (`git checkout -b my-new-feature`)
171 | 3. Commit your changes (`git commit -m 'Add some feature'`)
172 | 4. Push to the branch (`git push origin my-new-feature`)
173 | 5. Create a new Pull Request
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import {
2 | Bar,
3 | Bubble,
4 | Doughnut,
5 | HorizontalBar,
6 | Line,
7 | Pie,
8 | PolarArea,
9 | Radar,
10 | Scatter,
11 | generateChart
12 | } from './src/components/BaseChart'
13 |
14 | export {
15 | Bar,
16 | Bubble,
17 | Doughnut,
18 | HorizontalBar,
19 | Line,
20 | Pie,
21 | PolarArea,
22 | Radar,
23 | Scatter,
24 | generateChart
25 | // renderChart
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Bar,
3 | Bubble,
4 | Doughnut,
5 | HorizontalBar,
6 | Line,
7 | Pie,
8 | PolarArea,
9 | Radar,
10 | Scatter,
11 | generateChart
12 | } from './src/components/BaseChart'
13 |
14 | export {
15 | Bar,
16 | Bubble,
17 | Doughnut,
18 | HorizontalBar,
19 | Line,
20 | Pie,
21 | PolarArea,
22 | Radar,
23 | Scatter,
24 | generateChart
25 | // renderChart
26 | }
27 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
3 | transform: {
4 | '^.+\\.vue$': 'vue-jest'
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue3-chart-v2",
3 | "version": "0.8.3",
4 | "private": false,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "test:unit": "vue-cli-service test:unit",
9 | "prettier:src": "npx prettier -w src/**"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/vutran6853/vue3-chart-v2"
14 | },
15 | "keywords": [
16 | "ChartJs",
17 | "Vue3-chart",
18 | "wrapper",
19 | "Vue 3"
20 | ],
21 | "dependencies": {
22 | "@types/chart.js": "^2.9.29",
23 | "chart.js": "^2.9.4",
24 | "core-js": "^3.6.5",
25 | "prettier": "^2.2.1",
26 | "vue": "^3.0.0"
27 | },
28 | "devDependencies": {
29 | "@types/jest": "^24.0.19",
30 | "@vue/cli-plugin-babel": "~4.5.0",
31 | "@vue/cli-plugin-typescript": "~4.5.0",
32 | "@vue/cli-plugin-unit-jest": "~4.5.0",
33 | "@vue/cli-service": "~4.5.0",
34 | "@vue/compiler-sfc": "^3.0.0",
35 | "@vue/test-utils": "^2.0.0-0",
36 | "typescript": "~3.9.3",
37 | "vue-jest": "^5.0.0-0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | tabWidth: 2,
3 | semi: false,
4 | printWidth: 120,
5 | bracketSpacing: true,
6 | jsxBracketSameLine: true,
7 | trailingComma: 'none',
8 | arrowParens: 'always',
9 | singleQuote: true
10 | }
11 |
12 | module.exports = config
13 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { defineComponent, VNode } from 'vue'
2 | // import { Pie, Doughnut, Bubble, Line } from './components/BaseChart'
3 | import Chart from './components/Chart.vue'
4 | // import RandomChart from './components/RandomChart.vue'
5 |
6 | interface IAppState {
7 | chartData: {
8 | labels?: string[]
9 | datasets?: [
10 | {
11 | label?: string
12 | backgroundColor?: string
13 | data?: number[]
14 | }
15 | ]
16 | }
17 | dataCollection: {}
18 | chartOptions: {
19 | responsive?: boolean
20 | maintainAspectRatio?: boolean
21 | height?: number
22 | intersect?: boolean
23 | hover?: any
24 | tooltips?: any
25 | layout?: any
26 | pointHoverRadius?: any
27 | }
28 | height: number
29 | }
30 |
31 | export default defineComponent({
32 | name: 'App',
33 | data(): IAppState {
34 | return {
35 | chartData: {
36 | labels: ['January', 'February'],
37 | datasets: [
38 | {
39 | label: 'Data One',
40 | backgroundColor: '#f87979',
41 | data: [40, 20]
42 | }
43 | ]
44 | },
45 | dataCollection: {},
46 | chartOptions: {
47 | responsive: true,
48 | maintainAspectRatio: false
49 | },
50 | height: 500
51 | }
52 | },
53 | beforeMount() {
54 | this.fillData()
55 | },
56 | methods: {
57 | fillData() {
58 | this.dataCollection = {
59 | labels: ['Red', 'Blue'],
60 | datasets: [
61 | {
62 | label: 'Data One',
63 | data: [this.getRandomInt(), this.getRandomInt()],
64 | backgroundColor: ['red', 'blue'],
65 | borderColor: ['red', 'blue'],
66 | borderWidth: 1
67 | }
68 | ]
69 | // labels: [this.getRandomInt(), this.getRandomInt()],
70 | // datasets: [
71 | // {
72 | // label: 'Data One',
73 | // backgroundColor: '#f87979',
74 | // data: [this.getRandomInt(), this.getRandomInt()]
75 | // }, {
76 | // label: 'Data One',
77 | // backgroundColor: '#f87979',
78 | // data: [this.getRandomInt(), this.getRandomInt()]
79 | // }
80 | // ]
81 | }
82 | },
83 | getRandomInt() {
84 | return Math.floor(Math.random() * (20 - 5))
85 | },
86 | increase() {
87 | this.height += 10
88 | }
89 | },
90 | computed: {
91 | myStyles(): { height?: string; position?: string; border?: string } {
92 | return {
93 | height: `${this.height}px`,
94 | border: `2px solid red`,
95 | position: 'relative'
96 | }
97 | }
98 | },
99 | render(): VNode {
100 | return (
101 |
102 | {/*
app tsx
*/}
103 | {/* */}
104 |
105 |
106 |
107 |
108 | )
109 | }
110 | })
111 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
hello wolrd
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
106 |
--------------------------------------------------------------------------------
/src/assets/bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/bar.png
--------------------------------------------------------------------------------
/src/assets/bubble.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/bubble.png
--------------------------------------------------------------------------------
/src/assets/doughnut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/doughnut.png
--------------------------------------------------------------------------------
/src/assets/line.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/line.png
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/pie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/pie.png
--------------------------------------------------------------------------------
/src/assets/polar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/polar.png
--------------------------------------------------------------------------------
/src/assets/radar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/radar.png
--------------------------------------------------------------------------------
/src/assets/scatter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vutran6853/vue3-chart-v2/8fcb80798815a1043975bd1b08c0709530a4ca6e/src/assets/scatter.png
--------------------------------------------------------------------------------
/src/components/BaseChart.js:
--------------------------------------------------------------------------------
1 | import Chart from 'chart.js'
2 | import { defineComponent, h, reactive } from 'vue'
3 |
4 | function useChartInfo() {
5 | const state = reactive({
6 | myName: '',
7 | userData: {},
8 | userOptions: {}
9 | })
10 |
11 | function setChartData(payload) {
12 | state.userData = payload
13 | }
14 |
15 | function setChartOption(payload) {
16 | state.userOptions = payload
17 | }
18 |
19 | return {
20 | state,
21 | setChartData,
22 | setChartOption
23 | }
24 | }
25 |
26 | /**
27 | *
28 | * @param chartsId string
29 | * @param chartsType string
30 | */
31 | function generateChart(chartsId, chartsType) {
32 | let { state, setChartData, setChartOption } = useChartInfo()
33 |
34 | return defineComponent({
35 | name: 'BaseChart',
36 | props: {
37 | chartId: {
38 | type: String,
39 | required: false
40 | },
41 | chartType: {
42 | type: String,
43 | required: false
44 | },
45 | width: {
46 | type: Number,
47 | required: false,
48 | default: 400
49 | },
50 | height: {
51 | type: Number,
52 | required: false,
53 | default: 400
54 | },
55 | cssClasses: {
56 | type: String,
57 | required: false,
58 | default: ''
59 | },
60 | styles: {
61 | type: Object,
62 | required: false
63 | }
64 | },
65 | data() {
66 | return {
67 | state: {
68 | chartObj: null
69 | }
70 | }
71 | },
72 | // emits: ['chart:update'],
73 |
74 | beforeUnmount() {
75 | if (this.state.chartObj) {
76 | this.state.chartObj.destroy()
77 | }
78 | },
79 | methods: {
80 | renderChart(userData, userOptions) {
81 | setChartData(userData)
82 | setChartOption(userOptions)
83 |
84 | if (this.state.chartObj) {
85 | // this.state.chartObj.destroy()
86 | }
87 | // if (!this.$refs.canvas) {
88 | // throw new Error('Please remove the tags from your chart component. See https://vue-chartjs.org/guide/#vue-single-file-components')
89 | // }
90 |
91 | // REMOVE OLD DATA FIRST BEFORE UPDATE.
92 | if (this.state.chartObj != null && this.state.chartObj.data != null) { this.state.chartObj.data.datasets.pop() }
93 |
94 | let ctx = this.$refs.canvas.getContext('2d')
95 | this.state.chartObj = new Chart(ctx, {
96 | type: chartsType,
97 | data: userData,
98 | options: userOptions
99 | // plugins: this.$data._plugins
100 | })
101 | }
102 | },
103 | beforeMount() {
104 | if (document.getElementById(chartsId)) {
105 | let ctx = document.getElementById(chartsId).getContext('2d')
106 | this.state.chartObj = new Chart(ctx, {
107 | type: chartsType,
108 | data: {
109 | datasets: [
110 | {
111 | data: [1, 2, 3, 4],
112 | backgroundColor: ['Red', 'Yellow', 'Blue', 'Green']
113 | }
114 | ],
115 | // These labels appear in the legend and in the tooltips when hovering different arcs
116 | labels: ['Red', 'Yellow', 'Blue', 'Green']
117 | },
118 | options: {
119 | responsive: false
120 | }
121 | // options: this.options,
122 | // plugins: this.$data._plugins
123 | })
124 | }
125 | },
126 | computed: {
127 | currentChartData() {
128 | return state.userData
129 | },
130 | currentChartOption() {
131 | return state.userOptions
132 | }
133 | },
134 | watch: {
135 | chartData(prevState, newState) {
136 | if (prevState !== newState) {
137 | this.renderChart(newState, this.currentChartOption)
138 | }
139 | }
140 | },
141 | render() {
142 | // return h('canvas', {
143 | // ref: 'canvas',
144 | // id: this.chartId,
145 | // width: this.width,
146 | // height: this.height
147 | // })
148 | return h('div', { style: this.styles, class: this.cssClasses }, [
149 | h('canvas', {
150 | ref: 'canvas',
151 | id: this.chartId,
152 | width: this.width,
153 | height: this.height
154 | })
155 | ])
156 | }
157 | })
158 | }
159 |
160 | const Bar = generateChart('bar-chart', 'bar')
161 | const Bubble = generateChart('bubble-chart', 'bubble')
162 | const Doughnut = generateChart('doughnut-chart', 'doughnut')
163 | const HorizontalBar = generateChart('horizontalbar-chart', 'horizontalBar')
164 | const Line = generateChart('line-chart', 'line')
165 | const Pie = generateChart('pie-chart', 'pie')
166 | const PolarArea = generateChart('polar-chart', 'polarArea')
167 | const Radar = generateChart('radar-chart', 'radar')
168 | const Scatter = generateChart('scatter-chart', 'scatter')
169 |
170 | export {
171 | Bar,
172 | Bubble,
173 | Doughnut,
174 | HorizontalBar,
175 | Line,
176 | Pie,
177 | PolarArea,
178 | Radar,
179 | Scatter,
180 | generateChart
181 | // renderChart
182 | }
183 |
--------------------------------------------------------------------------------
/src/components/BaseChart.tsx:
--------------------------------------------------------------------------------
1 | import Chart from 'chart.js'
2 | import { defineComponent, h, reactive } from 'vue'
3 |
4 | // interface IBaseChart {
5 | // width: number,
6 | // height: number,
7 | // chartObj: any,
8 | // chartType: any
9 | // }
10 |
11 | interface IBaseChart {
12 | state: {
13 | chartObj?: Chart | null
14 | }
15 | }
16 |
17 | type IBaseChartProps = {
18 | chartId: string
19 | chartType: string
20 | width: number
21 | height: number
22 | cssClasses: string
23 | styles: string
24 | plugins: any[]
25 | }
26 |
27 | interface IState {
28 | myName: string
29 | userData: {}
30 | userOptions: {}
31 | }
32 |
33 | function useChartInfo() {
34 | const state: IState = reactive({
35 | myName: '',
36 | userData: {},
37 | userOptions: {}
38 | })
39 |
40 | function setChartData(payload: {}) {
41 | state.userData = payload
42 | }
43 |
44 | function setChartOption(payload: {}) {
45 | state.userOptions = payload
46 | }
47 |
48 | return {
49 | state,
50 | setChartData,
51 | setChartOption
52 | }
53 | }
54 |
55 | /**
56 | *
57 | * @param chartsId string
58 | * @param chartsType string
59 | */
60 | function generateChart(chartsId: string, chartsType: string) {
61 | let { state, setChartData, setChartOption } = useChartInfo()
62 |
63 | return defineComponent({
64 | name: 'BaseChart',
65 | props: {
66 | chartId: {
67 | type: String,
68 | required: false
69 | },
70 | chartType: {
71 | type: String,
72 | required: false
73 | },
74 | width: {
75 | type: Number,
76 | required: false
77 | // default: 400
78 | },
79 | height: {
80 | type: Number,
81 | required: false
82 | // default: 400
83 | },
84 | cssClasses: {
85 | type: String,
86 | required: false,
87 | default: ''
88 | },
89 | styles: {
90 | type: Object,
91 | required: false
92 | }
93 | },
94 | data(): IBaseChart {
95 | return {
96 | state: {
97 | chartObj: null
98 | }
99 | }
100 | },
101 | // emits: ['chart:update'],
102 |
103 | beforeUnmount() {
104 | if (this.state.chartObj) {
105 | this.state.chartObj.destroy()
106 | }
107 | },
108 | methods: {
109 | renderChart(userData: any, userOptions: any) {
110 | setChartData(userData)
111 | setChartOption(userOptions)
112 | if (this.state.chartObj) {
113 | // this.state.chartObj.destroy()
114 | // setChartData({})
115 | // setChartOption({})
116 | }
117 | // if (!this.$refs.canvas) {
118 | // throw new Error('Please remove the tags from your chart component. See https://vue-chartjs.org/guide/#vue-single-file-components')
119 | // }
120 |
121 | // REMOVE OLD DATA FIRST BEFORE UPDATE.
122 | if (this.state.chartObj != null && this.state.chartObj.data != null) {
123 | if (this.state.chartObj.data.datasets) {
124 | this.state.chartObj.data.datasets.pop()
125 | }
126 | }
127 |
128 | let ctx = (this as any).$refs.canvas.getContext('2d')
129 | this.state.chartObj = new Chart(ctx, {
130 | type: chartsType,
131 | data: userData,
132 | options: userOptions
133 | // plugins: this.$data._plugins
134 | })
135 | this.state.chartObj.update()
136 | }
137 | },
138 | beforeMount() {
139 | if ((document as any).getElementById(chartsId)) {
140 | let ctx = (document as any).getElementById(chartsId).getContext('2d')
141 | this.state.chartObj = new Chart(ctx, {
142 | type: chartsType,
143 | data: {
144 | datasets: [
145 | {
146 | data: [1, 2, 3, 4],
147 | backgroundColor: ['Red', 'Yellow', 'Blue', 'Green']
148 | }
149 | ],
150 | // These labels appear in the legend and in the tooltips when hovering different arcs
151 | labels: ['Red', 'Yellow', 'Blue', 'Green']
152 | },
153 | options: {
154 | responsive: false
155 | }
156 | // options: this.options,
157 | // plugins: this.$data._plugins
158 | })
159 | this.state.chartObj.update()
160 | }
161 | },
162 | computed: {
163 | currentChartData(): any {
164 | return state.userData
165 | },
166 | currentChartOption(): any {
167 | return state.userOptions
168 | }
169 | },
170 | watch: {
171 | chartData(prevState, newState) {
172 | if (prevState !== newState) {
173 | this.renderChart(newState, this.currentChartOption)
174 | }
175 | }
176 | },
177 | render() {
178 | return (
179 |
180 |
181 |
182 | )
183 | }
184 | })
185 | }
186 |
187 | const Bar = generateChart('bar-chart', 'bar')
188 | const Bubble = generateChart('bubble-chart', 'bubble')
189 | const Doughnut = generateChart('doughnut-chart', 'doughnut')
190 | const HorizontalBar = generateChart('horizontalbar-chart', 'horizontalBar')
191 | const Line = generateChart('line-chart', 'line')
192 | const Pie = generateChart('pie-chart', 'pie')
193 | const PolarArea = generateChart('polar-chart', 'polarArea')
194 | const Radar = generateChart('radar-chart', 'radar')
195 | const Scatter = generateChart('scatter-chart', 'scatter')
196 |
197 | export {
198 | Bar,
199 | Bubble,
200 | Doughnut,
201 | HorizontalBar,
202 | Line,
203 | Pie,
204 | PolarArea,
205 | Radar,
206 | Scatter,
207 | generateChart
208 | // renderChart
209 | }
210 |
--------------------------------------------------------------------------------
/src/components/BaseChart.vue:
--------------------------------------------------------------------------------
1 |
195 |
--------------------------------------------------------------------------------
/src/components/Chart.vue:
--------------------------------------------------------------------------------
1 |
44 |
--------------------------------------------------------------------------------
/src/components/RandomChart.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
50 |
51 |
57 |
--------------------------------------------------------------------------------
/src/components/example/ChartWthLocalData.vue:
--------------------------------------------------------------------------------
1 |
32 |
--------------------------------------------------------------------------------
/src/components/minxins.ts:
--------------------------------------------------------------------------------
1 | import { defineComponent } from 'vue'
2 |
3 | function dataHandler(this: { chartData: (newData: any, oldData: any) => void }, newData: any, oldData: any) {
4 | if (oldData) {
5 | let chart = (this as any).chartData
6 | // Get new and old DataSet Labels
7 | let newDatasetLabels = newData.datasets.map((dataset: any) => {
8 | return dataset.label
9 | })
10 |
11 | let oldDatasetLabels = oldData.datasets.map((dataset: any) => {
12 | return dataset.label
13 | })
14 |
15 | // Stringify 'em for easier compare
16 | const oldLabels = JSON.stringify(oldDatasetLabels)
17 | const newLabels = JSON.stringify(newDatasetLabels)
18 |
19 | // Check if Labels are equal and if dataset length is equal
20 | if (newLabels === oldLabels && oldData.datasets.length === newData.datasets.length) {
21 | newData.datasets.forEach((dataset: any, index: any) => {
22 | // Get new and old dataset keys
23 | const oldDatasetKeys = Object.keys(oldData.datasets[index])
24 | const newDatasetKeys = Object.keys(dataset)
25 |
26 | // Get keys that aren't present in the new data
27 | const deletionKeys = oldDatasetKeys.filter((key) => {
28 | return key !== '_meta' && newDatasetKeys.indexOf(key) === -1
29 | })
30 |
31 | // Remove outdated key-value pairs
32 | deletionKeys.forEach((deletionKey) => {
33 | delete chart.data.datasets[index][deletionKey]
34 | })
35 |
36 | // Update attributes individually to avoid re-rendering the entire chart
37 | for (const attribute in dataset) {
38 | if (dataset.hasOwnProperty(attribute)) {
39 | chart.datasets[index][attribute] = dataset[attribute]
40 | }
41 | }
42 | })
43 |
44 | if (newData.hasOwnProperty('labels')) {
45 | chart.labels = newData.labels
46 | // (this as any).$emit('labels:update') // TODO: FIX
47 | }
48 | if (newData.hasOwnProperty('xLabels')) {
49 | chart.xLabels = newData.xLabels(this as any).$emit('xlabels:update') // TODO: FIX
50 | }
51 | if (newData.hasOwnProperty('yLabels')) {
52 | chart.yLabels = newData.yLabels(this as any).$emit('ylabels:update') // TODO: FIX
53 | }
54 | // console.log('(this as any).$root(this as any).$root', (this as any).$nextTick())
55 | // (this as any).$root.updated
56 | console.log('(this as any).$.data.state.localChartData', (this as any).$.data.state.chartObj)
57 | console.log('this.$', (this as any).$.data.state.chartObj)
58 | // (this as any).$.data.state.localChartData.clear()
59 | // console.log('this', (this as any))
60 | // (this as any).$emit('chart:update') // TODO: FIX
61 | } else {
62 | if (chart) {
63 | chart
64 | .destroy()(this as any)
65 | .$emit('chart:destroy')
66 | }
67 | ;(this as any)
68 | .renderChart(
69 | this.chartData,
70 | (this as any).options
71 | )(this as any)
72 | .$emit('chart:render')
73 | }
74 | } else {
75 | if ((this as any).chartData) {
76 | ;(this as any).chartData
77 | .destroy()(this as any)
78 | .$emit('chart:destroy')
79 | }
80 | ;(this as any)
81 | .renderChart(
82 | this.chartData,
83 | (this as any).options
84 | )(this as any)
85 | .$emit('chart:render')
86 | }
87 | }
88 |
89 | const reactiveData = defineComponent({
90 | data() {
91 | return {
92 | chartData: null
93 | }
94 | },
95 | watch: {
96 | chartData: dataHandler
97 | }
98 | })
99 |
100 | const reactiveProp = defineComponent({
101 | props: {
102 | chartData: {
103 | type: Object,
104 | required: false,
105 | default: () => {}
106 | }
107 | },
108 | computed: {
109 | getme(): any {
110 | return this.chartData
111 | }
112 | }
113 | // watch: {
114 | // chartData: dataHandler
115 | // },
116 | // watch: {
117 | // 'chartData' (prevState, newState) {
118 | // if (prevState !== newState) {
119 | // console.log(true)
120 | // } else {
121 | // console.log(false)
122 | // }
123 | // }
124 | // }
125 | })
126 |
127 | export { reactiveData, reactiveProp }
128 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App'
3 |
4 | const app = createApp(App)
5 |
6 | app.mount('#app')
7 |
--------------------------------------------------------------------------------
/src/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from 'vue'
2 |
3 | declare global {
4 | namespace JSX {
5 | // tslint:disable no-empty-interface
6 | interface Element extends VNode {}
7 | // tslint:disable no-empty-interface
8 | interface ElementClass extends Vue {}
9 | interface IntrinsicElements {
10 | [elem: string]: any
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | declare module '*.vue' {
3 | import type { DefineComponent } from 'vue'
4 | const component: DefineComponent<{}, {}, any>
5 | export default component
6 | }
7 |
--------------------------------------------------------------------------------
/tests/unit/example.spec.ts:
--------------------------------------------------------------------------------
1 | import { shallowMount } from '@vue/test-utils'
2 | import HelloWorld from '@/components/HelloWorld.vue'
3 |
4 | describe('HelloWorld.vue', () => {
5 | it('renders props.msg when passed', () => {
6 | const msg = 'new message'
7 | const wrapper = shallowMount(HelloWorld, {
8 | props: { msg }
9 | })
10 | expect(wrapper.text()).toMatch(msg)
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext",
4 | "module": "esnext",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "skipLibCheck": true,
10 | "esModuleInterop": true,
11 | "allowSyntheticDefaultImports": true,
12 | "sourceMap": true,
13 | "baseUrl": ".",
14 | "types": [
15 | "webpack-env",
16 | "jest"
17 | ],
18 | "paths": {
19 | "@/*": [
20 | "src/*"
21 | ]
22 | },
23 | "lib": [
24 | "esnext",
25 | "dom",
26 | "dom.iterable",
27 | "scripthost"
28 | ]
29 | },
30 | "include": [
31 | "src/**/*.ts",
32 | "src/**/*.tsx",
33 | "src/**/*.vue",
34 | "tests/**/*.ts",
35 | "tests/**/*.tsx"
36 | ],
37 | "exclude": [
38 | "node_modules"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------