Skip to content

Commit

Permalink
[FE-18151] Full color hashing (#688)
Browse files Browse the repository at this point in the history
* Create function to build out SELECT; push color_attr to query builder

* Create utility function

* Modify sql in vega spec for lines and polys

* Push original domain/range to legend filtering func

* Revert weird capitalization changes

* Cleanup

* Only apply hashed select to ordinal colors

* Update color query depending if fullColorHashing is active or not

* Push build file

* Remove experimental code

* Make babel process mapbox ruler due to arrow func

* Update build file

---------

Co-authored-by: Chris Matzenbach <[email protected]>
  • Loading branch information
cmatzenbach and Chris Matzenbach authored Jan 29, 2025
1 parent 4d2fa97 commit 216078a
Show file tree
Hide file tree
Showing 7 changed files with 2,210 additions and 1,143 deletions.
3,271 changes: 2,135 additions & 1,136 deletions dist/charting.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/chart-addons/stacked-legend.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export async function getLegendStateFromChart(chart, useMap, selectedLayer) {
let colValues = await getTopValues(
layer,
layer_name,
color.domain.length
color.originalDomain.length
)

if (color.sorted) {
Expand All @@ -233,8 +233,8 @@ export async function getLegendStateFromChart(chart, useMap, selectedLayer) {
const { newDomain, newRange } = colValues
? getUpdatedDomainRange(
colValues,
color.domain,
color.range,
color.originalDomain,
color.originalRange,
color.defaultOtherRange
)
: {}
Expand Down
25 changes: 24 additions & 1 deletion src/mixins/raster-layer-line-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
isContourType,
validateContourState
} from "../utils/utils-contour"
import { buildHashedColor } from "../utils/color-helpers"

const AUTOSIZE_DOMAIN_DEFAULTS = [100000, 1000]
const AUTOSIZE_RANGE_DEFAULTS = [1.0, 3.0]
Expand Down Expand Up @@ -220,13 +221,35 @@ export default function rasterLayerLineMixin(_layer) {
alias.push("strokeColor")
ops.push(null)
} else {
const expression = color.field || color.aggregate
let expression = ""
if (color.field) {
if (color.type === "ordinal" && color.fullColorHashing) {
expression = buildHashedColor(
color.field,
color.range,
color.palette.val.length,
color.customColors
)
} else {
expression = color.field
}
} else {
expression = color.aggregate
}

transforms.push({
type: "project",
expr: expression,
as: "strokeColor"
})

if (color.field) {
transforms.push({
type: "project",
expr: color.field,
as: "color_attr"
})
}
}
}

Expand Down
16 changes: 15 additions & 1 deletion src/mixins/raster-layer-point-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { parser } from "../utils/utils"
import * as d3 from "d3"
import { AABox2d, Point2d } from "@heavyai/draw/dist/draw"
import { buildHashedColor } from "../utils/color-helpers"

const AUTOSIZE_DOMAIN_DEFAULTS = [100000, 0]
const AUTOSIZE_RANGE_DEFAULTS = [2.0, 5.0]
Expand Down Expand Up @@ -284,9 +285,22 @@ export default function rasterLayerPointMixin(_layer) {
) {
transforms.push({
type: "project",
expr: color.field,
expr:
color.type === "ordinal" && color.fullColorHashing
? buildHashedColor(
color.field,
color.range,
color.palette.val.length,
color.customColors
)
: color.field,
as: "color"
})
transforms.push({
type: "project",
expr: color.field,
as: "color_attr"
})
}

if (orientation) {
Expand Down
16 changes: 15 additions & 1 deletion src/mixins/raster-layer-poly-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
isContourType,
validateContourState
} from "../utils/utils-contour"
import { buildHashedColor } from "../utils/color-helpers"

const polyDefaultScaleColor = "#d6d7d6"
const polyNullScaleColor = "#d6d7d6"
Expand Down Expand Up @@ -350,9 +351,22 @@ export default function rasterLayerPolyMixin(_layer) {
if (color.type !== "solid" && !layerFilter.length) {
transforms.push({
type: "project",
expr: colorField,
expr:
color.type === "ordinal" && color.fullColorHashing
? buildHashedColor(
color.field,
color.range,
color.palette.val.length,
color.customColors
)
: colorField,
as: "color"
})
transforms.push({
type: "project",
expr: colorField,
as: "color_attr"
})
}

if (layerFilter.length && !isDataExport) {
Expand Down
17 changes: 17 additions & 0 deletions src/utils/color-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,20 @@ export function maybeUpdateAllOthers(chart, data, domain, range) {
chart.customDomain(domain)
chart.customRange(range)
}

export function buildHashedColor(field, range, paletteLength, customColors) {
if (customColors?.domain?.length > 0 && customColors?.range?.length > 0) {
const domain = customColors.domain
// build SQL CASE statement
let sql = `CASE `
for (let i = 0; i < domain.length; i++) {
sql += `WHEN ${field} = '${domain[i]}' THEN ${range.indexOf(
customColors.range[i]
)} `
}
sql += `ELSE MOD(HASH(${field}), ${paletteLength}) END`
return sql
} else {
return `MOD(HASH(${field}), ${paletteLength})`
}
}
2 changes: 1 addition & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ module.exports = {
loaders: [
{
test: /\.js?$/,
exclude: /node_modules/,
exclude: /node_modules\/(?!@mapbox-controls\/ruler)/,
use: "babel-loader"
},
{
Expand Down

0 comments on commit 216078a

Please sign in to comment.