UNPKG

vsup

Version:

Value-Suppressing Uncertainty Palettes. A technique for creating bivariate scales for depicting uncertainty, using D3.

138 lines (119 loc) 3.11 kB
import * as d3 from "d3"; // Returns a color, based on a bivariate data point, // a quantization function, and a color interpolator // can be extended to different modes (just saturation, say) export function simpleScale(m_mode, m_range, m_quantization) { var range = m_range || d3.interpolateViridis, quantization = m_quantization || function(v, u) { var data = u != undefined ? { v: v, u: u } : { v: v.v, u: v.u }; return data; }, mode = m_mode; function CIEDist(color1, color2) { var c1 = d3.lab(d3.color(color1)), c2 = d3.lab(d3.color(color2)); return Math.sqrt( Math.pow(c1.l - c2.l, 2) + Math.pow(c1.a - c2.a, 2) + Math.pow(c1.b - c2.b, 2) ); } function map(value, uncertainty) { var data = quantization(value, uncertainty); var uDom = [0, 1]; var vDom = [0, 1]; if (quantization.uncertaintyDomain) { uDom = quantization.uncertaintyDomain(); } if (quantization.valueDomain) { vDom = quantization.valueDomain(); } var uScale = d3 .scaleLinear() .domain(uDom) .range([0, 1]); var vScale = d3 .scaleLinear() .domain(vDom) .range([0, 1]); var vcolor = range(vScale(data.v)); switch (mode) { case "usl": default: vcolor = d3.interpolateLab(vcolor, "#fff")(uScale(data.u)); break; case "us": vcolor = d3.hsl(vcolor); var sScale = d3 .scaleLinear() .domain([0, 1]) .range([vcolor.s, 0]); vcolor.s = sScale(uScale(data.u)); break; case "ul": vcolor = d3.hsl(vcolor); var lScale = d3 .scaleLinear() .domain([0, 1]) .range([vcolor.l, 1]); vcolor.l = lScale(uScale(data.u)); break; } return vcolor; } map.colorList = function() { return this.quantize() .range() .map(function(d) { return map(d); }); }; map.colorDists = function() { var clist = this.colorList(), matrix = new Array(clist.length), minDist, minPair = new Array(2), dist; for (var i = 0; i < matrix.length; i++) { matrix[i] = new Array(clist.length); for (var j = 0; j < matrix[i].length; j++) { dist = CIEDist(clist[i], clist[j]); matrix[i][j] = dist; if (i != j && ((i == 0 && j == 1) || dist < minDist)) { minDist = dist; minPair = [clist[i], clist[j]]; } } } matrix.minDist = minDist; matrix.minPair = minPair; return matrix; }; map.mode = function(newMode) { if (!arguments.length) { return mode; } else { mode = newMode; return map; } }; map.range = function(newRange) { if (!arguments.length) { return range; } else { range = newRange; return map; } }; map.quantize = function(newQuantization) { if (!arguments.length) { return quantization; } else { quantization = newQuantization; return map; } }; return map; }