Tengo un SVG en el que me dirijo a un determinado elemento de ruta con id: _116 .
Puedo llenar el camino fácilmente con un color sólido haciendo esto:
d3.select("path#_116").style("fill", 'blue');Sin embargo, digamos que tengo un color de escala lineal, por lo que quiero que se le aplique un degradado:
let scale = d3.scaleLinear() .domain([1,10]) .range(["white", "blue"]); d3.select("path#_116").style("fill", scale);Esto simplemente no funciona. Por alguna razón, está configurando el relleno en un color negro (# 212a39) que parece provenir del elemento hermano como se muestra a continuación:
¿Alguna idea de lo que está pasando aquí?
La función de escala devolverá un solo color para un valor proporcionado (como ocurre con todas las funciones de escala de D3), lo que probablemente explica el resultado que está viendo. La escala de forma predeterminada no está sujeta, por lo que la escala interpolará valores fuera del dominio y devolverá valores fuera del rango, lo que explica por qué tiene un valor que no parece encajar en su dominio.
Las funciones de escalado no modifican el DOM, pero un degradado requiere elementos dentro del SVG para representar los degradados. Por lo general, los gradientes son hijos de una etiqueta defs:
<svg> <defs> <linearGradient id="gradient"> <stop stop-color="white" offset="0%"/> <stop stop-color="blue" offset="100%"/> </linearGradient> </defs> <rect width=300 height=100 fill="url(#gradient)"></rect> </svg>Si tiene un SVG existente y desea modificar una sola ruta, podemos agregar las definiciones, el degradado, las paradas y aplicarlo a una ruta determinada:
d3.xml("https://upload.wikimedia.org/wikipedia/commons/a/ab/Isobates-simple_example.svg") .then(function(image) { let svg = d3.select("body") .append(()=>image.documentElement); let gradient = svg.append("defs") .append("linearGradient") .attr("id","gradient"); gradient.append("stop") .attr("stop-color","white") .attr("offset","0%") gradient.append("stop") .attr("stop-color","blue") .attr("offset","100%"); svg.selectAll("#path3156") .style("fill", "url(#gradient)"); }) <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.1.0/d3.min.js"></script>Hay formas en que puede hacer esto de manera más eficiente, aunque generalmente logrará la misma estructura en el DOM (usar .append() y .html() puede ahorrar algunas líneas). Y D3 también es completamente opcional: esto es solo agregar algunos elementos al DOM y configurar el relleno de un elemento existente.
Su pregunta parece estar relacionada con un gradiente singular, pero si tenemos muchos gradientes, la respuesta se vuelve un poco más complicada si queremos que los gradientes se basen en datos e incorporen la escala en la mezcla. Como no creo que estés preguntando eso, lo dejaré para otro momento.