/
draw-mixin.js
154 lines (129 loc) · 3.67 KB
/
draw-mixin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
import {transition} from 'd3-transition'
/**
* ## Draw
*
* handles drawable drawing mechanism
*
* @memberof MultiChart.mixin
* @polymer
* @mixinFunction
*/
const Draw = superClass => {
return class extends superClass {
static get properties() {
return {
...super.properties,
/*
* `data` to draw the chart from
*/
data: {
type: Array
},
/*
* `transition` a transition composer function
*/
transition: {
type: Function,
value: function() {
return function(transition) {
return transition.duration(200);
}
}
},
/*
* `filter` a way to filter data passed to draw method
*
*/
filter : {
type: Function
}
};
}
/*
* `getDrawable` allows to specify which data to use for generating the chart.
* This is usefull for multi-geo where chart is generated by topojson feature and not by raw data.
*/
get drawableData() {
return this._shaped;
}
setData(data) {
if (data) {
// Note(cg): filter allows to dispay only a subset of the data.
// This is usefull for instance when we want to display multiple groups.
if(this.filter) {
this.data = data.filter(this.filter);
}
else {this.data = data ;}
}
}
// get propertiesToDraw() {
// return ['data'];
// }
// shallDraw(changedProperties) {
// return this.propertiesToDraw.some(k=> changedProperties.has(k))
// }
update(props) {
this.log && console.info('update props', props, this)
super.update(props);
if(props.has('data')) {
this._shaped = this.shape(this.data);
}
}
updated(props) {
this.log && console.info('updated props', props, this)
super.updated(props);
this.debounceDraw();
}
/*
* `shape` some charts are easier to draw is data is reshaped (for instance, stack chart)
*/
shape(data) {
return data;
}
debounceDraw() {
this.log && console.info('debounce', this)
this._debounceDraw = Debouncer.debounce(
this._debounceDraw, // initially undefined
timeOut.after(10),
() => {
this.log && console.info('debounced', this)
const isDrawn = this.draw();
this._isDrawn = !!isDrawn;
this.dispatchEvent(new CustomEvent('multi-drawn', {detail: {}, bubbles: true, composed: true}));
});
}
/*
* `draw` this is where do the work !
*/
draw() {
this.log && console.error(`draw method shall be overriden in subClasses.`)
}
/*
* `shallTransition` called within the draw function to know if transition shall be applied
*/
get shallTransition() {
// Note(cg): by default, we skip the transition for first draw.
return this.transition && this._isDrawn === true;
}
dataChanged(data, transition) {
this.log && console.info('dataChanged', this.data === data)
this.data = data;
if(transition) {
this.transition = transition;
}
// this._shaped = null;
// this.render(data, transition);
}
/*
* `applyTransition` applies a transition to chart
*/
applyTransition(chart, transition) {
return chart.transition().call(transition)
.on('end', this.onEndTransition);
}
onEndTransition() {}
};
};
export default Draw ;