Skip to content

Commit 608a57c

Browse files
Merge pull request #138 from ignoreintuition/development
Development
2 parents 0d0b904 + a6bde7e commit 608a57c

File tree

9 files changed

+912
-377
lines changed

9 files changed

+912
-377
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,31 @@ export default {
9292
}
9393
}
9494
```
95+
Bubble Charts require three metrics (v1, v2, and v3). These should be passed as triplets
96+
97+
```JavaScript
98+
export default {
99+
name: 'example',
100+
data () {
101+
return {
102+
chartData: {
103+
chartType: "bubbleChart",
104+
selector: "chart",
105+
title: "Important Data",
106+
width: 400,
107+
height: 200,
108+
triplet: ['count', 'pyCount', 'revenue']
109+
data: [
110+
{'count': 120,
111+
'fruit': 'apples'},
112+
{'count': 250,
113+
'fruit': 'oranges'}
114+
]
115+
}
116+
}
117+
}
118+
}
119+
```
95120
### Overrides
96121
If you need to override any of the default values of the charts (pallette colors, ticks, margins, etc) you can pass an overrides object to you chartData.
97122

@@ -131,9 +156,11 @@ chartData: {
131156
* scatterPlot: a graph in which the values of two variables are plotted along two axes, the pattern of the resulting points revealing any correlation present.
132157
* pieChart: a chart in which a circle is divided into slices to illustrate proportion
133158
* areaChart: a chart which displays graphically quantitative data
159+
* bubleChart: a bubble chart is a variation of a scatter chart in which the data points are replaced with bubbles, and an additional dimension of the data is represented in the size of the bubbles.
134160

135161
### Charts that support two or more metrics
136162
* barChart
163+
* vBarChart
137164
* lineGraph
138165

139166
Lastly you will need to add the component and bind your data

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "v-chart-plugin",
33
"main": "./dist/module/v-chart-plugin.js",
4-
"version": "0.2.15",
4+
"version": "0.3.0",
55
"description": "This plugin is designed to allow Vue.js developers to incorporate fully reactive and customizable charts into your applications. Uses D3.js for charting.",
66
"keywords": [
77
"vue",

src/components/chartExample.vue

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
<div class="col-6 col-md-8">
1818
<div class="row">
1919
<div class="col-12">
20-
<v-chart v-bind:chartData="lineGraphData"></v-chart>
20+
<v-chart v-bind:chartData="bubbleChartData"></v-chart>
2121
</div>
2222
<div class="col-12 col-lg-6">
2323
<v-chart v-bind:chartData="areaChartData"></v-chart>
2424
</div>
2525
<div class="col-12 col-lg-6">
26-
<v-chart v-bind:chartData="barChartData"></v-chart>
26+
<v-chart v-bind:chartData="lineGraphData"></v-chart>
2727
</div>
2828
<div class="col-12 col-lg-6">
2929
<v-chart v-bind:chartData="vBarChartData"></v-chart>
@@ -75,15 +75,16 @@ export default {
7575
width: 50
7676
},
7777
},
78-
barChartData: {
79-
chartType: "barChart",
78+
bubbleChartData: {
79+
chartType: "bubbleChart",
8080
selector: "chart",
8181
title: "Bar Chart",
8282
subtitle: "Sales by month",
83-
height: 200,
84-
metric: ["total"],
85-
dim: "month",
83+
width: 600,
84+
height: 500,
85+
triplet: ["total", "forecast", "yoy"],
8686
data: sales,
87+
goal: 500,
8788
legends: {
8889
enabled: true,
8990
height: 25,
@@ -94,9 +95,10 @@ export default {
9495
chartType: "lineGraph",
9596
selector: "lineGraph",
9697
title: "Line Graph",
97-
width: 600,
98+
width: 200,
9899
subtitle: "Sales by month",
99100
height: 200,
101+
goal: 500,
100102
metric: ["total", "forecast"],
101103
dim: "month",
102104
data: sales,
@@ -112,8 +114,8 @@ export default {
112114
title: "Verticle Bar Chart",
113115
subtitle: "Sales by month",
114116
width: 300,
115-
height: 200,
116-
metric: "total",
117+
height: 300,
118+
metric: ["total", "forecast"],
117119
dim: "month",
118120
data: sales,
119121
legends: {

src/import/barChart.js

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { globalAgent } from 'http';
2+
13
/**
24
* @fileOverview Bar chart component definition
35
*
@@ -30,7 +32,7 @@ const barChart = function chart() {
3032
*/
3133
let cs = {
3234
palette: {
33-
fill: '#005792',
35+
fill: ['#005792', '#ffcdcd'],
3436
stroke: '#d1f4fa',
3537
},
3638
bar: {
@@ -62,7 +64,7 @@ const barChart = function chart() {
6264
* @function
6365
*/
6466
const getHeight = () => (
65-
this.displayHeight - cs.x.axisHeight - this.header - cs.bar.vPadding) / this.ds.length - 1;
67+
(this.displayHeight - cs.x.axisHeight - this.header - cs.bar.vPadding) / this.ds.length - 1) / this.metric.length ;
6668

6769
/**
6870
* Returns y axis co-ordinate of the bar
@@ -72,7 +74,7 @@ const barChart = function chart() {
7274
* @param {Object} i (svg element)
7375
*/
7476
const getYCoord = (d, i) => i * (
75-
this.displayHeight - cs.x.axisHeight - this.header) / this.ds.length + 1 + this.header;
77+
this.displayHeight - cs.x.axisHeight - this.header) / this.ds.length + 1 + this.header + cs.bar.offset * getHeight();
7678

7779
/**
7880
* Adds a tooltip on mouse over
@@ -100,17 +102,22 @@ const barChart = function chart() {
100102
* @param {Object} rects (svg element)
101103
*/
102104
const enter = (rects) => {
103-
rects.enter()
104-
.append('rect')
105-
.attr('fill', cs.palette.fill)
106-
.attr('stroke', cs.palette.stroke)
107-
.attr('class', this.selector)
108-
.attr('width', getWidth)
109-
.attr('height', getHeight)
110-
.attr('y', getYCoord)
111-
.attr('x', cs.y.axisWidth + cs.bar.hPadding)
112-
.on('mouseover', mouseOver)
113-
.on('mouseout', mouseOut);
105+
this.metric.forEach( (e, i) => {
106+
cs.bar.offset = i;
107+
rects[i].enter()
108+
.append('rect')
109+
.attr('fill', cs.palette.fill[i])
110+
.attr('stroke', cs.palette.stroke)
111+
.attr('class', this.selector)
112+
.attr('class', 'r' + i)
113+
.attr('width', getWidth)
114+
.attr('height', getHeight)
115+
.attr('y', getYCoord)
116+
.attr('x', cs.y.axisWidth + cs.bar.hPadding)
117+
.on('mouseover', mouseOver)
118+
.on('mouseout', mouseOut);
119+
});
120+
if (this.goal) this.generateGoal(cs, svgContainer, false, cs.y.axisWidth + cs.bar.hPadding);
114121
return rects;
115122
};
116123
/**
@@ -120,11 +127,15 @@ const barChart = function chart() {
120127
* @param {Object} rects (svg element)
121128
*/
122129
const transition = (rects) => {
123-
rects.transition()
124-
.attr('width', getWidth)
125-
.attr('height', getHeight)
126-
.attr('y', getYCoord)
127-
.attr('x', cs.y.axisWidth + cs.bar.hPadding);
130+
this.metric.forEach( (e, i) => {
131+
cs.bar.offset = i;
132+
rects[i].transition()
133+
.attr('width', getWidth)
134+
.attr('height', getHeight)
135+
.attr('y', getYCoord)
136+
.attr('x', cs.y.axisWidth + cs.bar.hPadding);
137+
});
138+
if (this.goal) this.generateGoal(cs, svgContainer, false, cs.y.axisWidth + cs.bar.hPadding);
128139
return rects;
129140
};
130141
/**
@@ -134,7 +145,9 @@ const barChart = function chart() {
134145
* @param {Object} rect (svg element)
135146
*/
136147
const exit = (rects) => {
137-
rects.exit().remove();
148+
this.metric.forEach( (e, i) => {
149+
rects[i].exit().remove();
150+
});
138151
return rects;
139152
};
140153
/**
@@ -175,13 +188,22 @@ const barChart = function chart() {
175188
* @param {number} currentValue
176189
*/
177190
const getMaxDimLength = (accumulator, currentValue) => {
191+
if(!currentValue.dim) return accumulator;
178192
return (currentValue.dim.length > accumulator) ? currentValue.dim.length : accumulator;
179193
}
180194

181-
const rects = svgContainer.selectAll('rect').data(this.ds);
195+
const rects = []
196+
this.metric.forEach( (e, i) => {
197+
rects.push(svgContainer.selectAll('rect.r' + i).data(this.ds.map(d => {
198+
return {
199+
metric: d.metric[i],
200+
dim: d.dim
201+
}
202+
})))
203+
})
182204

183205
cs = this.setOverrides(cs, this.chartData.overrides);
184-
if (this.ds[0].dim)
206+
if (this.ds[0] && this.ds[0].dim)
185207
cs.y.axisWidth = cs.y.axisWidth || (this.ds.reduce(getMaxDimLength, 0)) * 10;
186208

187209
buildScales(cs);

src/import/bubbleChart.js

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**
2+
* @fileOverview Line Graph component definition
3+
*
4+
* @author Brian Greig
5+
*
6+
* @requires NPM:d3:Vue
7+
* @requires src/v-chart-plugin.js
8+
*/
9+
const d3 = Object.assign({},
10+
require('d3-selection'),
11+
require('d3-scale'),
12+
require('d3-axis'),
13+
require('d3-shape'));
14+
/**
15+
* Builds a Line Graph.
16+
* @module lineGraph
17+
*/
18+
19+
const lineGraph = function chart(mode) {
20+
/**
21+
* The SVG that stores the chart
22+
* @member svgContainer
23+
*/
24+
const svgContainer = d3.select(`#${this.chartData.selector}`);
25+
/**
26+
* The configuration of the coordinate system
27+
* @member cs
28+
*/
29+
let cs = {
30+
palette: {
31+
pointFill: '#005792',
32+
pointStroke: '#d1f4fa',
33+
},
34+
x: {
35+
domain: [],
36+
range: [],
37+
axisHeight: 20,
38+
},
39+
y: {
40+
axisWidth: 30,
41+
ticks: 5,
42+
},
43+
r: {
44+
45+
}
46+
};
47+
48+
/**
49+
* Runs when a new element is added to the dataset
50+
* @member enter
51+
* @function
52+
* @param {Object} points (svg element)
53+
*/
54+
const enter = (points) => {
55+
points.enter()
56+
.append('circle')
57+
.attr('class', this.selector)
58+
.attr('r', d => cs.r.scale(d.metric[0][this.triplet[2]]))
59+
.attr('cx', d => cs.x.scale(d.metric[0][this.triplet[0]]) + cs.y.axisWidth + 5)
60+
.attr('cy', d => cs.y.scale(d.metric[0][this.triplet[1]]));
61+
return points;
62+
};
63+
/**
64+
* Runs when a value of an element in dataset is changed
65+
* @member transition
66+
* @function
67+
* @param {Object} points (svg element)
68+
*/
69+
const transition = (points) => {
70+
points.transition()
71+
.attr('r', d => cs.r.scale(d.metric[0][this.triplet[2]]))
72+
.attr('cx', d => cs.x.scale(d.metric[0][this.triplet[0]]) + cs.y.axisWidth + 5)
73+
.attr('cy', d => cs.y.scale(d.metric[0][this.triplet[1]]));
74+
return points;
75+
};
76+
77+
/**
78+
* Runs when an element is removed from the dataset
79+
* @member exit
80+
* @function
81+
* @param {Object} points (svg element)
82+
*/
83+
const exit = (points) => {
84+
points.exit().remove();
85+
return points;
86+
};
87+
88+
/**
89+
* Builds the scales for the x and y axes
90+
* @member buildScales
91+
* @function
92+
*/
93+
const buildScales = cs => {
94+
cs.y.scale = d3.scaleLinear()
95+
.domain([this.minTriplet.v1, this.maxTriplet.v1])
96+
.range([this.displayHeight - cs.x.axisHeight, this.header]);
97+
cs.x.scale = d3.scaleLinear()
98+
.domain([this.minTriplet.v2, this.maxTriplet.v2])
99+
.range([0, this.width]);
100+
cs.r.scale = d3.scaleLinear()
101+
.domain([this.minTriplet.v3, this.maxTriplet.v3])
102+
.range([0, 20]);
103+
};
104+
/**
105+
* Draws the x and y axes on the svg
106+
* @member drawAxis
107+
* @function
108+
*/
109+
const drawAxis = cs => {
110+
cs.x.axis = d3.axisBottom().scale(cs.x.scale);
111+
cs.x.xOffset = cs.y.axisWidth + 5;
112+
cs.x.yOffset = this.displayHeight - cs.x.axisHeight;
113+
cs.y.axis = d3.axisLeft().ticks(cs.y.ticks, 's').scale(cs.y.scale);
114+
cs.y.xOffset = cs.y.axisWidth;
115+
cs.y.yOffset = 0;
116+
svgContainer.append('g').attr('class', 'axis').attr('transform', `translate(${cs.x.xOffset}, ${cs.x.yOffset})`)
117+
.call(cs.x.axis);
118+
svgContainer.append('g').attr('class', 'axis').attr('transform', `translate(${cs.y.xOffset},${cs.y.yOffset})`)
119+
.call(cs.y.axis);
120+
};
121+
122+
const points = svgContainer.selectAll('circle').data(this.ds);
123+
124+
cs = this.setOverrides(cs, this.chartData.overrides);
125+
126+
buildScales(cs);
127+
drawAxis(cs);
128+
enter(points);
129+
transition(points);
130+
exit(points);
131+
132+
return cs;
133+
};
134+
135+
export default lineGraph;

0 commit comments

Comments
 (0)