En los siguientes ejemplos vamos a coger una escala que empieza y termina en los colores mostrados abajo (, ). Vamos a mapearla como una escala lineal en D3 y aplicaremos diferentes interpolaciones de color.
El código común a todas las escalas es el siguiente:
var width = 700,
height = 175,
lenght = 20; // Cantidad de colores en cada barra
var unit = width/lenght; // Ancho de cada color
/**
* Renderiza una barra de colores en un contenedor SVG
* usando un interpolador de D3.
*
* @param {string} svgId - Identificador del elemento SVG
* donde será renderizada la barra de colores.
* @param {object} interpolator - Interpolador D3 usado
* para construir la escala.
**/
var renderColorsBar = function(svgId, interpolator) {
var colorScale = d3.scaleLinear()
.domain([1, lenght])
.interpolate(interpolator)
.range([d3.rgb(color1), d3.rgb(color2)]);
for (var i = 0; i < lenght; i++) {
d3.select(svgId)
.attr("height", height)
.attr("width", width)
.append("rect")
.attr("x", i*unit )
.attr("y", 0)
.attr("width", unit)
.attr("height", 200)
.style("fill", colorScale(i));
}
}
Interpoladores desde d3-interpolate
Devuelve un interpolador en el espacio de color RGB entre los colores a
y b
con un parámetro gamma
configurable (1
si no es especificado).
Podemos cambiar el parámetro gamma
de un interpolador con la función interpolator.gamma(x).
Input
<svg id="colors-interpolate-rgb-gamma"></div>
<script>
var interpolator = d3.interpolateRgb.gamma(2);
renderColorsBar("#colors-interpolate-rgb-gamma", interpolator);
</script>
Output
Devuelve un interpolador en el espacio de color HSL entre los colores a
y b
.
Devuelve un interpolador en el espacio de color Lab entre los colores a
y b
.
Devuelve un interpolador en el espacio de color HCL entre los colores a
y b
.
Devuelve un interpolador en el espacio de color Cubehelix entre los colores a
y b
.
Para entender claramente lo que hacen los interpoladores, pongamos este sencillo interpolador RGB de ejemplo con Python (el código fuente está sacado de aquí):
import string
def make_color_tuple(color):
"""Convierte algo como "#000000" en "0,0,0"
ó "#FFFFFF" en "255,255,255".
"""
R = color[1:3]
G = color[3:5]
B = color[5:7]
R = int(R, 16)
G = int(G, 16)
B = int(B, 16)
return R,G,B
def interpolate_tuple( startcolor, goalcolor, steps ):
"""Toma dos colores RGB o los mezcla en
un número específico de pasos. Devuelve
la lista de todos los colores generados.
"""
R = startcolor[0]
G = startcolor[1]
B = startcolor[2]
targetR = goalcolor[0]
targetG = goalcolor[1]
targetB = goalcolor[2]
DiffR = targetR - R
DiffG = targetG - G
DiffB = targetB - B
buffer = []
for i in range(0, steps +1):
iR = R + (DiffR * i / steps)
iG = G + (DiffG * i / steps)
iB = B + (DiffB * i / steps)
hR = string.replace(hex(iR), "0x", "")
hG = string.replace(hex(iG), "0x", "")
hB = string.replace(hex(iB), "0x", "")
if len(hR) == 1:
hR = "0" + hR
if len(hB) == 1:
hB = "0" + hB
if len(hG) == 1:
hG = "0" + hG
color = string.upper("#"+hR+hG+hB)
buffer.append(color)
return buffer
def interpolate(startcolor, goalcolor, steps):
"""Envoltura para la función ``interpolate_tuple``
que acepta colores como "#CCCCCC".
"""
start_tuple = make_color_tuple(startcolor)
goal_tuple = make_color_tuple(goalcolor)
return interpolate_tuple(start_tuple, goal_tuple, steps)
def printchart(startcolor, endcolor, steps):
"""Imprime los colores que forman la escala
en formato exadecimal.
:param startcolor: Color de comienzo.
:type startcolor: str
:param endcolor: Color final.
:type endcolor: str
:param steps: Número de pasos de la escala.
:type steps: int
"""
colors = interpolate(startcolor, endcolor, steps)
for color in colors:
print(color)
# Muestra 16 valores de gradiente entre esos dos colores
printchart("#999933", "#6666FF", 16)