mirror of
https://github.com/KevinMidboe/vue-chartjs.git
synced 2026-02-09 10:59:32 +00:00
Merge pull request #11 from apertureless/feature/reactive_chart_data
WIP Feature/reactive chart data #11
This commit is contained in:
28
README.md
28
README.md
@@ -36,7 +36,7 @@ Just create your own component.
|
|||||||
// CommitChart.js
|
// CommitChart.js
|
||||||
import { Bar } from 'vue-chartjs'
|
import { Bar } from 'vue-chartjs'
|
||||||
|
|
||||||
export default BarChart.extend({
|
export default Bar.extend({
|
||||||
mounted () {
|
mounted () {
|
||||||
// Overwriting base render method with actual data.
|
// Overwriting base render method with actual data.
|
||||||
this.renderChart({
|
this.renderChart({
|
||||||
@@ -67,7 +67,7 @@ You can overwrite the default chart options. Just pass the options object as a s
|
|||||||
// MonthlyIncome.js
|
// MonthlyIncome.js
|
||||||
import { Line } from 'vue-chartjs'
|
import { Line } from 'vue-chartjs'
|
||||||
|
|
||||||
export default LineChart.extend({
|
export default Line.extend({
|
||||||
props: [data, options],
|
props: [data, options],
|
||||||
mounted () {
|
mounted () {
|
||||||
this.renderChart(this.data, this.options)
|
this.renderChart(this.data, this.options)
|
||||||
@@ -92,6 +92,30 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Reactivity
|
||||||
|
|
||||||
|
Chart.js does not update or re-render the chart if new data is passed.
|
||||||
|
However you can simply implement this by your own or use one of the two mixins which are included.
|
||||||
|
|
||||||
|
- `reactiveProp`
|
||||||
|
- `reactiveData`
|
||||||
|
|
||||||
|
The mixins automatically create `chartData` as a prop or data. And add a watcher. If data has changed, the chart will update.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// MonthlyIncome.js
|
||||||
|
import { Line, reactiveProp } from 'vue-chartjs'
|
||||||
|
|
||||||
|
export default Line.extend({
|
||||||
|
mixins: [reactiveProp]
|
||||||
|
props: [chartData, options],
|
||||||
|
mounted () {
|
||||||
|
this.renderChart(this.chartData, this.options)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Available Charts
|
## Available Charts
|
||||||
|
|
||||||
### Bar Chart
|
### Bar Chart
|
||||||
|
|||||||
34
codecov.yml
Normal file
34
codecov.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
codecov:
|
||||||
|
branch: master
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
precision: 2
|
||||||
|
round: down
|
||||||
|
range: "70...100"
|
||||||
|
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
target: auto
|
||||||
|
threshold: null
|
||||||
|
branches: null
|
||||||
|
|
||||||
|
patch:
|
||||||
|
default:
|
||||||
|
target: auto
|
||||||
|
branches: null
|
||||||
|
|
||||||
|
changes:
|
||||||
|
default:
|
||||||
|
branches: null
|
||||||
|
|
||||||
|
ignore:
|
||||||
|
- "tests/*"
|
||||||
|
- "src/examples/*"
|
||||||
|
- "src/mixins/*"
|
||||||
|
|
||||||
|
|
||||||
|
comment:
|
||||||
|
layout: "header, diff, changes, sunburst, uncovered, tree"
|
||||||
|
branches: null
|
||||||
|
behavior: default
|
||||||
24
package.json
24
package.json
@@ -38,9 +38,9 @@
|
|||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"chromedriver": "^2.21.2",
|
"chromedriver": "^2.21.2",
|
||||||
"connect-history-api-fallback": "^1.1.0",
|
"connect-history-api-fallback": "^1.1.0",
|
||||||
"cross-spawn": "^2.1.5",
|
"cross-spawn": "^4.0.2",
|
||||||
"css-loader": "^0.25.0",
|
"css-loader": "^0.25.0",
|
||||||
"eslint": "^3.7.0",
|
"eslint": "^3.7.1",
|
||||||
"eslint-config-standard": "^6.2.0",
|
"eslint-config-standard": "^6.2.0",
|
||||||
"eslint-friendly-formatter": "^2.0.5",
|
"eslint-friendly-formatter": "^2.0.5",
|
||||||
"eslint-loader": "^1.3.0",
|
"eslint-loader": "^1.3.0",
|
||||||
@@ -56,23 +56,25 @@
|
|||||||
"http-proxy-middleware": "^0.17.2",
|
"http-proxy-middleware": "^0.17.2",
|
||||||
"inject-loader": "^2.0.1",
|
"inject-loader": "^2.0.1",
|
||||||
"isparta-loader": "^2.0.0",
|
"isparta-loader": "^2.0.0",
|
||||||
|
"jasmine-core": "^2.5.2",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"karma": "^0.13.15",
|
"karma": "^1.3.0",
|
||||||
"karma-coverage": "^0.5.5",
|
"karma-coverage": "^1.1.1",
|
||||||
"karma-mocha": "^0.2.2",
|
"karma-jasmine": "^1.0.2",
|
||||||
|
"karma-mocha": "^1.2.0",
|
||||||
"karma-phantomjs-launcher": "^1.0.0",
|
"karma-phantomjs-launcher": "^1.0.0",
|
||||||
"karma-sinon-chai": "^1.2.0",
|
"karma-sinon-chai": "^1.2.0",
|
||||||
"karma-sourcemap-loader": "^0.3.7",
|
"karma-sourcemap-loader": "^0.3.7",
|
||||||
"karma-spec-reporter": "0.0.26",
|
"karma-spec-reporter": "0.0.26",
|
||||||
"karma-webpack": "^1.7.0",
|
"karma-webpack": "^1.7.0",
|
||||||
"lodash": "^4.15.0",
|
"lodash": "^4.16.3",
|
||||||
"lolex": "^1.4.0",
|
"lolex": "^1.4.0",
|
||||||
"mocha": "^3.1.0",
|
"mocha": "^3.1.0",
|
||||||
"nightwatch": "^0.8.18",
|
"nightwatch": "^0.9.8",
|
||||||
"ora": "^0.2.0",
|
"ora": "^0.3.0",
|
||||||
"phantomjs-prebuilt": "^2.1.3",
|
"phantomjs-prebuilt": "^2.1.13",
|
||||||
"selenium-server": "^2.53.1",
|
"selenium-server": "^2.53.1",
|
||||||
"shelljs": "^0.6.0",
|
"shelljs": "^0.7.4",
|
||||||
"sinon": "^1.17.3",
|
"sinon": "^1.17.3",
|
||||||
"sinon-chai": "^2.8.0",
|
"sinon-chai": "^2.8.0",
|
||||||
"url-loader": "^0.5.7",
|
"url-loader": "^0.5.7",
|
||||||
@@ -83,6 +85,6 @@
|
|||||||
"webpack": "^1.13.2",
|
"webpack": "^1.13.2",
|
||||||
"webpack-dev-middleware": "^1.4.0",
|
"webpack-dev-middleware": "^1.4.0",
|
||||||
"webpack-hot-middleware": "^2.6.0",
|
"webpack-hot-middleware": "^2.6.0",
|
||||||
"webpack-merge": "^0.8.3"
|
"webpack-merge": "^0.14.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<bar-example></bar-example>
|
<bar-example></bar-example>
|
||||||
|
<reactive-example></reactive-example>
|
||||||
<line-example></line-example>
|
<line-example></line-example>
|
||||||
<doughnut-example></doughnut-example>
|
<doughnut-example></doughnut-example>
|
||||||
<pie-example></pie-example>
|
<pie-example></pie-example>
|
||||||
@@ -18,9 +19,21 @@
|
|||||||
import RadarExample from './RadarExample'
|
import RadarExample from './RadarExample'
|
||||||
import PolarAreaExample from './PolarAreaExample'
|
import PolarAreaExample from './PolarAreaExample'
|
||||||
import BubbleExample from './BubbleExample'
|
import BubbleExample from './BubbleExample'
|
||||||
|
import ReactiveExample from './ReactiveExample'
|
||||||
|
import ReactivePropExample from './ReactivePropExample'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { BarExample, LineExample, DoughnutExample, PieExample, RadarExample, PolarAreaExample, BubbleExample }
|
components: {
|
||||||
|
BarExample,
|
||||||
|
LineExample,
|
||||||
|
DoughnutExample,
|
||||||
|
PieExample,
|
||||||
|
RadarExample,
|
||||||
|
PolarAreaExample,
|
||||||
|
BubbleExample,
|
||||||
|
ReactiveExample,
|
||||||
|
ReactivePropExample
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
41
src/examples/ReactiveExample.js
Normal file
41
src/examples/ReactiveExample.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import BarChart from '../BaseCharts/Bar'
|
||||||
|
import reactiveData from '../mixins/reactiveData'
|
||||||
|
|
||||||
|
export default BarChart.extend({
|
||||||
|
mixins: [reactiveData],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
chartData: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created () {
|
||||||
|
this.fillData()
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
this.renderChart(this.chartData)
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
this.fillData()
|
||||||
|
}, 5000)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
fillData () {
|
||||||
|
this.chartData = {
|
||||||
|
labels: ['January' + this.getRandomInt(), 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Data One',
|
||||||
|
backgroundColor: '#f87979',
|
||||||
|
data: [this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt(), this.getRandomInt()]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getRandomInt () {
|
||||||
|
return Math.floor(Math.random() * (50 - 5 + 1)) + 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
10
src/examples/ReactivePropExample.js
Normal file
10
src/examples/ReactivePropExample.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import BarChart from '../BaseCharts/Bar'
|
||||||
|
import reactiveData from '../mixins/reactiveProp'
|
||||||
|
|
||||||
|
export default BarChart.extend({
|
||||||
|
mixins: [reactiveData],
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
this.renderChart(this.chartData)
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -5,6 +5,8 @@ import Pie from './BaseCharts/Pie'
|
|||||||
import PolarArea from './BaseCharts/PolarArea'
|
import PolarArea from './BaseCharts/PolarArea'
|
||||||
import Radar from './BaseCharts/Radar'
|
import Radar from './BaseCharts/Radar'
|
||||||
import Bubble from './BaseCharts/Bubble'
|
import Bubble from './BaseCharts/Bubble'
|
||||||
|
import reactiveProp from './mixins/reactiveProp'
|
||||||
|
import reactiveData from './mixins/reactiveData'
|
||||||
|
|
||||||
const VueCharts = {
|
const VueCharts = {
|
||||||
Bar,
|
Bar,
|
||||||
@@ -13,7 +15,9 @@ const VueCharts = {
|
|||||||
Pie,
|
Pie,
|
||||||
PolarArea,
|
PolarArea,
|
||||||
Radar,
|
Radar,
|
||||||
Bubble
|
Bubble,
|
||||||
|
reactiveProp,
|
||||||
|
reactiveData
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = VueCharts
|
module.exports = VueCharts
|
||||||
|
|||||||
44
src/mixins/reactiveData.js
Normal file
44
src/mixins/reactiveData.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
module.exports = {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
chartData: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'chartData': {
|
||||||
|
handler (newData, oldData) {
|
||||||
|
if (oldData) {
|
||||||
|
let chart = this._chart
|
||||||
|
|
||||||
|
let newDataLabels = newData.datasets.map((dataset) => {
|
||||||
|
return dataset.label
|
||||||
|
})
|
||||||
|
|
||||||
|
let oldDataLabels = oldData.datasets.map((dataset) => {
|
||||||
|
return dataset.label
|
||||||
|
})
|
||||||
|
|
||||||
|
if (JSON.stringify(newDataLabels) === JSON.stringify(oldDataLabels)) {
|
||||||
|
this.forceUpdate(newData, chart)
|
||||||
|
} else {
|
||||||
|
this.forceRender()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
forceUpdate (newData, chart) {
|
||||||
|
newData.datasets.forEach((dataset, i) => {
|
||||||
|
chart.data.datasets[i].data = dataset.data
|
||||||
|
})
|
||||||
|
|
||||||
|
chart.data.labels = newData.labels
|
||||||
|
chart.update()
|
||||||
|
},
|
||||||
|
|
||||||
|
forceRender () {
|
||||||
|
this.renderChart(this.chartData, this.options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/mixins/reactiveProp.js
Normal file
35
src/mixins/reactiveProp.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
module.exports = {
|
||||||
|
props: {
|
||||||
|
chartData: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
'chartData': {
|
||||||
|
handler (newData, oldData) {
|
||||||
|
if (oldData) {
|
||||||
|
let chart = this._chart
|
||||||
|
|
||||||
|
let newDataLabels = newData.datasets.map((dataset) => {
|
||||||
|
return dataset.label
|
||||||
|
})
|
||||||
|
|
||||||
|
let oldDataLabels = oldData.datasets.map((dataset) => {
|
||||||
|
return dataset.label
|
||||||
|
})
|
||||||
|
|
||||||
|
if (JSON.stringify(newDataLabels) === JSON.stringify(oldDataLabels)) {
|
||||||
|
newData.datasets.forEach((dataset, i) => {
|
||||||
|
chart.data.datasets[i].data = dataset.data
|
||||||
|
})
|
||||||
|
chart.data.labels = newData.labels
|
||||||
|
chart.update()
|
||||||
|
} else {
|
||||||
|
this.renderChart(this.chartData, this.options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"expect": true,
|
"expect": true,
|
||||||
|
"jasmine": true,
|
||||||
"sinon": true
|
"sinon": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ module.exports = function (config) {
|
|||||||
// http://karma-runner.github.io/0.13/config/browsers.html
|
// http://karma-runner.github.io/0.13/config/browsers.html
|
||||||
// 2. add it to the `browsers` array below.
|
// 2. add it to the `browsers` array below.
|
||||||
browsers: ['PhantomJS'],
|
browsers: ['PhantomJS'],
|
||||||
frameworks: ['mocha', 'sinon-chai'],
|
frameworks: ['mocha', 'sinon-chai', 'jasmine'],
|
||||||
reporters: ['spec', 'coverage'],
|
reporters: ['spec', 'coverage'],
|
||||||
files: ['./index.js'],
|
files: ['./index.js'],
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
|
|||||||
0
test/unit/specs/mixins/reactiveData.js
Normal file
0
test/unit/specs/mixins/reactiveData.js
Normal file
Reference in New Issue
Block a user