gridviz 3.0.2 → 3.0.3

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.
@@ -0,0 +1,203 @@
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { interpolateLab } from "d3-interpolate"
5
+
6
+
7
+
8
+ export const trivariateClassifier = (properties, totalFunction, opts = {}) => {
9
+
10
+ //the three properties
11
+ const p0 = properties[0], p1 = properties[1], p2 = properties[2]
12
+
13
+ //the classifier center point. sum must be equal to 1
14
+ const [c0, c1, c2] = opts.center || [1 / 3, 1 / 3, 1 / 3]
15
+
16
+ //parameter to decide wether to use mixed classes m0, m1, m2.
17
+ const withMixedClasses = opts.withMixedClasses != undefined ? opts.withMixedClasses : true
18
+
19
+ //paramerter decide wether to use a central class, and the size of this central class.
20
+ //set to 0 or undefined for not showing any central class. Set to 1 for a central class that contains the mix classes
21
+ const cc = opts.centerCoefficient ? 1 - opts.centerCoefficient : undefined
22
+
23
+ //the output classifier method
24
+ const fun = c => {
25
+ //get total
26
+ const tot = totalFunction(c)
27
+ if (!tot) return undefined
28
+ //compute shares
29
+ const [s0, s1, s2] = [+c[p0] / tot, +c[p1] / tot, +c[p2] / tot]
30
+
31
+ //class 0
32
+ if (s0 >= c0 && s1 <= c1 && s2 <= c2) {
33
+ //central class near class 0
34
+ if (cc != undefined && (s2 - c2) * (c1 - cc * c1) >= (s1 - cc * c1) * (cc * c2 - c2))
35
+ return "center"
36
+ return "0"
37
+ }
38
+ //class 1
39
+ if (s0 <= c0 && s1 >= c1 && s2 <= c2) {
40
+ //central class near class 1
41
+ if (cc != undefined && (s2 - c2) * (c0 - cc * c0) >= (s0 - cc * c0) * (cc * c2 - c2))
42
+ return "center"
43
+ return "1"
44
+ }
45
+ //class 2
46
+ if (s0 <= c0 && s1 <= c1 && s2 >= c2) {
47
+ //central class near class 2
48
+ if (cc != undefined && (s1 - c1) * (c0 - cc * c0) >= (s0 - cc * c0) * (cc * c1 - c1))
49
+ return "center"
50
+ return "2"
51
+ }
52
+ //middle class 0 - intersection class 1 and 2
53
+ if (s0 <= c0 && s1 >= c1 && s2 >= c2) {
54
+ //central class
55
+ if (cc != undefined && s0 > cc * c0) return "center"
56
+ if (withMixedClasses) return "m0"
57
+ return s1 > s2 ? "1" : "2"
58
+ }
59
+ //middle class 1 - intersection class 0 and 1
60
+ if (s0 >= c0 && s1 <= c1 && s2 >= c2) {
61
+ //central class
62
+ if (cc != undefined && s1 > cc * c1) return "center"
63
+ if (withMixedClasses) return "m1"
64
+ return s0 > s2 ? "0" : "2"
65
+ }
66
+ //middle class 2 - intersection class 0 and 1
67
+ if (s0 >= c0 && s1 >= c1 && s2 <= c2) {
68
+ //central class
69
+ if (cc != undefined && s2 > cc * c2) return "center"
70
+ if (withMixedClasses) return "m2"
71
+ return s1 > s0 ? "1" : "0"
72
+ }
73
+ //should not happen
74
+ return "unknown"
75
+ }
76
+
77
+ //attach information to output function
78
+ fun.center = [c0, c1, c2]
79
+ fun.centerCoefficient = opts.centerCoefficient
80
+
81
+ return fun
82
+ }
83
+
84
+
85
+
86
+ export const trivariateColorClassifier = (properties, totalFunction, colors, opts = {}) => {
87
+
88
+ //the three colors
89
+ const [color0, color1, color2] = colors || ["red", "green", "blue"]
90
+
91
+ //the color interpolation function
92
+ const colorInterpolation = opts.colorInterpolation || interpolateLab
93
+
94
+ //parameter to decide wether to use mixed classes.
95
+ const withMixedClasses = opts.withMixedClasses != undefined ? opts.withMixedClasses : true
96
+ //https://d3js.org/d3-interpolate/color
97
+ const mixColorFunction = (color1, color2) => colorInterpolation(color1, color2)(0.5)
98
+ //the colors corresponding to the mixed classes
99
+ const [mixColor0, mixColor1, mixColor2] = opts.mixedColors || withMixedClasses ? [mixColorFunction(color1, color2), mixColorFunction(color0, color2), mixColorFunction(color0, color1)] : []
100
+
101
+ //the central color, used for the central class, if any. The central class is the class of relatively balanced values, around the center point
102
+ const centerColor = opts.centerColor || colorInterpolation(mixColorFunction(color0, color1), color2)(0.333)
103
+
104
+ //make classifier
105
+ const classifier = trivariateClassifier(properties, totalFunction, opts)
106
+
107
+ //the output color classifier method
108
+ const fun = c => {
109
+ const cla = classifier(c)
110
+ if (cla == "0") return color0
111
+ if (cla == "1") return color1
112
+ if (cla == "2") return color2
113
+ if (cla == "m0") return mixColor0
114
+ if (cla == "m1") return mixColor1
115
+ if (cla == "m2") return mixColor2
116
+ if (cla == "center") return centerColor
117
+ return opts.defaultColor || "black"
118
+ }
119
+ fun.center = classifier.center
120
+ fun.centerCoefficient = opts.centerCoefficient
121
+ fun.colors = [color0, color1, color2]
122
+ fun.mixColors = [mixColor0, mixColor1, mixColor2]
123
+ fun.centerColor = centerColor
124
+
125
+ return fun
126
+ }
127
+
128
+
129
+
130
+
131
+
132
+
133
+ /*
134
+ const orderedIndexesDec = arr => [...arr.keys()].sort((a, b) => arr[b] - arr[a]);
135
+ const orderedIndexesInc = arr => [...arr.keys()].sort((a, b) => arr[a] - arr[b]);
136
+
137
+ export const trivariateClassifier = (properties, totalFunction, opts = {}) => {
138
+ const lowThreshold = opts.lowThreshold || [1 / 3, 1 / 3, 1 / 3]
139
+ const highThreshold = opts.highThreshold || [2 / 3, 2 / 3, 2 / 3]
140
+ const colors = opts.colors || ["red", "green", "blue"]
141
+ const colorInterpolation = opts.colorInterpolation || interpolateLab
142
+
143
+ //https://d3js.org/d3-interpolate/color
144
+ const middleColorFunction = (color1, color2) => colorInterpolation(color1, color2)(0.5)
145
+ const middleColors = opts.middleColors || [middleColorFunction(colors[1], colors[2]), middleColorFunction(colors[0], colors[2]), middleColorFunction(colors[0], colors[1])]
146
+ const centerColor = opts.centerColor || colorInterpolation(middleColors[2], colors[2])(0.333)
147
+
148
+ const high_ = orderedIndexesDec(highThreshold)
149
+ const low_ = orderedIndexesInc(lowThreshold)
150
+
151
+ const p0 = properties[0], p1 = properties[1], p2 = properties[2]
152
+ const fun = c => {
153
+ //get total
154
+ const tot = totalFunction(c)
155
+ if (!tot) return undefined
156
+ //compute shares
157
+ const shares = [+c[p0] / tot, +c[p1] / tot, +c[p2] / tot]
158
+ //return colors
159
+ //start first with the extreme high (triangles): from the larger value (small triangle) to the lower value (large triangle)
160
+ for (let i of high_) if (shares[i] > highThreshold[i]) return colors[i]
161
+ //then draw the extreme low (trapeziums): from the lower value (small trapeziums) to the larger values (large trapezium)
162
+ for (let i of low_) if (shares[i] < lowThreshold[i]) return middleColors[i]
163
+ //else central color
164
+ return centerColor
165
+ }
166
+ fun.lowThreshold = lowThreshold
167
+ fun.highThreshold = highThreshold
168
+ fun.colors = colors
169
+ fun.middleColors = middleColors
170
+ fun.centerColor = centerColor
171
+ fun.lowIndex = low_
172
+ fun.highIndex = high_
173
+ return fun
174
+ }
175
+ */
176
+
177
+ /*
178
+ export const trivariateClassifier3 = (properties, totalFunction, opts = {}) => {
179
+ const [a01, a12, a20] = opts.thresholds || [1/3, 1/3, 1/3]
180
+ const [c0, c1, c2] = opts.colors || ["red", "green", "blue"]
181
+ const centerColor = opts.centerColor || "gray"
182
+
183
+ const fff = a => a == 1 ? Infinity : a / (1 - a)
184
+ const c01 = fff(a01), c12 = fff(a12), c20 = fff(a20)
185
+
186
+ const p0 = properties[0], p1 = properties[1], p2 = properties[2]
187
+ const fun = c => {
188
+ //get total
189
+ const tot = totalFunction(c)
190
+ if (!tot) return undefined
191
+ //compute shares
192
+ const [s0, s1, s2] = [+c[p0] / tot, +c[p1] / tot, +c[p2] / tot]
193
+ //return colors
194
+ if (s0 * c01 > s1 && s0 > s2 * c20) return c0
195
+ else if (s1 > s0 * c01 && s1 * c12 > s2) return c1
196
+ else if (s2 * c20 > s0 && s2 > s1 * c12) return c2
197
+ else return centerColor
198
+ }
199
+ fun.colors = [c0, c1, c2]
200
+ fun.centerColor = centerColor
201
+ return fun
202
+ }
203
+ */
@@ -29,6 +29,16 @@ export function nice(v, multiples = [8, 6, 5, 4, 2.5, 2]) {
29
29
  }
30
30
 
31
31
 
32
+ export function loadImage(src) {
33
+ return new Promise((resolve, reject) => {
34
+ const img = new Image();
35
+ img.onload = function () { resolve(img); };
36
+ img.onerror = function () { reject(new Error('Error loading image')); };
37
+ img.src = src;
38
+ });
39
+ }
40
+
41
+
32
42
 
33
43
  /*
34
44
  export let monitor = false