mirror of
https://github.com/apache/superset.git
synced 2026-04-23 01:55:09 +00:00
Improvements to the polygon spatial viz (#6178)
* WIP * WIP * WIP * WIP * Fix color bucketing * Fixed colors * Fix no num categories selected * Colors working * Fix no metric selected * Visual cues for selection * Add unit tests * Remove jest from deps * Rename category to bucket * Small fixes * Fix lint * Fix unit tests * Remove duplicate hexToRGB * Fix import * Change order of arguments in getBuckets * Refactor function signature
This commit is contained in:
92
superset/assets/src/visualizations/deckgl/utils.js
Normal file
92
superset/assets/src/visualizations/deckgl/utils.js
Normal file
@@ -0,0 +1,92 @@
|
||||
import d3 from 'd3';
|
||||
import getSequentialSchemeRegistry from '../../modules/colors/SequentialSchemeRegistrySingleton';
|
||||
import { colorScalerFactory, hexToRGB } from '../../modules/colors';
|
||||
|
||||
export function getBreakPoints({
|
||||
break_points: formDataBreakPoints,
|
||||
num_buckets: formDataNumBuckets,
|
||||
metric,
|
||||
}, features) {
|
||||
if (formDataBreakPoints === undefined || formDataBreakPoints.length === 0) {
|
||||
// compute evenly distributed break points based on number of buckets
|
||||
const numBuckets = formDataNumBuckets
|
||||
? parseInt(formDataNumBuckets, 10)
|
||||
: 10;
|
||||
const [minValue, maxValue] = d3.extent(features, d => d[metric]);
|
||||
const delta = (maxValue - minValue) / numBuckets;
|
||||
const precision = delta === 0
|
||||
? 0
|
||||
: Math.max(0, Math.ceil(Math.log10(1 / delta)));
|
||||
return Array(numBuckets + 1)
|
||||
.fill()
|
||||
.map((_, i) => (minValue + i * delta).toFixed(precision));
|
||||
}
|
||||
return formDataBreakPoints.sort((a, b) => parseFloat(a) - parseFloat(b));
|
||||
}
|
||||
|
||||
export function getBreakPointColorScaler({
|
||||
break_points: formDataBreakPoints,
|
||||
num_buckets: formDataNumBuckets,
|
||||
linear_color_scheme: linearColorScheme,
|
||||
metric,
|
||||
opacity,
|
||||
}, features) {
|
||||
const breakPoints = formDataBreakPoints || formDataNumBuckets
|
||||
? getBreakPoints({
|
||||
break_points: formDataBreakPoints,
|
||||
num_buckets: formDataNumBuckets,
|
||||
metric,
|
||||
}, features)
|
||||
: null;
|
||||
const colors = Array.isArray(linearColorScheme)
|
||||
? linearColorScheme
|
||||
: getSequentialSchemeRegistry().get(linearColorScheme).colors;
|
||||
|
||||
let scaler;
|
||||
let maskPoint;
|
||||
if (breakPoints !== null) {
|
||||
// bucket colors into discrete colors
|
||||
const colorScaler = colorScalerFactory(colors);
|
||||
const n = breakPoints.length - 1;
|
||||
const bucketedColors = n > 1
|
||||
? [...Array(n).keys()].map(d => colorScaler(d / (n - 1)))
|
||||
: [colors[colors.length - 1]];
|
||||
|
||||
// repeat ends
|
||||
bucketedColors.unshift(bucketedColors[0]);
|
||||
bucketedColors.push(bucketedColors[n - 1]);
|
||||
|
||||
const points = breakPoints.map(p => parseFloat(p));
|
||||
scaler = d3.scale.threshold().domain(points).range(bucketedColors);
|
||||
maskPoint = value => value > breakPoints[n] || value < breakPoints[0];
|
||||
} else {
|
||||
// interpolate colors linearly
|
||||
scaler = colorScalerFactory(colors, features, d => d[metric]);
|
||||
maskPoint = () => false;
|
||||
}
|
||||
|
||||
return (d) => {
|
||||
const c = hexToRGB(scaler(d[metric]));
|
||||
if (maskPoint(d[metric])) {
|
||||
c[3] = 0;
|
||||
} else {
|
||||
c[3] = (opacity / 100.0) * 255;
|
||||
}
|
||||
return c;
|
||||
};
|
||||
}
|
||||
|
||||
export function getBuckets(fd, features) {
|
||||
const breakPoints = getBreakPoints(fd, features, true);
|
||||
const colorScaler = getBreakPointColorScaler(fd, features);
|
||||
const buckets = {};
|
||||
breakPoints.slice(1).forEach((value, i) => {
|
||||
const range = breakPoints[i] + ' - ' + breakPoints[i + 1];
|
||||
const mid = 0.5 * (parseInt(breakPoints[i], 10) + parseInt(breakPoints[i + 1], 10));
|
||||
buckets[range] = {
|
||||
color: colorScaler({ [fd.metric]: mid }),
|
||||
enabled: true,
|
||||
};
|
||||
});
|
||||
return buckets;
|
||||
}
|
||||
Reference in New Issue
Block a user