Merge pull request #694 from weaveworks/procedural-colors

Procedural colors (like #690 but merge to master)
This commit is contained in:
David
2015-11-24 18:41:40 +01:00
3 changed files with 44 additions and 15 deletions

View File

@@ -23,7 +23,7 @@ const Node = React.createClass({
let labelOffsetY = 18;
let subLabelOffsetY = 35;
const isPseudo = !!this.props.pseudo;
const color = isPseudo ? '' : this.getNodeColor(this.props.rank);
const color = isPseudo ? '' : this.getNodeColor(this.props.rank, this.props.label);
const onMouseEnter = this.handleMouseEnter;
const onMouseLeave = this.handleMouseLeave;
const onMouseClick = this.handleMouseClick;

View File

@@ -61,7 +61,7 @@ const NodeDetails = React.createClass({
return this.renderLoading();
}
const nodeColor = this.getNodeColorDark(details.rank);
const nodeColor = this.getNodeColorDark(details.rank, details.label_major);
const styles = {
controls: {
'backgroundColor': this.brightenColor(nodeColor)

View File

@@ -1,25 +1,54 @@
const d3 = require('d3');
const colors = d3.scale.category20();
const PSEUDO_COLOR = '#b1b1cb';
let colorIndex = 0;
const hueRange = [20, 330]; // exclude red
const hueScale = d3.scale.linear().range(hueRange);
// map hues to lightness
const lightnessScale = d3.scale.linear().domain(hueRange).range([0.5, 0.7]);
const startLetterRange = 'A'.charCodeAt();
const endLetterRange = 'Z'.charCodeAt();
const letterRange = endLetterRange - startLetterRange;
/**
* Converts a text to a 360 degree value
*/
function text2degree(text) {
const input = text.substr(0, 2).toUpperCase();
let num = 0;
let charCode;
for (let i = 0; i < input.length; i++) {
charCode = Math.max(Math.min(input[i].charCodeAt(), endLetterRange), startLetterRange);
num += Math.pow(letterRange, input.length - i - 1) * (charCode - startLetterRange);
}
hueScale.domain([0, Math.pow(letterRange, input.length)]);
return hueScale(num);
}
function colors(text, secondText) {
let hue = text2degree(text);
// skip green and shift to the end of the color wheel
if (hue > 70 && hue < 150) {
hue += 80;
}
const saturation = 0.6;
let lightness = 0.5;
if (secondText) {
// reuse text2degree and feed degree to lightness scale
lightness = lightnessScale(text2degree(secondText));
}
const color = d3.hsl(hue, saturation, lightness);
return color;
}
const NodeColorMixin = {
getNodeColor: function(text) {
colorIndex++;
// skip green and red (index 5-8 in d3.scale.category20)
if (colorIndex > 4 && colorIndex < 9) {
colors('_' + colorIndex);
return this.getNodeColor(text);
}
return colors(text);
getNodeColor: function(text, secondText) {
return colors(text, secondText);
},
getNodeColorDark: function(text) {
getNodeColorDark: function(text, secondText) {
if (text === undefined) {
return PSEUDO_COLOR;
}
const color = d3.rgb(colors(text));
const color = d3.rgb(colors(text, secondText));
let hsl = color.hsl();
// ensure darkness