• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / deck.gl / 10519844544

23 Aug 2024 04:24AM UTC coverage: 88.902% (-0.2%) from 89.141%
10519844544

push

github

web-flow
GPU Aggregation (6/8): HexagonLayer (#9098)

6667 of 7306 branches covered (91.25%)

Branch coverage included in aggregate %.

674 of 710 new or added lines in 5 files covered. (94.93%)

223 existing lines in 3 files now uncovered.

55786 of 62943 relevant lines covered (88.63%)

6459.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.75
/modules/aggregation-layers/src/utils/scale-utils.js
1
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
1✔
2
//
1✔
3
// Permission is hereby granted, free of charge, to any person obtaining a copy
1✔
4
// of this software and associated documentation files (the "Software"), to deal
1✔
5
// in the Software without restriction, including without limitation the rights
1✔
6
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1✔
7
// copies of the Software, and to permit persons to whom the Software is
1✔
8
// furnished to do so, subject to the following conditions:
1✔
9
//
1✔
10
// The above copyright notice and this permission notice shall be included in
1✔
11
// all copies or substantial portions of the Software.
1✔
12
//
1✔
13
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1✔
14
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1✔
15
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1✔
16
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1✔
17
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1✔
18
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1✔
19
// THE SOFTWARE.
1✔
20

1✔
21
import {log} from '@deck.gl/core';
1✔
22

1✔
23
// a scale function wrapper just like d3-scales
1✔
24
export function getScale(domain, range, scaleFunction) {
1✔
25
  const scale = scaleFunction;
9✔
26
  scale.domain = () => domain;
9✔
27
  scale.range = () => range;
9✔
28

9✔
29
  return scale;
9✔
30
}
9✔
31

9✔
32
// Quantize scale is similar to linear scales,
1✔
33
// except it uses a discrete rather than continuous range
1✔
34
// return a quantize scale function
1✔
35
export function getQuantizeScale(domain, range) {
1✔
UNCOV
36
  const scaleFunction = value => quantizeScale(domain, range, value);
×
UNCOV
37

×
UNCOV
38
  return getScale(domain, range, scaleFunction);
×
UNCOV
39
}
×
UNCOV
40

×
41
// return a linear scale function
1✔
42
export function getLinearScale(domain, range) {
1✔
43
  const scaleFunction = value => linearScale(domain, range, value);
1✔
44

1✔
45
  return getScale(domain, range, scaleFunction);
1✔
46
}
1✔
47

1✔
48
export function getQuantileScale(domain, range) {
1✔
49
  // calculate threshold
4✔
50
  const sortedDomain = domain.sort(ascending);
4✔
51
  let i = 0;
4✔
52
  const n = Math.max(1, range.length);
4✔
53
  const thresholds = new Array(n - 1);
4✔
54
  while (++i < n) {
4✔
55
    thresholds[i - 1] = threshold(sortedDomain, i / n);
4✔
56
  }
9✔
57

9✔
58
  const scaleFunction = value => thresholdsScale(thresholds, range, value);
4✔
59
  scaleFunction.thresholds = () => thresholds;
4✔
60

×
61
  return getScale(domain, range, scaleFunction);
4✔
62
}
4✔
63

4✔
64
function ascending(a, b) {
1✔
65
  return a - b;
150✔
66
}
150✔
67

150✔
68
function threshold(domain, fraction) {
1✔
69
  const domainLength = domain.length;
9✔
70
  if (fraction <= 0 || domainLength < 2) {
9✔
71
    return domain[0];
9✔
72
  }
3✔
73
  if (fraction >= 1) {
9✔
74
    return domain[domainLength - 1];
9!
75
  }
×
76

×
77
  const domainFraction = (domainLength - 1) * fraction;
9✔
78
  const lowIndex = Math.floor(domainFraction);
6✔
79
  const low = domain[lowIndex];
6✔
80
  const high = domain[lowIndex + 1];
6✔
81
  return low + (high - low) * (domainFraction - lowIndex);
6✔
82
}
6✔
83

6✔
84
function bisectRight(a, x) {
1✔
85
  let lo = 0;
72✔
86
  let hi = a.length;
72✔
87
  while (lo < hi) {
72✔
88
    const mid = (lo + hi) >>> 1;
72✔
89
    if (ascending(a[mid], x) > 0) {
108✔
90
      hi = mid;
108✔
91
    } else {
48✔
92
      lo = mid + 1;
108✔
93
    }
60✔
94
  }
60✔
95
  return lo;
108✔
96
}
72✔
97

72✔
98
// return a quantize scale function
1✔
99
function thresholdsScale(thresholds, range, value) {
1✔
100
  return range[bisectRight(thresholds, value)];
72✔
101
}
72✔
102

72✔
103
// ordinal Scale
1✔
104
function ordinalScale(domain, domainMap, range, value) {
1✔
105
  const key = `${value}`;
16✔
106
  let d = domainMap.get(key);
16✔
107
  if (d === undefined) {
16✔
108
    // update the domain
16✔
109
    d = domain.push(value);
6✔
110
    domainMap.set(key, d);
6✔
111
  }
6✔
112
  return range[(d - 1) % range.length];
16✔
113
}
16✔
114

16✔
115
export function getOrdinalScale(domain, range) {
1✔
116
  const domainMap = new Map();
4✔
117
  const uniqueDomain = [];
4✔
118
  for (const d of domain) {
4✔
119
    const key = `${d}`;
4✔
120
    if (!domainMap.has(key)) {
8✔
121
      domainMap.set(key, uniqueDomain.push(d));
8✔
122
    }
8✔
123
  }
8✔
124

8✔
125
  const scaleFunction = value => ordinalScale(uniqueDomain, domainMap, range, value);
4✔
126

16✔
127
  return getScale(domain, range, scaleFunction);
4✔
128
}
4✔
129

4✔
130
// Quantize scale is similar to linear scales,
1✔
131
// except it uses a discrete rather than continuous range
1✔
132
export function quantizeScale(domain, range, value) {
1✔
133
  const domainRange = domain[1] - domain[0];
3✔
134
  if (domainRange <= 0) {
3✔
135
    log.warn('quantizeScale: invalid domain, returning range[0]')();
3✔
136
    return range[0];
2✔
137
  }
2✔
138
  const step = domainRange / range.length;
3✔
139
  const idx = Math.floor((value - domain[0]) / step);
1✔
140
  const clampIdx = Math.max(Math.min(idx, range.length - 1), 0);
1✔
141

1✔
142
  return range[clampIdx];
1✔
143
}
1✔
144

1✔
145
// Linear scale maps continuous domain to continuous range
1✔
146
export function linearScale(domain, range, value) {
1✔
147
  return ((value - domain[0]) / (domain[1] - domain[0])) * (range[1] - range[0]) + range[0];
1✔
148
}
1✔
149

1✔
150
// get scale domains
1✔
151
function notNullOrUndefined(d) {
1✔
152
  return d !== undefined && d !== null;
9✔
153
}
9✔
154

9✔
155
export function unique(values) {
1✔
156
  const results = [];
1✔
157
  values.forEach(v => {
1✔
158
    if (!results.includes(v) && notNullOrUndefined(v)) {
1✔
159
      results.push(v);
3✔
160
    }
3✔
161
  });
3✔
162

3✔
163
  return results;
1✔
164
}
1✔
165

1✔
166
function getTruthyValues(data, valueAccessor) {
1✔
167
  const values = typeof valueAccessor === 'function' ? data.map(valueAccessor) : data;
2✔
168
  return values.filter(notNullOrUndefined);
2!
169
}
2✔
170

2✔
171
export function getLinearDomain(data, valueAccessor) {
1✔
172
  const sorted = getTruthyValues(data, valueAccessor).sort();
×
173
  return sorted.length ? [sorted[0], sorted[sorted.length - 1]] : [0, 0];
×
174
}
×
175

×
176
export function getQuantileDomain(data, valueAccessor) {
1✔
177
  return getTruthyValues(data, valueAccessor);
1✔
178
}
1✔
179

1✔
180
export function getOrdinalDomain(data, valueAccessor) {
1✔
181
  return unique(getTruthyValues(data, valueAccessor));
1✔
182
}
1✔
183

1✔
184
export function getScaleDomain(scaleType, data, valueAccessor) {
1✔
185
  switch (scaleType) {
×
186
    case 'quantize':
×
187
    case 'linear':
×
188
      return getLinearDomain(data, valueAccessor);
×
189

×
190
    case 'quantile':
×
191
      return getQuantileDomain(data, valueAccessor);
×
192

×
193
    case 'ordinal':
×
194
      return getOrdinalDomain(data, valueAccessor);
×
195

×
196
    default:
×
197
      return getLinearDomain(data, valueAccessor);
×
198
  }
×
199
}
×
200

×
201
export function clamp(value, min, max) {
1✔
202
  return Math.max(min, Math.min(max, value));
10✔
203
}
10✔
204

10✔
205
export function getScaleFunctionByScaleType(scaleType) {
1✔
UNCOV
206
  switch (scaleType) {
×
UNCOV
207
    case 'quantize':
×
UNCOV
208
      return getQuantizeScale;
×
UNCOV
209
    case 'linear':
×
UNCOV
210
      return getLinearScale;
×
UNCOV
211
    case 'quantile':
×
212
      return getQuantileScale;
×
UNCOV
213
    case 'ordinal':
×
214
      return getOrdinalScale;
×
215

×
UNCOV
216
    default:
×
UNCOV
217
      return getQuantizeScale;
×
218
  }
×
219
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc