• Explore
  • Sites
  • Posts
  • Twitter
  • FAQs
  • Terms
  • Discord
  • Support
  • Privacy
Nathan Dorney
Nathan Dorney

Experimenting with conditional formatting in a node and edge interface

While conditional formatting is a familiar tool for improving table-based presentations of data, its application within a Node and Edge interface introduces some increased complexity. The sheer volume of data can easily result in clutter that obscures vital patterns and trends. Therefore, enhancing the usability of data visualisations without compromising their accuracy and clarity poses a significant challenge.

Attempt #1 Scaling

For the first attempt, I generated a colour in hexadecimal format based on a given value relative to a maximum value (defaulting to 9999 but this would need to be dynamic based on the actual data).

It calculates a scale from 0 to 1 based on where the value falls between a fixed minimum value of 1 and the maximum value. It then uses this scale to determine the red component (increasing with value) and the green component (decreasing with value), setting the blue component to a constant 50. The resulting RGB values are converted to a hexadecimal string and returned as the color code.

export function getColorBasedOnValue(value, maxValue = 9999) {
  const minValue = 1;
  const scale = (value - minValue) / (maxValue - minValue);
  const red = Math.min(255, Math.floor(255 * scale));
  const green = Math.max(0, Math.floor(200 * (1 - scale)));
  const blue = 50;
  return `#${red.toString(16).padStart(2, "0")}${green
    .toString(16)
    .padStart(2, "0")}${blue.toString(16).padStart(2, "0")}`;
}
Result of Attempt #1

This worked as a POC, but we really wanted to have a selection based on the brand colours rather than just red, green divergence.

Generating the colour pallets

Selecting the ideal shades required some going back and forth testing at different scale of data.. Ultimately, I opted for simplicity, adjusting the colours in 20% increments to create distinct layers of dark and light. This method ensures that each colour variation is both noticeable and harmonious, enhancing the overall clarity of the visualisation. I found d3-scale-chromatic and ColorBrewer's tooling really helpful inspiration for the project.

Extened brand pallete
Shade generating

Result

The function I ended up with selects a colour from the predefined palettes based on a given minimum and maximum value. It calculates an index into the selectedPalette array by dividing the range of possible values into segments corresponding to the number of colours in the palette. This index is based on where the value falls within these segments. It then ensures this index is within the bounds of the array to avoid errors. The function finally returns the hexadecimal colour code from the palette corresponding to the calculated index.

export function getColorBasedOnValue(value, maxValue = 9999, selectedPalette) {
  const hexValues = selectedPalette;

  // Calculate the index for the hex value based on the input value
  const segment = (maxValue - 1) / (hexValues.length - 1);
  let index = Math.min(hexValues.length - 1, Math.floor((value - 1) / segment));

  // Ensure index is within the bounds of the hexValues array
  index = Math.max(0, Math.min(index, hexValues.length - 1));

  // Return the hex value corresponding to the calculated index
  return hexValues[index];
}
Final Result
Send Nathan Dorney a reply about this page
Back to profile