diff --git a/README.md b/README.md index d9c9c78..b2827ab 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,10 @@ export default Line.extend({ ![Bubble](assets/bubble.png) +### Scatter + +![Scatter](assets/scatter.png) + ## Build Setup ``` bash diff --git a/assets/bar.png b/assets/bar.png old mode 100644 new mode 100755 index 3548919..d93d7bb Binary files a/assets/bar.png and b/assets/bar.png differ diff --git a/assets/bubble.png b/assets/bubble.png old mode 100644 new mode 100755 index 9c68493..f82f748 Binary files a/assets/bubble.png and b/assets/bubble.png differ diff --git a/assets/doughnut.png b/assets/doughnut.png old mode 100644 new mode 100755 index 34be7aa..0797775 Binary files a/assets/doughnut.png and b/assets/doughnut.png differ diff --git a/assets/line.png b/assets/line.png old mode 100644 new mode 100755 index c700f17..28bf84a Binary files a/assets/line.png and b/assets/line.png differ diff --git a/assets/pie.png b/assets/pie.png old mode 100644 new mode 100755 index 5cc540c..ee54d68 Binary files a/assets/pie.png and b/assets/pie.png differ diff --git a/assets/polar.png b/assets/polar.png old mode 100644 new mode 100755 index e51103f..8343f6b Binary files a/assets/polar.png and b/assets/polar.png differ diff --git a/assets/radar.png b/assets/radar.png old mode 100644 new mode 100755 index 0f71590..ab8e6a5 Binary files a/assets/radar.png and b/assets/radar.png differ diff --git a/assets/scatter.png b/assets/scatter.png new file mode 100755 index 0000000..6a35705 Binary files /dev/null and b/assets/scatter.png differ diff --git a/docs/README.md b/docs/README.md index 1235aec..a6cf11f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -287,6 +287,12 @@ Sometimes you need more control over chart.js. Thats why you can access the char ![Bubble](assets/bubble.png) +### Scatter + +This chart has a different data structure then the others. Right now the reactive Mixins are not working for this chart type. + +![Scatter](assets/scatter.png) + ## Explanation of Different Builds There are three different entry points. It depends on which build setup do you have. The dependencies are bundled or required as a peerDependency. diff --git a/src/BaseCharts/Scatter.js b/src/BaseCharts/Scatter.js new file mode 100644 index 0000000..ef6d0d3 --- /dev/null +++ b/src/BaseCharts/Scatter.js @@ -0,0 +1,69 @@ +import Vue from 'vue' +import Chart from 'chart.js' +import { mergeOptions } from '../helpers/options' + +export default Vue.extend({ + render: function (createElement) { + return createElement( + 'div', + [ + createElement( + 'canvas', { + attrs: { + id: this.chartId, + width: this.width, + height: this.height + }, + ref: 'canvas' + } + ) + ] + ) + }, + + props: { + chartId: { + default: 'scatter-chart', + type: String + }, + width: { + default: 400, + type: Number + }, + height: { + default: 400, + type: Number + } + }, + + data () { + return { + defaultOptions: { + scales: { + xAxes: [{ + type: 'linear', + position: 'bottom' + }] + } + } + } + }, + + methods: { + renderChart (data, options) { + let chartOptions = mergeOptions(this.defaultOptions, options) + + this._chart = new Chart( + this.$refs.canvas.getContext('2d'), { + type: 'scatter', + data: data, + options: chartOptions + } + ) + this._chart.generateLegend() + } + }, + beforeDestroy () { + this._chart.destroy() + } +}) diff --git a/src/examples/App.vue b/src/examples/App.vue index 61f5cee..289e82c 100644 --- a/src/examples/App.vue +++ b/src/examples/App.vue @@ -1,23 +1,54 @@ @@ -31,6 +62,7 @@ import BubbleExample from './BubbleExample' import ReactiveExample from './ReactiveExample' import ReactivePropExample from './ReactivePropExample' + import ScatterExample from './ScatterExample' export default { components: { @@ -42,7 +74,8 @@ PolarAreaExample, BubbleExample, ReactiveExample, - ReactivePropExample + ReactivePropExample, + ScatterExample }, data () { return { @@ -79,4 +112,21 @@ max-width: 800px; margin: 0 auto; } + + h1 { + font-family: 'Helvetica', Arial; + color: #464646; + text-transform: uppercase; + border-bottom: 1px solid #f1f1f1; + padding-bottom: 15px; + font-size: 28px; + margin-top: 0; + } + + .Chart { + padding: 20px; + box-shadow: 0px 0px 20px 2px rgba(0, 0, 0, .4); + border-radius: 20px; + margin: 50px 0; + } diff --git a/src/examples/ScatterExample.js b/src/examples/ScatterExample.js new file mode 100644 index 0000000..a6ea91f --- /dev/null +++ b/src/examples/ScatterExample.js @@ -0,0 +1,53 @@ +import Scatter from '../BaseCharts/Scatter' + +export default Scatter.extend({ + mounted () { + this.renderChart({ + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'], + datasets: [{ + label: 'Scatter Dataset 1', + fill: false, + borderColor: '#f87979', + backgroundColor: '#f87979', + data: [{ + x: -2, + y: 4 + }, { + x: -1, + y: 1 + }, { + x: 0, + y: 0 + }, { + x: 1, + y: 1 + }, { + x: 2, + y: 4 + }] + }, + { + label: 'Scatter Dataset 2', + fill: false, + borderColor: '#7acbf9', + backgroundColor: '#7acbf9', + data: [{ + x: -2, + y: -4 + }, { + x: -1, + y: -1 + }, { + x: 0, + y: 1 + }, { + x: 1, + y: -1 + }, { + x: 2, + y: -4 + }] + }] + }, {responsive: true, maintainAspectRatio: false}) + } +}) diff --git a/test/unit/specs/Scatter.spec.js b/test/unit/specs/Scatter.spec.js new file mode 100644 index 0000000..72207b5 --- /dev/null +++ b/test/unit/specs/Scatter.spec.js @@ -0,0 +1,64 @@ +import Vue from 'vue' +import ScatterChart from 'src/examples/ScatterExample' + +describe('ScatterChart', () => { + let el + + beforeEach(() => { + el = document.createElement('div') + }) + + it('should render a canvas', () => { + const vm = new Vue({ + render: function (createElement) { + return createElement( + ScatterChart + ) + }, + components: { ScatterChart } + }).$mount(el) + + expect(vm.$el.querySelector('#scatter-chart')).not.to.be.an('undefined') + expect(vm.$el.querySelector('canvas')).not.to.be.an('undefined') + expect(vm.$el.querySelector('canvas')).not.to.be.an('null') + expect(vm.$el.querySelector('canvas')).to.exist + }) + + it('should change id based on prop', () => { + const vm = new Vue({ + render: function (createElement) { + return createElement( + ScatterChart, { + props: { + chartId: 'linechartprop' + } + } + ) + }, + components: { ScatterChart } + }).$mount(el) + + expect(vm.$el.querySelector('#linechartprop')).not.to.be.an('undefined') + }) + + it('should destroy chart instance', (done) => { + const vm = new Vue({ + render: function (createElement) { + return createElement( + ScatterChart + ) + }, + components: { ScatterChart } + }).$mount(el) + + expect(vm.$children[0]._chart.chart.ctx).not.to.be.null + + vm.$destroy() + + vm.$nextTick(() => { + vm.$forceUpdate() + expect(vm.$children[0]._chart.chart.ctx).to.be.null + done() + }) + }) +})