gridviz 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +18 -15
  2. package/dist/gridviz.js +3829 -2623
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +5 -3
  5. package/src/button/Button.js +77 -68
  6. package/src/button/FullscreenButton.js +123 -123
  7. package/src/button/ZoomButtons.js +109 -104
  8. package/src/core/GeoCanvas.js +15 -0
  9. package/src/core/Legend.js +267 -245
  10. package/src/core/Map.js +819 -670
  11. package/src/core/Tooltip.js +191 -185
  12. package/src/index.js +82 -79
  13. package/src/layer/GridLayer.js +4 -3
  14. package/src/layer/LabelLayer.js +7 -4
  15. package/src/legend/ColorCategoryLegend.js +127 -125
  16. package/src/legend/ColorDiscreteLegend.js +116 -114
  17. package/src/legend/ColorLegend.js +33 -11
  18. package/src/legend/OrientationLegend.js +94 -92
  19. package/src/legend/SizeLegend.js +8 -1
  20. package/src/legend/TernaryLegend.js +317 -314
  21. package/src/legend/VennLegend.js +202 -0
  22. package/src/style/CircleColorSizeWebGLStyle.js +249 -0
  23. package/src/style/CompositionStyle.js +1 -1
  24. package/src/style/DotDensityStyle.js +8 -4
  25. package/src/style/ImageStyle.js +1 -1
  26. package/src/style/Interpolator.js +283 -259
  27. package/src/style/IsoFenceStyle.js +1 -1
  28. package/src/style/LegoStyle.js +6 -5
  29. package/src/style/MosaicStyle.js +1 -1
  30. package/src/style/NinjaStarStyle.js +1 -1
  31. package/src/style/PillarStyle.js +1 -1
  32. package/src/style/RandomWalkInterpolator.js +213 -0
  33. package/src/style/ShadingRayStyle.js +16 -2
  34. package/src/style/ShadingStyle.js +80 -72
  35. package/src/style/ShapeColorSizeStyle.js +18 -2
  36. package/src/style/SideCategoryStyle.js +1 -1
  37. package/src/style/SideStyle.js +1 -1
  38. package/src/style/SideTanakaStyle.js +1 -1
  39. package/src/style/SquareColorCategoryWebGLStyle.js +71 -20
  40. package/src/style/SquareColorWebGLStyle.js +7 -4
  41. package/src/style/StrokeStyle.js +1 -1
  42. package/src/style/TextStyle.js +1 -1
  43. package/src/style/TimeSeriesStyle.js +14 -7
  44. package/src/utils/WebGLSquareColoringAdvanced.js +47 -9
  45. package/src/utils/scale.js +20 -0
  46. package/src/utils/webGLUtils.js +52 -0
@@ -1,314 +1,317 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { select } from 'd3-selection'
5
- import { Legend } from '../core/Legend.js'
6
-
7
- /**
8
- *
9
- * @module legend
10
- * @author Julien Gaffuri
11
- */
12
- export class TernaryLegend extends Legend {
13
- /** @param {Object} opts */
14
- constructor(opts) {
15
- super(opts)
16
- opts = opts || {}
17
-
18
- //classifier
19
- this.classifier = opts.classifier
20
-
21
- this.width = opts.width || 150
22
- this.selectionColor = opts.selectionColor || 'red'
23
- this.tooltip = opts.tooltip
24
- this.texts = opts.texts
25
-
26
- this.leftText = opts.leftText || 'Category 0'
27
- this.topText = opts.topText || 'Category 1'
28
- this.rightText = opts.rightText || 'Category 2'
29
-
30
- this.centerCoefficient = opts.centerCoefficient || this.classifier.centerCoefficient
31
- this.setType('ternary')
32
- }
33
-
34
- /**
35
- * @param {{} } opts
36
- */
37
- update(opts) {
38
- //clear
39
- this.div.selectAll('*').remove()
40
-
41
- //title
42
- this.makeTitle()
43
-
44
- const sqrt3over2 = 0.866025
45
- const w = this.width,
46
- h = w * sqrt3over2
47
- const classifier = this.classifier
48
- const selectionColor = this.selectionColor
49
- const selectionStrokeWidth = 0
50
- const tt = this.tooltip
51
- const texts = this.texts || {}
52
-
53
- const padding = 2
54
- const fontSize = 12
55
- const legend = this
56
-
57
- //make svg element
58
- const svg = this.div
59
- .append('svg')
60
- .classed('gridviz-legend-graphic', true)
61
- .attr('width', w + selectionStrokeWidth)
62
- .attr('height', h + 4 * padding + 2 * fontSize)
63
-
64
- //top label
65
- svg.append('text')
66
- .attr('x', w / 2)
67
- .attr('y', padding + fontSize)
68
- .classed('gridviz-legend-label', true)
69
- .text(this.topText)
70
- .attr('font-size', fontSize)
71
- .attr('text-anchor', 'middle')
72
- //left label
73
- svg.append('text')
74
- .attr('x', 0)
75
- .attr('y', 3 * padding + 2 * fontSize + h)
76
- .classed('gridviz-legend-label', true)
77
- .text(this.leftText)
78
- .attr('font-size', fontSize)
79
- .attr('text-anchor', 'start')
80
- //right label
81
- svg.append('text')
82
- .attr('x', w)
83
- .attr('y', 3 * padding + 2 * fontSize + h)
84
- .classed('gridviz-legend-label', true)
85
- .text(this.rightText)
86
- .attr('font-size', fontSize)
87
- .attr('text-anchor', 'end')
88
-
89
- //triangle group
90
- const g = svg
91
- .append('g')
92
- .classed('gridviz-legend-triangle', true)
93
- .attr(
94
- 'transform',
95
- 'translate(' +
96
- selectionStrokeWidth / 2 +
97
- ' ' +
98
- (selectionStrokeWidth / 2 + (2 * padding + fontSize)) +
99
- ')'
100
- )
101
-
102
- //common function for triangle patches
103
- const setAttributes = (elt, color, text) => {
104
- //elt.raise();
105
- elt.attr('fill', color)
106
- .classed('gridviz-legend-swatch', true)
107
- //.attr("stroke", colorOver)
108
- //.attr("stroke-width", 0)
109
- //.attr("stroke-linejoin", "round")
110
- .style('cursor', this.interactive ? 'pointer' : null)
111
- .on('mouseover', function (e) {
112
- /*this.parentNode.appendChild(this); select(this).attr("stroke-width", selectionStrokeWidth);*/
113
- select(this).classed('gridviz-legend-swatch--active', true).attr('fill', selectionColor)
114
- // show only the cells of this class on the map
115
- legend.highlight([color])
116
- if (!tt || !text) return
117
- tt.html(text)
118
- tt.setPosition(e)
119
- tt.show()
120
- })
121
- .on('mouseout', function () {
122
- /*select(this).attr("stroke-width", 0);*/
123
- select(this).classed('gridviz-legend-swatch--active', false).attr('fill', color)
124
- legend.highlight(null)
125
- if (tt) tt.hide()
126
- })
127
- if (tt && text)
128
- elt.on('mousemove', function (e) {
129
- tt.setPosition(e)
130
- })
131
- }
132
-
133
- //const [c0, c1, c2] = classifier.center
134
-
135
- //trapezium s0
136
- const t0 = g
137
- .append('polygon')
138
- .attr(
139
- 'points',
140
- '0,' +
141
- h +
142
- ' ' +
143
- w / 3 +
144
- ',' +
145
- h +
146
- ' ' +
147
- w / 2 +
148
- ',' +
149
- (h * 2) / 3 +
150
- ' ' +
151
- w / 6 +
152
- ',' +
153
- (h * 2) / 3
154
- )
155
- setAttributes(t0, classifier.colors[0], texts['0'])
156
- //trapezium s1
157
- const t1 = g
158
- .append('polygon')
159
- .attr(
160
- 'points',
161
- w / 2 +
162
- ',0 ' +
163
- (w * 2) / 3 +
164
- ',' +
165
- h / 3 +
166
- ' ' +
167
- w / 2 +
168
- ',' +
169
- (h * 2) / 3 +
170
- ' ' +
171
- w / 3 +
172
- ',' +
173
- h / 3
174
- )
175
- setAttributes(t1, classifier.colors[1], texts['1'])
176
- //trapezium s2
177
- const t2 = g
178
- .append('polygon')
179
- .attr(
180
- 'points',
181
- w +
182
- ',' +
183
- h +
184
- ' ' +
185
- (w * 5) / 6 +
186
- ',' +
187
- (2 * h) / 3 +
188
- ' ' +
189
- w / 2 +
190
- ',' +
191
- (h * 2) / 3 +
192
- ' ' +
193
- (w * 2) / 3 +
194
- ',' +
195
- h
196
- )
197
- setAttributes(t2, classifier.colors[2], texts['2'])
198
- //triangle s0
199
- const t0_ = g
200
- .append('polygon')
201
- .attr(
202
- 'points',
203
- w / 2 +
204
- ',' +
205
- (h * 2) / 3 +
206
- ' ' +
207
- (w * 5) / 6 +
208
- ',' +
209
- (h * 2) / 3 +
210
- ' ' +
211
- (w * 2) / 3 +
212
- ',' +
213
- h / 3
214
- )
215
- setAttributes(t0_, classifier.mixColors[0], texts['m12'])
216
- //triangle s1
217
- const t1_ = g
218
- .append('polygon')
219
- .attr('points', w / 2 + ',' + (h * 2) / 3 + ' ' + w / 3 + ',' + h + ' ' + (w * 2) / 3 + ',' + h)
220
- setAttributes(t1_, classifier.mixColors[1], texts['m02'])
221
- //triangle s2
222
- const t2_ = g
223
- .append('polygon')
224
- .attr(
225
- 'points',
226
- w / 2 + ',' + (h * 2) / 3 + ' ' + w / 6 + ',' + (h * 2) / 3 + ' ' + w / 3 + ',' + h / 3
227
- )
228
- setAttributes(t2_, classifier.mixColors[2], texts['m01'])
229
-
230
- //center
231
- if (this.centerCoefficient) {
232
- //TODO make it an hexagon !
233
- const center = g
234
- .append('circle')
235
- .attr('cx', w / 2)
236
- .attr('cy', (h * 2) / 3)
237
- .attr('r', (this.centerCoefficient * h) / 3)
238
- setAttributes(center, classifier.centerColor, texts['center'])
239
- }
240
-
241
- /*
242
- let middle, left, top, right, left_, bottom_, right_
243
- if (!this.real) {
244
-
245
- //0 left triangle
246
- left = g.append('polygon')
247
- .attr('points', "0," + h + " " + (w / 3) + "," + h + " " + (w / 6) + "," + (2 * h / 3))
248
- //1 top triangle
249
- top = g.append('polygon')
250
- .attr('points', (w / 3) + "," + (h / 3) + " " + (w * 2 / 3) + "," + (h / 3) + " " + (w / 2) + ",0")
251
- //2 right triangle
252
- right = g.append('polygon')
253
- .attr('points', (w * 2 / 3) + "," + h + " " + w + "," + h + " " + (w * 5 / 6) + "," + (2 * h / 3))
254
- //middle triangle
255
- middle = g.append('polygon')
256
- .attr('points', (w / 2) + "," + (h / 3) + " " + (w / 4) + "," + (h * 5 / 6) + " " + (3 * w / 4) + "," + (h * 5 / 6))
257
- //01 left trapezium
258
- left_ = g.append('polygon')
259
- .attr('points', (w / 6) + "," + (h * 2 / 3) + " " + (w / 4) + "," + (h * 5 / 6) + " " + (w / 2) + "," + (h / 3) + " " + (w / 3) + "," + (h / 3))
260
- //02 bottom trapezium
261
- bottom_ = g.append('polygon')
262
- .attr('points', (w / 3) + "," + (h) + " " + (2 * w / 3) + "," + (h) + " " + (w * 3 / 4) + "," + (h * 5 / 6) + " " + (w / 4) + "," + (h * 5 / 6))
263
- //12 right trapezium
264
- right_ = g.append('polygon')
265
- .attr('points', (w / 2) + "," + (h / 3) + " " + (w * 3 / 4) + "," + (h * 5 / 6) + " " + (w * 5 / 6) + "," + (h * 2 / 3) + " " + (w * 2 / 3) + "," + (h / 3))
266
-
267
- } else {
268
-
269
- //middle triangle
270
- middle = g.append('polygon')
271
- .attr('points', (w / 2) + ",0 0," + h + " " + w + "," + h)
272
-
273
- //draw trapezium
274
- //draw large trapezium first
275
- for (let i_ = 2; i_ >= 0; i_--) {
276
- const i = this.classifier.lowIndex[i_]
277
- const r = this.classifier.lowThreshold[i]
278
- if (i == 2)
279
- //01 left trapezium
280
- left_ = g.append('polygon')
281
- .attr('points', w / 2 + ",0 0," + h + " " + w * r + "," + h + " " + w * (1 + r) / 2 + "," + r * h)
282
- else if (i == 1)
283
- //02 bottom trapezium
284
- bottom_ = g.append('polygon')
285
- .attr('points', "0," + h + " " + w + "," + h + " " + w * (1 - r / 2) + "," + h * (1 - r) + " " + r * w / 2 + "," + h * (1 - r))
286
- else
287
- //12 right trapezium
288
- right_ = g.append('polygon')
289
- .attr('points', w + "," + h + " " + w / 2 + ",0 " + w * (1 - r) / 2 + "," + h * r + " " + w * (1 - r) + "," + h)
290
- }
291
-
292
- //draw triangles
293
- //draw large triangles first
294
- for (let i_ = 2; i_ >= 0; i_--) {
295
- const i = this.classifier.highIndex[i_]
296
- const r = this.classifier.highThreshold[i]
297
-
298
- if (i == 2)
299
- //2 right triangle
300
- right = g.append('polygon')
301
- .attr('points', w + "," + h + " " + w * r + "," + h + " " + w * (1 + r) / 2 + "," + h * r)
302
- else if (i == 1)
303
- //1 top triangle
304
- top = g.append('polygon')
305
- .attr('points', (w / 2) + ",0 " + w * r / 2 + "," + h * (1 - r) + " " + w * (1 - r / 2) + "," + h * (1 - r))
306
- else
307
- //0 left triangle
308
- left = g.append('polygon')
309
- .attr('points', "0," + h + " " + w * (1 - r) + "," + h + " " + w * (1 - r) / 2 + "," + h * r)
310
- }
311
-
312
- }*/
313
- }
314
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { select } from 'd3-selection'
5
+ import { Legend } from '../core/Legend.js'
6
+
7
+ /**
8
+ *
9
+ * @module legend
10
+ * @author Julien Gaffuri
11
+ */
12
+ export class TernaryLegend extends Legend {
13
+ /** @param {Object} opts */
14
+ constructor(opts) {
15
+ super(opts)
16
+ opts = opts || {}
17
+
18
+ //classifier
19
+ this.classifier = opts.classifier
20
+
21
+ this.width = opts.width || 150
22
+ this.selectionColor = opts.selectionColor || 'red'
23
+ this.tooltip = opts.tooltip
24
+ this.texts = opts.texts
25
+
26
+ this.leftText = opts.leftText || 'Category 0'
27
+ this.topText = opts.topText || 'Category 1'
28
+ this.rightText = opts.rightText || 'Category 2'
29
+
30
+ this.centerCoefficient = opts.centerCoefficient || this.classifier.centerCoefficient
31
+ this.setType('ternary')
32
+ }
33
+
34
+ /**
35
+ * @param {{} } opts
36
+ */
37
+ update(opts) {
38
+ //clear
39
+ this.div.selectAll('*').remove()
40
+
41
+ //title
42
+ this.makeTitle()
43
+
44
+ const sqrt3over2 = 0.866025
45
+ const w = this.width,
46
+ h = w * sqrt3over2
47
+ const classifier = this.classifier
48
+ const selectionColor = this.selectionColor
49
+ const selectionStrokeWidth = 0
50
+ const tt = this.tooltip
51
+ const texts = this.texts || {}
52
+
53
+ const padding = 2
54
+ const fontSize = 14
55
+ const legend = this
56
+
57
+ //make svg element
58
+ const svg = this.div
59
+ .append('svg')
60
+ .classed('gridviz-legend-graphic', true)
61
+ .attr('width', w + selectionStrokeWidth)
62
+ .attr('height', h + 4 * padding + 2 * fontSize)
63
+
64
+ //top label
65
+ svg.append('text')
66
+ .attr('x', w / 2)
67
+ .attr('y', padding + fontSize)
68
+ .classed('gridviz-legend-label', true)
69
+ .text(this.topText)
70
+ .attr('font-size', fontSize)
71
+ .style('fill', this.labelColorCSS())
72
+ .attr('text-anchor', 'middle')
73
+ //left label
74
+ svg.append('text')
75
+ .attr('x', 0)
76
+ .attr('y', 3 * padding + 2 * fontSize + h)
77
+ .classed('gridviz-legend-label', true)
78
+ .text(this.leftText)
79
+ .attr('font-size', fontSize)
80
+ .style('fill', this.labelColorCSS())
81
+ .attr('text-anchor', 'start')
82
+ //right label
83
+ svg.append('text')
84
+ .attr('x', w)
85
+ .attr('y', 3 * padding + 2 * fontSize + h)
86
+ .classed('gridviz-legend-label', true)
87
+ .text(this.rightText)
88
+ .attr('font-size', fontSize)
89
+ .style('fill', this.labelColorCSS())
90
+ .attr('text-anchor', 'end')
91
+
92
+ //triangle group
93
+ const g = svg
94
+ .append('g')
95
+ .classed('gridviz-legend-triangle', true)
96
+ .attr(
97
+ 'transform',
98
+ 'translate(' +
99
+ selectionStrokeWidth / 2 +
100
+ ' ' +
101
+ (selectionStrokeWidth / 2 + (2 * padding + fontSize)) +
102
+ ')'
103
+ )
104
+
105
+ //common function for triangle patches
106
+ const setAttributes = (elt, color, text) => {
107
+ //elt.raise();
108
+ elt.attr('fill', color)
109
+ .classed('gridviz-legend-swatch', true)
110
+ //.attr("stroke", colorOver)
111
+ //.attr("stroke-width", 0)
112
+ //.attr("stroke-linejoin", "round")
113
+ .style('cursor', this.interactive ? 'pointer' : null)
114
+ .on('mouseover', function (e) {
115
+ /*this.parentNode.appendChild(this); select(this).attr("stroke-width", selectionStrokeWidth);*/
116
+ select(this).classed('gridviz-legend-swatch--active', true).attr('fill', selectionColor)
117
+ // show only the cells of this class on the map
118
+ legend.highlight([color])
119
+ if (!tt || !text) return
120
+ tt.html(text)
121
+ tt.setPosition(e)
122
+ tt.show()
123
+ })
124
+ .on('mouseout', function () {
125
+ /*select(this).attr("stroke-width", 0);*/
126
+ select(this).classed('gridviz-legend-swatch--active', false).attr('fill', color)
127
+ legend.highlight(null)
128
+ if (tt) tt.hide()
129
+ })
130
+ if (tt && text)
131
+ elt.on('mousemove', function (e) {
132
+ tt.setPosition(e)
133
+ })
134
+ }
135
+
136
+ //const [c0, c1, c2] = classifier.center
137
+
138
+ //trapezium s0
139
+ const t0 = g
140
+ .append('polygon')
141
+ .attr(
142
+ 'points',
143
+ '0,' +
144
+ h +
145
+ ' ' +
146
+ w / 3 +
147
+ ',' +
148
+ h +
149
+ ' ' +
150
+ w / 2 +
151
+ ',' +
152
+ (h * 2) / 3 +
153
+ ' ' +
154
+ w / 6 +
155
+ ',' +
156
+ (h * 2) / 3
157
+ )
158
+ setAttributes(t0, classifier.colors[0], texts['0'])
159
+ //trapezium s1
160
+ const t1 = g
161
+ .append('polygon')
162
+ .attr(
163
+ 'points',
164
+ w / 2 +
165
+ ',0 ' +
166
+ (w * 2) / 3 +
167
+ ',' +
168
+ h / 3 +
169
+ ' ' +
170
+ w / 2 +
171
+ ',' +
172
+ (h * 2) / 3 +
173
+ ' ' +
174
+ w / 3 +
175
+ ',' +
176
+ h / 3
177
+ )
178
+ setAttributes(t1, classifier.colors[1], texts['1'])
179
+ //trapezium s2
180
+ const t2 = g
181
+ .append('polygon')
182
+ .attr(
183
+ 'points',
184
+ w +
185
+ ',' +
186
+ h +
187
+ ' ' +
188
+ (w * 5) / 6 +
189
+ ',' +
190
+ (2 * h) / 3 +
191
+ ' ' +
192
+ w / 2 +
193
+ ',' +
194
+ (h * 2) / 3 +
195
+ ' ' +
196
+ (w * 2) / 3 +
197
+ ',' +
198
+ h
199
+ )
200
+ setAttributes(t2, classifier.colors[2], texts['2'])
201
+ //triangle s0
202
+ const t0_ = g
203
+ .append('polygon')
204
+ .attr(
205
+ 'points',
206
+ w / 2 +
207
+ ',' +
208
+ (h * 2) / 3 +
209
+ ' ' +
210
+ (w * 5) / 6 +
211
+ ',' +
212
+ (h * 2) / 3 +
213
+ ' ' +
214
+ (w * 2) / 3 +
215
+ ',' +
216
+ h / 3
217
+ )
218
+ setAttributes(t0_, classifier.mixColors[0], texts['m12'])
219
+ //triangle s1
220
+ const t1_ = g
221
+ .append('polygon')
222
+ .attr('points', w / 2 + ',' + (h * 2) / 3 + ' ' + w / 3 + ',' + h + ' ' + (w * 2) / 3 + ',' + h)
223
+ setAttributes(t1_, classifier.mixColors[1], texts['m02'])
224
+ //triangle s2
225
+ const t2_ = g
226
+ .append('polygon')
227
+ .attr(
228
+ 'points',
229
+ w / 2 + ',' + (h * 2) / 3 + ' ' + w / 6 + ',' + (h * 2) / 3 + ' ' + w / 3 + ',' + h / 3
230
+ )
231
+ setAttributes(t2_, classifier.mixColors[2], texts['m01'])
232
+
233
+ //center
234
+ if (this.centerCoefficient) {
235
+ //TODO make it an hexagon !
236
+ const center = g
237
+ .append('circle')
238
+ .attr('cx', w / 2)
239
+ .attr('cy', (h * 2) / 3)
240
+ .attr('r', (this.centerCoefficient * h) / 3)
241
+ setAttributes(center, classifier.centerColor, texts['center'])
242
+ }
243
+
244
+ /*
245
+ let middle, left, top, right, left_, bottom_, right_
246
+ if (!this.real) {
247
+
248
+ //0 left triangle
249
+ left = g.append('polygon')
250
+ .attr('points', "0," + h + " " + (w / 3) + "," + h + " " + (w / 6) + "," + (2 * h / 3))
251
+ //1 top triangle
252
+ top = g.append('polygon')
253
+ .attr('points', (w / 3) + "," + (h / 3) + " " + (w * 2 / 3) + "," + (h / 3) + " " + (w / 2) + ",0")
254
+ //2 right triangle
255
+ right = g.append('polygon')
256
+ .attr('points', (w * 2 / 3) + "," + h + " " + w + "," + h + " " + (w * 5 / 6) + "," + (2 * h / 3))
257
+ //middle triangle
258
+ middle = g.append('polygon')
259
+ .attr('points', (w / 2) + "," + (h / 3) + " " + (w / 4) + "," + (h * 5 / 6) + " " + (3 * w / 4) + "," + (h * 5 / 6))
260
+ //01 left trapezium
261
+ left_ = g.append('polygon')
262
+ .attr('points', (w / 6) + "," + (h * 2 / 3) + " " + (w / 4) + "," + (h * 5 / 6) + " " + (w / 2) + "," + (h / 3) + " " + (w / 3) + "," + (h / 3))
263
+ //02 bottom trapezium
264
+ bottom_ = g.append('polygon')
265
+ .attr('points', (w / 3) + "," + (h) + " " + (2 * w / 3) + "," + (h) + " " + (w * 3 / 4) + "," + (h * 5 / 6) + " " + (w / 4) + "," + (h * 5 / 6))
266
+ //12 right trapezium
267
+ right_ = g.append('polygon')
268
+ .attr('points', (w / 2) + "," + (h / 3) + " " + (w * 3 / 4) + "," + (h * 5 / 6) + " " + (w * 5 / 6) + "," + (h * 2 / 3) + " " + (w * 2 / 3) + "," + (h / 3))
269
+
270
+ } else {
271
+
272
+ //middle triangle
273
+ middle = g.append('polygon')
274
+ .attr('points', (w / 2) + ",0 0," + h + " " + w + "," + h)
275
+
276
+ //draw trapezium
277
+ //draw large trapezium first
278
+ for (let i_ = 2; i_ >= 0; i_--) {
279
+ const i = this.classifier.lowIndex[i_]
280
+ const r = this.classifier.lowThreshold[i]
281
+ if (i == 2)
282
+ //01 left trapezium
283
+ left_ = g.append('polygon')
284
+ .attr('points', w / 2 + ",0 0," + h + " " + w * r + "," + h + " " + w * (1 + r) / 2 + "," + r * h)
285
+ else if (i == 1)
286
+ //02 bottom trapezium
287
+ bottom_ = g.append('polygon')
288
+ .attr('points', "0," + h + " " + w + "," + h + " " + w * (1 - r / 2) + "," + h * (1 - r) + " " + r * w / 2 + "," + h * (1 - r))
289
+ else
290
+ //12 right trapezium
291
+ right_ = g.append('polygon')
292
+ .attr('points', w + "," + h + " " + w / 2 + ",0 " + w * (1 - r) / 2 + "," + h * r + " " + w * (1 - r) + "," + h)
293
+ }
294
+
295
+ //draw triangles
296
+ //draw large triangles first
297
+ for (let i_ = 2; i_ >= 0; i_--) {
298
+ const i = this.classifier.highIndex[i_]
299
+ const r = this.classifier.highThreshold[i]
300
+
301
+ if (i == 2)
302
+ //2 right triangle
303
+ right = g.append('polygon')
304
+ .attr('points', w + "," + h + " " + w * r + "," + h + " " + w * (1 + r) / 2 + "," + h * r)
305
+ else if (i == 1)
306
+ //1 top triangle
307
+ top = g.append('polygon')
308
+ .attr('points', (w / 2) + ",0 " + w * r / 2 + "," + h * (1 - r) + " " + w * (1 - r / 2) + "," + h * (1 - r))
309
+ else
310
+ //0 left triangle
311
+ left = g.append('polygon')
312
+ .attr('points', "0," + h + " " + w * (1 - r) + "," + h + " " + w * (1 - r) / 2 + "," + h * r)
313
+ }
314
+
315
+ }*/
316
+ }
317
+ }