Coder Social home page Coder Social logo

d3-color's Introduction

d3-color

Even though your browser understands a lot about colors, it doesn’t offer much help in manipulating colors through JavaScript. The d3-color module therefore provides representations for various color spaces, allowing specification, conversion and manipulation. (Also see d3-interpolate for color interpolation.)

Resources

d3-color's People

Contributors

curran avatar danburzo avatar dependabot[bot] avatar devgru avatar fil avatar jasondavies avatar mbostock avatar mef avatar rich-harris avatar tschaub avatar zerovox avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3-color's Issues

color.hex() is not a function

IM trying to use this as the documentation suggests but when I create any color.hex() is throwing an error that it is not a function.

var white = d3.color("white"); console.log(white.hex());// Uncaught TypeError: white.hex is not a function

L*a*b* chromatic adaptation

While investigating why d3's lab() method gives subtly different results than, for example, Wolfram Alpha, I came to understand d3-color is missing a chromatic adaptation between the D65 (sRGB) and D50 (Lab) illuminants:

The process should be: Lab ↔ XYZ (D50) ↔ XYZ(D65) ↔ RGB

I'm not sure how important this adaptation is to the purpose of the library, but it boils down to using the matrices from this page:

const d50_to_d6 = ({ x, y, z }) => ({
	x: x * 0.9555766 - y * 0.0230393 + z * 0.0631636,
	y: x * -0.0282895 + y * 1.0099416 + z * 0.0210077,
	z: x * 0.0122982 - y * 0.0204830 + z * 1.3299098
});

const d65_to_d50 = ({ x, y, z }) => ({
	x: x * 1.0478112 + y * 0.0228866 - z * 0.0501270,
	y: x * 0.0295424 + y * 0.9904844 - z * 0.0170491,
	z: x * -0.0092345 + y * 0.0150436 + z * 0.7521316
});

What’s the range of *s* in Cubehelix?

in the color picker s has range [0,2]
but after i Played with it looks like values more then 2 are allowed
d3Color.cubehelix(370,3.4,0.15).toString() // "rgb(200, 0, 0)"
d3Color.cubehelix(370,3,0.15).toString() // "rgb(181, 0, 0)"
d3Color.cubehelix(370,2,0.15).toString() // "rgb(133, 5, 0)"
d3Color.cubehelix(370,1,0.15).toString() // "rgb(86, 22, 0)"

So I do not quite understand how is that working, can you add some comments or link to some resources (I'm familiar with original page and paper, but I have not seen implementation of it as a color space), (I'm thinking on implementing it as part of purescript-contrib/purescript-colors#31)

Issue with latest d3-color version (1.4.0)

Hi Mike,

Application was working fine until the new release of d3 color version(1.4.0). As soon as this new version has come, kubernetes started failing with below mentioned error where as same code is working fine in local. After lot of research we could identify the issue and as an interim fix we are overriding with older version "1.3.0" and it is working fine now. Request you to extend your help on this.
image

https://github.com/d3/d3-color

color.fade([delta=0.2])

Similar to color.brighter, but for succinctly modifying the opacity channel. It could return a new color whose opacity is max(0, min(1, this.opacity - delta)).

Parsing rgba() and hsla() values

Have you considered parsing strings with alpha channels? I know they wouldn't map to hex values, but it would be pretty cool if the alpha channel was stripped out and it returned a valid color (and not null).

Great work on these modules, really digging it.

oklab / oklch?

https://bottosson.github.io/posts/oklab/

Here's a list of the design choices behind oklab:

  • Should be an opponent color space, similar to for example CIELAB.
  • Should predict lightness, chroma and hue well. LL, CC and hh should be perceived as orthogonal, so one can be altered without affecting the other two. This is useful for things like turning an image black and white and increasing colorfulness without introducing hue shifts etc.
  • Blending two colors should result in even transitions. The transition colors should appear to be in between the blended colors (e.g. passing through a warmer color than either original color is not good).
  • Should assume a D65 whitepoint. This is what common color spaces like sRGB, rec2020 and Display P3 uses.
  • Should behave well numerically. The model should be easy to compute, numerically stable and differentiable.
  • Should assume normal well lit viewing conditions. The complexity of supporting different viewing conditions is not practical in most applications. Other models could be used in conjunction if this is needed in some case.
  • If the scale/exposure of colors are changed, the perceptual coordinates should just be scaled by a factor. More complex models that depend on absolute luminance should be avoided since the viewing conditions can not be accurately controlled and incorrect behavior would be confusing.

Some alpha-values not recognized

The following is a valid color (black with 50% opacity) but will not be recognized:

d3.color("rgba(0,0,0,.5)") === null // true

It seems that at least one digit is always required before the decimal point. I believe this can be fixed in the corresponding regex.

Link to d3 repositories for other color spaces in the README

Looking through the other pull requests on d3-color, I realized the approach for this repo is to keep a fairly minimal API and prefer creating separate plugins for the other color spaces. To that end, I'll close my vague issue #41 and propose and addition to the README that links to these other related repos, which I just realized exist:

(and any others I may be missing)

I'll gladly do the PR if that's okay!

Automatically pick N distinct colors?

This is not an "issue" per se with d3-color, but just an idea / research problem that you may want to consider.

I always thought it would be great to have an algorithm that automagically picks N distinct colors that are as far apart perceptually as possible, for representing categorical values. Perhaps d3.scale.category20() and friends fills this need currently in practice, but I feel like there should be an algorithm for this.

Here is a first attempt at such an algorithm that places points on a circle in LAB space (L is fixed, and the points vary only in (A, B), so they have equal luminance but different hue) http://bl.ocks.org/curran/dd73d3d8925cdf50df86.

Perhaps a better solution would be use Mitchell’s best-candidate algorithm for generating a Poisson-disc distribution in a limited region of (A, B) color space (perhaps a circle?), where the user could specify as input a fixed L value and the desired number of distinct colors. Also Lloyd relaxation might be another nice way to do this.

The API documentation might look something like this:


color.distinct(n, [L])

Returns an array of n colors that are perceptually distinct. If L is specified, it controls the fixed L value in LAB color space that the algorithm uses. If L is not specified, it defaults to 50.


Just an idea.

It's great to see all this activity on the new D3, excited to try it out!

Control over shortest path hue interpolation?

It’s useful to sometimes take the longer path when interpolating hue. For example, hue in the default cubehelix ramp goes through 540°. But this need extends beyond cubehelix—it seems reasonable to allow “long” hue interpolation in other cylindrical colorspaces, such as HCL and HSL, too.

This means: 1. Color instances in those spaces must be capable of representing hues outside of [0°,360°). Having hue default to that range when converting from another colorspace seems reasonable, though. 2. We need both “short” and “long” forms of interpolation for cylindrical colorspaces. It seems reasonable to default to short.

(I suppose it would also be possible to default to “long” if the change in hue is greater than or equal to 360°. But… that seems a little brittle, since you definitely might want to use “long” hue interpolation when the hue delta is in [180°,360°), too. So probably best to always make it explicit.)

Clamp chroma to displayable RGB gamut?

In R, fixup defaults to TRUE. We need some equivalent to this (but faster, hopefully, at least using binary search):

function fixup(c) {
  while (!c.displayable()) --c.c;
  return c;
}

This makes a pretty big difference if you want to, say, emulate ggplot2’s hue color scale.

Brightening black in RGB

What is the desired behaviour of brightening black colour? Right now it will return black.

const brighter = d3.rgb("#000000").brighter(); // {b: 0, g: 0, opacity: 1, r: 0}

Unexpected conversion to HSL

Convertion to HSL gives unexpected results. Consider:

import { hcl } from "d3-color";
const c = hcl(200, 100, 150);
console.log(c.formatHex());
console.log(c.formatRgb());
console.log(c.formatHsl());

Actual output in Chrome 86 on Mac:

#00ffff
rgb(0, 255, 255)
hsl(180.380573958081, -163.7644455443205%, -293.13231330226415%)

The hex and rgb notations are the same color: bright cyan. The HSL notation is different. The documentation also says the saturation and lightness values are clamped to the interval of 0-100, but they are not. Do I misunderstand how non-displayable colors are converted or is there a bug in the hsl converstion here?

Here’s another way to look at this:

const a = rgb(0, 255, 255);
const b = rgb(hcl(200, 100, 150));
a.formatRgb(); // rgb(0, 255, 255)
b.formatRgb(); // rgb(0, 255, 255)
a.formatHsl(); // hsl(180, 100%, 50%)
b.formatHsl(); // hsl(180.380573958081, -163.7644455443205%, -293.13231330226415%)

Default cubehelix color interpolators?

Maybe this should be in d3-scale, but it would be nice to have some standard Cubehelix color scales:

var defaultCubehelix = color.interpolateCubehelix(
  color.cubehelix(300, 0.5, 0.0),
  color.cubehelix(-240, 0.5, 1.0)
);

var perceptualRainbow1 = color.interpolateCubehelix(
  color.cubehelix(-100, 0.75, 0.35),
  color.cubehelix(80, 1.50, 0.8)
);

var perceptualRainbow2 = color.interpolateCubehelix(
  color.cubehelix(80, 1.50, 0.8),
  color.cubehelix(260, 0.75, 0.35)
);

Cubehelix gamma?

The Cubehelix color scheme allows a γ (gamma) parameter. I’m not sure how best to represent this concept if we define Cubehelix as a colorspace. Probably the colorspace assumes γ = 1, but then we allow interpolateCubehelixGamma(γ)? Ugh, with #4 we’ll also need interpolateCubehelixGammaLong.

Incorrect conversion from HCL / LCH to hex or rgb

Firstly, thank you @mbostock for all of your incredible work, every time i have no clue how i am going to achieve something, it seems that d3 has already created a solution.

One small issue i have spotted is that when creating a d3.hcl object (example used is d3.hcl(15,100,65)) and converting to either rgb or hex (using both .rgb or d3.rgb()), it provides the wrong values. Output from this conversion is #FF0077 and it should be #F8766D.

Tested with d3 5.9.2 & 6.2.0

Edit: The conversion seems to be the same as Chroma.js so maybe this isn't a d3 issue? The output varies massively to this http://hclwizard.org/hclcolorpicker/ which i think is using R to generate the colors / graphics

L*a*b* <-> sRGB conversions?

Most importantly: Thanks for your work on d3! 🎉 , ❤️ and 🥇!

I was trying to use d3-color for sRGB to CIE-L*a*b* conversions today:

$ node
> const d3 = require("d3-color")
undefined
> d3.lab(0,100,100).rgb()
Rgb {
  r: 109.26297015067321,
  g: -126.7018621426472,
  b: -236.7921286790844,
  opacity: 1 }
> d3.lab(50,-50,-50).rgb()
Rgb {
  r: -868.5123725460351,
  g: 143.16534084117143,
  b: 203.4499609542193,
  opacity: 1 }

You expect L*a*b* values to be [[0-100], [-100,100], [-100,100]], correct? What colorspace are these RGB values in? I was expecting [0,255].

Am I using the API incorrectly?

(This is with node v8.9.0, fwiw)

Add CIECAM02.

Possibly a better perceptual colorspace than Lab/Lch and Cubehelix?

Alpha value of 0 breaks rgb

When using an alpha value with d3.rgb, via rgba or hsla colors strings, the color values return NaN.

Is this expected behavior?

tested on [email protected]

d3.rgb('hsla(240,100%,25%,0)');

// returns
{
  r: NaN,
  b: NaN,
  g: NaN,
  opacity: 0,
}
d3.rgb('rgba(0,0,0,0)');

// returns
{
  r: NaN,
  b: NaN,
  g: NaN,
  opacity: 0,
}

Also interesting to note that the behavior of non-zero, but close to zero, alpha values return the expected color.

d3.rgb('rgba(0,0,0,0.001)');

// returns
{
  r: 0,
  b: 0,
  g: 0,
  opacity: 0.001,
}

Replace clamping with validation for RGB values

README says:

Colors are now validated upon construction.

In fact they are clamped, not validated.

IMHO clamping isn't a good idea for RGB constructor, it hides "invalid" LAB/HCL colors instead of notifying about them.
Would you mind throwing exception or returning special value for invalid colors?

It is the only way to check whether LAB/HCL color is "valid" or not.

I'm using this kind of validation here:
https://github.com/devgru/postcss-color-hcl/blob/master/index.js#L22

Various updates?

I am working on a color library that aims to support all the CSS Color Level 4 formats, and would love to contribute to d3-color with some updates:

  • HEX 4 and 8 formats
  • RGB(A) and HSL(A) current syntax (rgb(255 255 255 / 0.1), etc.)

And could add HSV and HSI color spaces.

(+ more as I sort them out)

I was wondering which of these are in the scope of d3-color and whether I can submit PRs.

Thanks!

CIEDE2000 color difference

In the spirit of I couldn't help it I've ported all the color difference metrics to work with d3-color here 👉 https://github.com/danburzo/d3-color-difference

Out of them the euclidean distances are trivial to compute by end-users, and from the rest CIEDE2000 is supposedly the most accurate, and a hassle to implement. May be a good addition to d3-color itself, or is it preferable as a separate package?

(Oooh, I missed this notebook!)

Document hcl functions

It would be lovely to have documentation for the argument ranges of the hcl color space, as there is for the other color spaces.

Should Lab and HCL colorspaces clamp luminance to [0, 100]?

They currently do, but I don’t think it makes sense. It only makes sense for RGB because of machine limitations. I suppose we could force the luminance to be non-negative, but I don’t think there’s any reason to limit the maximum value to 100.

non-es6 version?

Can you create a transpiled version of this project to your bower repo for browsers that arent es6 compliant?

Add formatHex8() to include opacity

To reproduce:

console.log(d3.color("#fff1").formatRgb());  // rgba(255, 255, 255, 0.06666666666666667)
console.log(d3.color("#fff1").formatHex());  // #ffffff <-- shouldn't this be #ffffff11?

I'd expect that formatHex would preserve opacity just as formatRgb does; however, opacity is clearly ignored in the function definition

function rgb_formatHex() {

LUV and XYZ.

Per #33 (comment), d3-color should support CIELUV in addition to CIELAB, and for compatibility with R, should redefine d3.hcl as polar CIELUV, but preserve d3.lch as polar CIELAB. We should also expose CIEXYZ for completeness.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.