Skip to content

Commit aceb39c

Browse files
committed
Added support for timeseries
1 parent 861eb2d commit aceb39c

File tree

4 files changed

+269
-22
lines changed

4 files changed

+269
-22
lines changed

example/index.html

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@
2121
<fusioncharts :options="options">
2222
FusionCharts will render here...
2323
</fusioncharts>
24-
<p class="message-box">
25-
The value that you have selected is: {{ displayValue }}
26-
</p>
24+
<div v-show="displayChart">
25+
<fusioncharts :options="timeseriesOptions">
26+
FusionCharts will render here...
27+
</fusioncharts>
28+
</div>
29+
<button @click="changeFirstChartAttr">Change 1st Chart Attributes</button>
30+
<button @click="changeSecondChartAttr">
31+
Change 2nd Chart Attributes
32+
</button>
2733
</div>
2834
<script type="text/javascript" src="bundle.js"></script>
2935
</body>

example/index.js

Lines changed: 93 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,123 @@ import VueFCComponent from '../src/vue-fusioncharts-component';
55
// import VueFusionCharts from '../dist/vue-fusioncharts';
66
import FusionCharts from 'fusioncharts';
77
import Charts from 'fusioncharts/fusioncharts.charts';
8+
import TimeSeries from 'fusioncharts/fusioncharts.timeseries';
9+
10+
const jsonify = res => res.json();
11+
const dataFetch = fetch(
12+
'https://raw.githubusercontent.com/fusioncharts/dev_centre_docs/fusiontime-beta-release/charts-resources/fusiontime/online-sales-single-series/data.json'
13+
).then(jsonify);
14+
const schemaFetch = fetch(
15+
'https://raw.githubusercontent.com/fusioncharts/dev_centre_docs/fusiontime-beta-release/charts-resources/fusiontime/online-sales-single-series/schema.json'
16+
).then(jsonify);
817

918
// Use VueFusionCharts plugins by calling the Vue.use() global method:
1019
// Vue.use(VueFusionCharts, FusionCharts, Charts);
1120

1221
//Use this to add vue-fusioncharts a component
13-
let vFC = VueFCComponent(FusionCharts, Charts);
22+
let vFC = VueFCComponent(FusionCharts, Charts, TimeSeries);
1423
Vue.component('fusioncharts', vFC);
1524

1625
// bootstrap the demo
1726
var chart = new Vue({
1827
el: '#chart1',
1928
// components: { fusioncharts: vFC },
2029
data: {
30+
chartType: 'Pie2D',
31+
pieDataSource: {
32+
chart: {
33+
caption: 'Vue FusionCharts Sample',
34+
theme: 'fint'
35+
},
36+
data: [{ value: 1.9 }, { value: 2.3 }, { value: 2.1 }]
37+
},
38+
displayValue: 'nothing',
39+
events: {
40+
dataplotRollover: function(ev, props) {
41+
chart.displayValue = props.value;
42+
}
43+
},
44+
width: '500',
45+
height: '300',
46+
type: 'timeseries',
47+
dataFormat: 'json',
48+
dataSource: {
49+
caption: { text: 'Online Sales of a SuperStore in the US' },
50+
data: null,
51+
yAxis: [
52+
{
53+
plot: [
54+
{
55+
value: 'Sales ($)'
56+
}
57+
]
58+
}
59+
]
60+
},
2161
options: {
22-
type: 'Pie2D',
2362
width: '500',
2463
height: '300',
64+
type: 'Pie2D',
2565
dataFormat: 'json',
2666
dataSource: {
2767
chart: {
2868
caption: 'Vue FusionCharts Sample',
2969
theme: 'fint'
3070
},
3171
data: [{ value: 1.9 }, { value: 2.3 }, { value: 2.1 }]
32-
},
33-
displayValue: 'nothing',
34-
events: {
35-
dataplotRollover: function(ev, props) {
36-
chart.displayValue = props.value;
37-
}
3872
}
3973
},
40-
displayValue: 'nothing'
74+
timeseriesOptions: {
75+
width: '500',
76+
height: '300',
77+
type: 'timeseries',
78+
dataFormat: 'json',
79+
dataSource: {
80+
caption: { text: 'Online Sales of a SuperStore in the US' },
81+
data: null,
82+
yAxis: [
83+
{
84+
plot: [
85+
{
86+
value: 'Sales ($)'
87+
}
88+
]
89+
}
90+
]
91+
}
92+
},
93+
displayChart: false
94+
},
95+
methods: {
96+
changeFirstChartAttr: function() {
97+
// let dataSource = Object.assign({}, this.pieDataSource);
98+
this.options.dataSource.chart.caption = 'Changed to something else';
99+
// dataSource.data[2].value = this.getRandomNumber();
100+
// dataSource.data[1].value = this.getRandomNumber();
101+
// this.pieDataSource = dataSource;
102+
},
103+
changeSecondChartAttr: function() {
104+
let dataSource = Object.assign({}, this.timeseriesOptions.dataSource);
105+
dataSource.caption.text = 'Changed to something else';
106+
this.timeseriesOptions.dataSource = dataSource;
107+
},
108+
getRandomNumber: function() {
109+
var max = 5,
110+
min = 1;
111+
return Math.round((max - min) * Math.random() + min);
112+
}
113+
},
114+
mounted: function() {
115+
Promise.all([dataFetch, schemaFetch]).then(res => {
116+
const data = res[0];
117+
const schema = res[1];
118+
const fusionTable = new FusionCharts.DataStore().createDataTable(
119+
data,
120+
schema
121+
);
122+
this.timeseriesOptions.dataSource.data = fusionTable;
123+
this.displayChart = true;
124+
});
41125
}
42126
});
43127

src/utils.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,139 @@ export const addDep = (FC, _FC, modules) => {
1212
modules(_FC);
1313
}
1414
};
15+
16+
export function checkIfDataTableExists(dataSource) {
17+
// eslint-disable-next-line no-underscore-dangle
18+
if (dataSource && dataSource.data && dataSource.data._dataStore) {
19+
return true;
20+
}
21+
return false;
22+
}
23+
24+
export function cloneDataSource(obj, purpose = 'clone') {
25+
const type = typeof obj;
26+
if (
27+
type === 'string' ||
28+
type === 'number' ||
29+
type === 'function' ||
30+
type === 'boolean'
31+
) {
32+
return obj;
33+
}
34+
if (obj === null || obj === undefined) {
35+
return obj;
36+
}
37+
if (Array.isArray(obj)) {
38+
const arr = [];
39+
for (let i = 0; i < obj.length; i++) {
40+
arr.push(cloneDataSource(obj[i]));
41+
}
42+
return arr;
43+
}
44+
if (typeof obj === 'object') {
45+
const clonedObj = {};
46+
// eslint-disable-next-line guard-for-in
47+
// eslint-disable-next-line no-restricted-syntax
48+
for (const prop in obj) {
49+
// Edge case handling for DataTable
50+
if (prop === 'data') {
51+
// eslint-disable-next-line no-underscore-dangle
52+
if (obj[prop] && obj[prop]._dataStore && purpose === 'clone') {
53+
clonedObj[prop] = obj[prop];
54+
// eslint-disable-next-line no-underscore-dangle
55+
} else if (obj[prop] && obj[prop]._dataStore && purpose === 'diff') {
56+
clonedObj[prop] = '-';
57+
} else {
58+
clonedObj[prop] = cloneDataSource(obj[prop]);
59+
}
60+
continue;
61+
}
62+
clonedObj[prop] = cloneDataSource(obj[prop]);
63+
}
64+
return clonedObj;
65+
}
66+
return undefined;
67+
}
68+
69+
export function attachListeners(THIS) {
70+
if (THIS.$listeners && typeof THIS.$listeners === 'object') {
71+
Object.keys(THIS.$listeners).forEach(event => {
72+
THIS.chartObj.addEventListener(event, e => {
73+
THIS.$emit(event, e);
74+
});
75+
});
76+
}
77+
}
78+
79+
export function createEvents(THIS) {
80+
const ret = {
81+
events: {}
82+
};
83+
if (THIS.$listeners && typeof THIS.$listeners === 'object') {
84+
Object.keys(THIS.$listeners).forEach(event => {
85+
ret.events[event] = e => {
86+
THIS.$emit(event, e);
87+
};
88+
});
89+
}
90+
return ret;
91+
}
92+
93+
export function setLastOptions(config, THIS) {
94+
THIS._oldOptions = Object.assign({}, config);
95+
}
96+
97+
export function getLastOptions(THIS) {
98+
return THIS._oldOptions;
99+
}
100+
101+
export function getOptions(This, optionsMap) {
102+
let config = {},
103+
THIS = This;
104+
for (let i in optionsMap) {
105+
if (THIS[i] !== undefined && THIS[i] !== null) {
106+
config[optionsMap[i]] = THIS[i];
107+
}
108+
}
109+
let options = Object.assign(Object.assign({}, THIS.options), config);
110+
return options;
111+
}
112+
113+
export function renderChart(This, FC) {
114+
let THIS = This,
115+
config = THIS.getOptions(),
116+
chartObj = THIS.chartObj;
117+
118+
config.renderAt = this.containerID;
119+
THIS.setLastOptions(config);
120+
121+
if (chartObj && chartObj.dispose) {
122+
chartObj.dispose();
123+
}
124+
const events = this.createEvents();
125+
config.events = Object.assign({}, config.events, events.events);
126+
127+
THIS.chartObj = chartObj = new FC(config);
128+
chartObj.render();
129+
}
130+
131+
export function updateChart(This) {
132+
let THIS = This,
133+
config = THIS.getOptions(),
134+
prevConfig = THIS.getLastOptions(),
135+
chartObj = THIS.chartObj;
136+
137+
if (
138+
config.width !== prevConfig.width ||
139+
config.height !== prevConfig.height
140+
) {
141+
chartObj && chartObj.resizeTo(config.width, config.height);
142+
} else if (config.type !== prevConfig.type) {
143+
chartObj.chartType(config.type);
144+
} else {
145+
if (!checkIfDataTableExists(config.dataSource))
146+
chartObj.setChartData(config.dataSource, config.dataFormat);
147+
}
148+
149+
THIS.setLastOptions(config);
150+
}

src/vue-fusioncharts-component.js

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import _FC from 'fusioncharts';
22
const { optionsMap, props } = require('./config.js');
3-
import { addDep } from './utils';
3+
import { addDep, checkIfDataTableExists, cloneDataSource } from './utils';
44

55
export default (FC, ...options) => {
66
options &&
@@ -76,6 +76,12 @@ export default (FC, ...options) => {
7676
const events = this.createEvents();
7777
config.events = Object.assign({}, config.events, events.events);
7878

79+
let ds = config.dataSource || config.datasource;
80+
81+
if (checkIfDataTableExists(ds))
82+
this.prevDataSource = cloneDataSource(ds, 'diff');
83+
else this.prevDataSource = cloneDataSource(ds, 'clone');
84+
7985
THIS.chartObj = chartObj = new FC(config);
8086
chartObj.render();
8187
},
@@ -93,7 +99,8 @@ export default (FC, ...options) => {
9399
} else if (config.type !== prevConfig.type) {
94100
chartObj.chartType(config.type);
95101
} else {
96-
chartObj.setChartData(config.dataSource, config.dataFormat);
102+
if (!checkIfDataTableExists(config.dataSource))
103+
chartObj.setChartData(config.dataSource, config.dataFormat);
97104
}
98105

99106
THIS.setLastOptions(config);
@@ -117,19 +124,23 @@ export default (FC, ...options) => {
117124
},
118125
dataSource: {
119126
handler: function() {
120-
this.chartObj.setChartData(
121-
this.datasource || this.dataSource,
122-
this.dataFormat || this.dataformat
123-
);
127+
if (!checkIfDataTableExists(this.dataSource)) {
128+
this.chartObj.setChartData(
129+
this.datasource || this.dataSource,
130+
this.dataFormat || this.dataformat
131+
);
132+
}
124133
},
125134
deep: true
126135
},
127136
datasource: {
128137
handler: function() {
129-
this.chartObj.setChartData(
130-
this.datasource || this.dataSource,
131-
this.dataFormat || this.dataformat
132-
);
138+
if (!checkIfDataTableExists(this.datasource)) {
139+
this.chartObj.setChartData(
140+
this.datasource || this.dataSource,
141+
this.dataFormat || this.dataformat
142+
);
143+
}
133144
},
134145
deep: true
135146
}
@@ -145,6 +156,16 @@ export default (FC, ...options) => {
145156
},
146157
ready: function() {
147158
this.renderChart();
159+
},
160+
beforeUpdate: function() {
161+
const strPrevClonedDataSource = JSON.stringify(this.prevDataSource);
162+
const ds = this.datasource || this.dataSource || this.options.dataSource;
163+
const strCurrClonedDataSource = JSON.stringify(
164+
cloneDataSource(ds, 'diff')
165+
);
166+
if (strPrevClonedDataSource !== strCurrClonedDataSource) {
167+
this.chartObj.setChartData(ds, this.dataFormat || this.dataformat);
168+
}
148169
}
149170
};
150171
};

0 commit comments

Comments
 (0)