admin管理员组

文章数量:1315367

I'm writing a sequential color scale for diverging numbers with D3 v4 and D3 Scale Chromatic.

Here is my function:

var divergentColor = function(value, theDomain, interpolation) {
    var theDomain = theDomain || [0, 50, 100];
    var theInterpolation = interpolation || 'BrBg';

    var scale = d3.scaleSequential()
      .interpolator(d3['interpolate' + theInterpolation])
      .domain(theDomain)
      .clamp(true);

    return scale(value);
};
  
divergentColor(25);
<script src=".v4.js"></script>
<script src=".v1.js"></script>

I'm writing a sequential color scale for diverging numbers with D3 v4 and D3 Scale Chromatic.

Here is my function:

var divergentColor = function(value, theDomain, interpolation) {
    var theDomain = theDomain || [0, 50, 100];
    var theInterpolation = interpolation || 'BrBg';

    var scale = d3.scaleSequential()
      .interpolator(d3['interpolate' + theInterpolation])
      .domain(theDomain)
      .clamp(true);

    return scale(value);
};
  
divergentColor(25);
<script src="https://d3js/d3.v4.js"></script>
<script src="https://d3js/d3-scale-chromatic.v1.js"></script>

I'm getting the following error when invoking this function:

d3.v4.js:12808 Uncaught TypeError: interpolator is not a function

This is D3's implementation of scaleSequential: https://github./d3/d3-scale/blob/master/src/sequential.js#L21

import {linearish} from "./linear";

export default function sequential(interpolator) {
  var x0 = 0,
      x1 = 1,
      clamp = false;

  function scale(x) {
    var t = (x - x0) / (x1 - x0);
    return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
  }

  scale.domain = function(_) {
    return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
  };

  scale.clamp = function(_) {
    return arguments.length ? (clamp = !!_, scale) : clamp;
  };

  scale.interpolator = function(_) {
    return arguments.length ? (interpolator = _, scale) : interpolator;
  };

  scale.copy = function() {
    return sequential(interpolator).domain([x0, x1]).clamp(clamp);
  };

  return linearish(scale);
}

It seems like a fairly straightforward function. Not sure what I'm doing wrong, or if there is an issue with D3 itself. Any advice?

Share Improve this question asked Feb 16, 2017 at 18:38 TaxFoundationTaxFoundation 3432 silver badges10 bronze badges 3
  • This is just a typo: you have to use BrBG instead of BrBg. – Gerardo Furtado Commented Feb 16, 2017 at 23:30
  • No difference. I've tested it with multiple interpolators copy-pasted from the docs and the result is the same. – TaxFoundation Commented Feb 17, 2017 at 15:05
  • I just wrote an answer with a snippet, check it. – Gerardo Furtado Commented Feb 18, 2017 at 0:44
Add a ment  | 

2 Answers 2

Reset to default 9

I was getting this error message because I failed to import d3-scale-chromatic. I hadn't realized it wasn't part of the default d3 namespace.

Basically, I started with something like this:

import * as d3 from 'd3';
var color = d3.scaleSequential(d3.interpolatePiYG);

And the fix was to change it to something like:

import * as d3 from 'd3';
import * as d3Chromatic from 'd3-scale-chromatic';
var color = d3.scaleSequential(d3Chromatic.interpolatePiYG);

After installing using npm install d3-scale-chromatic.

As I said in my ment, this is just a typo: it should be BrBG, not BrBg, since the name of the interpolator is d3.interpolateBrBG:

var divergentColor = function(value, theDomain, interpolation) {
    var theDomain = theDomain || [0, 50, 100];
    var theInterpolation = interpolation || 'BrBG';

    var scale = d3.scaleSequential()
      .interpolator(d3['interpolate' + theInterpolation])
      .domain(theDomain)
      .clamp(true);

    return scale(value);
};
  
console.log(divergentColor(25));
<script src="https://d3js/d3.v4.js"></script>
<script src="https://d3js/d3-scale-chromatic.v1.js"></script>

PS: Your domain is not correct. From the documentation:

Note that a sequential scale’s domain must be numeric and must contain exactly two values. (emphasis mine)

Thus, it has to be [0, 50], or [0, 100], or any bination of two values. Right now, using 3 values, D3 is gonna keep the first two values. You can see this in the next snippet:

var divergentColor = function(value, theDomain, interpolation) {
    var theDomain = theDomain || [0, 50, 100];
    var theInterpolation = interpolation || 'BrBG';

    var scale = d3.scaleSequential()
      .interpolator(d3['interpolate' + theInterpolation])
      .domain(theDomain)
      .clamp(true);

    console.log("The domain is: " + scale.domain());

    return scale(value);
};
  
divergentColor(25);
<script src="https://d3js/d3.v4.js"></script>
<script src="https://d3js/d3-scale-chromatic.v1.js"></script>

本文标签: javascriptd3scaleSequential quotinterpolator is not a functionquotStack Overflow