Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide some color and spectrum creating functions #293

Closed
1 task done
cchaos opened this issue Aug 6, 2019 · 3 comments
Closed
1 task done

Provide some color and spectrum creating functions #293

cchaos opened this issue Aug 6, 2019 · 3 comments
Labels
:colors colors related issue enhancement New feature or request :styling Styling related issue

Comments

@cchaos
Copy link
Contributor

cchaos commented Aug 6, 2019

Is your feature request related to a problem? Please describe.
Right now, when you provide an array of colors, the chart simply iterates consecutively through the array, stopping when it's reached the last series. This works great for categorical style charts, but not for quantitative or tend-like charts.

Describe the solution you'd like
Provide some color functions that allow consumers to pass 1+ colors, and the number of stops, then returns an array of colors interpolated based on those parameters.

Something like:

const function createSpectrum(colors: [], numSeries: number) {
  if (colors.length === 1) {
    // Create a spectrum using the color[0] as the middle (or near middle)
    'https://d.pr/free/i/o9J63Q'
  } else if (colors.length === 2) {
    // Create a spectrum using the color[0] as the first and color[1] as the last
    'https://d.pr/free/i/4kD8tq'
  } else {
    // Create a spectrum equally spacing out the array of colors
    'https://d.pr/free/i/kQRypX'
  }
}

You might even want to consider using Chroma.js as is used by the tool in the screenshots above.

Describe alternatives you've considered
Providing this in EUI instead. But it makes more sense for this library to provide it.

This was my hacky way of creating these functions:

import { colorPalette } from '@elastic/eui/src/services';

switch (this.state.colorType) {
  case 'Trend':
    // Three color
    firstColor = 'green';
    lastColor = 'red'
    middleColor = 'gray';

    const half = Math.round(numSeries / 2);

    if (half < 2) {
      vizColors = [firstColor, lastColor];
      break;
    } else {
      let firstHalf = colorPalette(firstColor, middleColor, half);
      let lastHalf = colorPalette(middleColor, lastColor, half);

      if (numSeries % 2) {
        // Number is odd
        const removeFirstColor = lastHalf.shift();
      } else {
        firstHalf = colorPalette(firstColor, middleColor, half + 1);
        lastHalf = colorPalette(middleColor, lastColor, half + 1);
        const removeFirstColor = lastHalf.shift();
        const removeLastColor = firstHalf.pop();
      }
      vizColors = [...firstHalf, ...lastHalf];
      break;
    }

  case 'Quantity':
    // Single color
    firstColor = 'white';
    lastColor = 'green';
    vizColors = colorPalette(
      firstColor,
      lastColor,
      numSeries + 1
    );
    // Remove the first white color since we can't use white on white
    const removeFirstColor = vizColors.shift();
    break;
}

Additional context

Checklist

  • this request is checked against already exist requests
  • [ ] every related Kibana issue is listed under Kibana Cross Issues list
  • [ ] kibana cross issue tag is associated to the issue if any kibana cross issue is present
@cchaos cchaos added enhancement New feature or request :styling Styling related issue labels Aug 6, 2019
@cchaos
Copy link
Contributor Author

cchaos commented Aug 6, 2019

So this was my attempt at using Chroma.js It does seem to work a little better in terms of finding the right interpolation. Though I think it can be expanded on/cleaned up. I'm going to leave it just on the docs side EUI for now.

import chroma from 'chroma-js';
export function createSpectrum(
  colors,
  steps = 5,
  diverging = false,
  correctLightness = true,
  bezier = true
) {
  if (colors.length < 2) {
    console.warn(
      'createSpectrum expects the colors array to have at least 2 colors'
    );
    return;
  }

  diverging = diverging || colors.length > 2;

  const even = steps % 2 === 0;
  const numStepsLeft = diverging
    ? Math.ceil(steps / 2) + (even ? 1 : 0)
    : steps;
  const numStepsRight = diverging ? Math.ceil(steps / 2) + (even ? 1 : 0) : 0;

  const numColorsHalf =
    Math.ceil(colors.length / 2) + (colors.length % 2 === 0 ? 1 : 0);

  const colorsLeft = colors.filter(function(item, index) {
    if (index < numColorsHalf) {
      return true; // keep it
    }
  });
  const colorsRight = colors
    .reverse()
    .filter(function(item, index) {
      if (index < numColorsHalf) {
        return true; // keep it
      }
    })
    .reverse();

  function createSteps(colors, steps) {
    return colors.length
      ? chroma
          .scale(bezier && colors.length > 1 ? chroma.bezier(colors) : colors)
          .correctLightness(correctLightness)
          .colors(steps)
      : [];
  }

  const stepsLeft = createSteps(colorsLeft, numStepsLeft);
  const stepsRight = createSteps(colorsRight, numStepsRight);

  const spectrum = (even && diverging
    ? stepsLeft.slice(0, stepsLeft.length - 1)
    : stepsLeft
  ).concat(stepsRight.slice(1));

  return spectrum;
}

@nickofthyme nickofthyme self-assigned this Aug 15, 2019
@nickofthyme nickofthyme removed their assignment Oct 29, 2019
@majagrubic majagrubic self-assigned this Oct 31, 2019
@markov00
Copy link
Member

@markov00
Copy link
Member

Closing as this is not a priority right now

@markov00 markov00 closed this as not planned Won't fix, can't repro, duplicate, stale Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:colors colors related issue enhancement New feature or request :styling Styling related issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants