Merge pull request #136 from apertureless/feature/scatter_chart
Feature/scatter chart
@@ -247,6 +247,10 @@ export default Line.extend({
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
### Scatter
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Build Setup
|
## Build Setup
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
|
|||||||
BIN
assets/bar.png
Normal file → Executable file
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 25 KiB |
BIN
assets/bubble.png
Normal file → Executable file
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 26 KiB |
BIN
assets/doughnut.png
Normal file → Executable file
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 41 KiB |
BIN
assets/line.png
Normal file → Executable file
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 31 KiB |
BIN
assets/pie.png
Normal file → Executable file
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 76 KiB |
BIN
assets/polar.png
Normal file → Executable file
|
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 87 KiB |
BIN
assets/radar.png
Normal file → Executable file
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 75 KiB |
BIN
assets/scatter.png
Executable file
|
After Width: | Height: | Size: 43 KiB |
@@ -287,6 +287,12 @@ Sometimes you need more control over chart.js. Thats why you can access the char
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
### Scatter
|
||||||
|
|
||||||
|
This chart has a different data structure then the others. Right now the reactive Mixins are not working for this chart type.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
## Explanation of Different Builds
|
## 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.
|
There are three different entry points. It depends on which build setup do you have. The dependencies are bundled or required as a peerDependency.
|
||||||
|
|||||||
69
src/BaseCharts/Scatter.js
Normal file
@@ -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()
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -1,23 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 style="text-align:center;margin:40px 0;">Barchart</h1>
|
<div class="Chart">
|
||||||
<bar-example></bar-example>
|
<h1 style="text-align:center;">Barchart</h1>
|
||||||
<h1 style="text-align:center;margin:40px 0;">Barchart with reactive mixing for live data</h1>
|
<bar-example></bar-example>
|
||||||
<reactive-example></reactive-example>
|
</div>
|
||||||
<h1 style="text-align:center;margin:40px 0;">Barchart with reactive mixing for live data as props</h1>
|
|
||||||
<reactive-prop-example :chart-data="dataPoints"></reactive-prop-example>
|
<div class="Chart">
|
||||||
<h1 style="text-align:center;margin:40px 0;">Linechart</h1>
|
<h1 style="text-align:center;">Barchart with reactive mixing for live data</h1>
|
||||||
<line-example></line-example>
|
<reactive-example></reactive-example>
|
||||||
<h1 style="text-align:center;margin:40px 0;">Doughnutchart</h1>
|
</div>
|
||||||
<doughnut-example></doughnut-example>
|
|
||||||
<h1 style="text-align:center;margin:40px 0;">Piechart</h1>
|
<div class="Chart">
|
||||||
<pie-example></pie-example>
|
<h1 style="text-align:center;">Barchart with reactive mixing for live data as props</h1>
|
||||||
<h1 style="text-align:center;margin:40px 0;">Radarchart</h1>
|
<reactive-prop-example :chart-data="dataPoints"></reactive-prop-example>
|
||||||
<radar-example></radar-example>
|
</div>
|
||||||
<h1 style="text-align:center;margin:40px 0;">Polararea</h1>
|
|
||||||
<polar-area-example></polar-area-example>
|
<div class="Chart">
|
||||||
<h1 style="text-align:center;margin:40px 0;">Bubblechart</h1>
|
<h1 style="text-align:center;">Linechart</h1>
|
||||||
<bubble-example></bubble-example>
|
<line-example></line-example>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Chart">
|
||||||
|
<h1 style="text-align:center;">Doughnutchart</h1>
|
||||||
|
<doughnut-example></doughnut-example>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Chart">
|
||||||
|
<h1 style="text-align:center;">Piechart</h1>
|
||||||
|
<pie-example></pie-example>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Chart">
|
||||||
|
<h1 style="text-align:center;">Radarchart</h1>
|
||||||
|
<radar-example></radar-example>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Chart">
|
||||||
|
<h1 style="text-align:center;">Polararea</h1>
|
||||||
|
<polar-area-example></polar-area-example>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Chart">
|
||||||
|
<h1 style="text-align:center;">Bubblechart</h1>
|
||||||
|
<bubble-example></bubble-example>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="Chart">
|
||||||
|
<h1 style="text-align:center;">Scatter Chart</h1>
|
||||||
|
<scatter-example></scatter-example>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -31,6 +62,7 @@
|
|||||||
import BubbleExample from './BubbleExample'
|
import BubbleExample from './BubbleExample'
|
||||||
import ReactiveExample from './ReactiveExample'
|
import ReactiveExample from './ReactiveExample'
|
||||||
import ReactivePropExample from './ReactivePropExample'
|
import ReactivePropExample from './ReactivePropExample'
|
||||||
|
import ScatterExample from './ScatterExample'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -42,7 +74,8 @@
|
|||||||
PolarAreaExample,
|
PolarAreaExample,
|
||||||
BubbleExample,
|
BubbleExample,
|
||||||
ReactiveExample,
|
ReactiveExample,
|
||||||
ReactivePropExample
|
ReactivePropExample,
|
||||||
|
ScatterExample
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -79,4 +112,21 @@
|
|||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
margin: 0 auto;
|
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;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
53
src/examples/ScatterExample.js
Normal file
@@ -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})
|
||||||
|
}
|
||||||
|
})
|
||||||
64
test/unit/specs/Scatter.spec.js
Normal file
@@ -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()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||