D3: créer une échelle de couleurs continue avec de nombreuses chaînes / entrées pour la gamme et les valeurs de changement dynamique du domaine

j'essaie de créer une échelle de couleur linéaire pour une heatmap. Je veux l'échelle de couleurs pour aller à travers une large gamme de couleurs spécifiques, où la première couleur correspondant à la min des données et la dernière couleur doit être donné le maximum de données.

je sais que je peux le faire en donnant aussi les valeurs du domaine 17 entre le min et le max, mais je ne sais pas comment le faire dynamiquement si l'utilisateur est capable de changer l'ensemble de données (et donc changer la coloration de la heatmap)

En substance, je voudrais la suite, mais je sais que ça ne fonctionne pas

var colorScale = d3.scale.linear()
   .range(["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
           "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", 
           "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"])
   .domain([d3.min(dataset, function(d) {return d;}),
            d3.max(dataset, function(d) {return d;})]);

quelqu'un Peut-il me dire ce que je dois mettre dans 'le domaine' pour le faire fonctionner?

modifier: J'ai trouvé quelque chose qui fait ce que je veux. En utilisant R j'ai calculé 256 couleurs entre les 17 ci-dessus avec le concepteur.couleurs fonctions et mettez cela dans la gamme. Cela donne le sentiment d'une échelle de couleur continue

var colorScale = d3.scale.linear()
    .range(["#6363FF", "#6364FF", "#6364FF", "#6365FF",
            "... several other lines with color codes ..."
            "#FF6764", "#FF6564", "#FF6464", "#FF6364"])
    .domain(d3.range(1,257));

var quantize = d3.scale.quantile()
   .range(d3.range(1,257))
   .domain([d3.min(dataset, function(d) {return d;}), 
            d3.max(dataset, function(d) {return d;})]);

maintenant je peux utiliser la couleur dans ce mode

colorScale(quantize(dataset))

mais je me demande si cela peut aussi être fait en moins de lignes de code?

18
demandé sur Cœur 2013-07-16 12:08:25

3 réponses

Vous souhaitez diviser le problème. Définissez d'abord une échelle pour votre heatmap qui correspond à 0-1 à vos couleurs. Ensuite, définissez une deuxième échelle (dynamique) qui établit la correspondance de votre ensemble de données à 0-1. Vous pouvez ensuite combiner les échelles de peindre vos formes.

var colours = ["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB",
               "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", 
               "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"];

var heatmapColour = d3.scale.linear()
  .domain(d3.range(0, 1, 1.0 / (colours.length - 1)))
  .range(colours);

// dynamic bit...
var c = d3.scale.linear().domain(d3.extent(dataset)).range([0,1]);

// use the heatmap to fill in a canvas or whatever you want to do...
canvas.append("svg:rect")
  .data(dataset)
  .enter()
  // snip...
  .style("fill", function(d) {
     return heatmapColour(c(d));

de Plus, vous pouvez utiliser le d3.fonction d'extension pour obtenir le min et le max de l'ensemble de données en une seule fois.

26
répondu dwxw 2013-07-16 09:24:12

Utiliser echelles de seuil. Voici un rapide exemple:

coffee> d3 = require 'd3'
coffee> color = d3.scale.threshold().domain([5,30,100]).range(["red","orange","green"]);
coffee> color 6
'orange'
coffee> color 3
'red'
coffee> color 33
'green'
3
répondu Vadym Tyemirov 2014-02-21 11:18:55

un Quantitative De L'Échelle les plus Couleur Brasseur

// pick any number [3-9]
var numColors = 9;

var heatmapColour = d3.scale.quantize()
  .domain(d3.extent(dataset))
  .range(colorbrewer.Reds[numColors]);

// use the heatmap to fill in a canvas or whatever you want to do...
canvas.append("svg:rect")
  .data(dataset)
  .enter()
  // snip...
  .style("fill", function(d) {return heatmapColour(d);})
3
répondu reubano 2014-10-20 22:03:36