Why does my D3 v7.9.0 scatter plot fail to render points when using d3.schemeObservable10 for color scaling?
0 reputation · 24 Jan 2025, 20:24 UTC
0 reputation · 24 Jan 2025, 20:24 UTC
When upgrading to D3 version 7.9.0 I want to use the newly added d3.schemeObservable10 color palette for a scatter plot. The data binds correctly and SVG elements are created, but the circles remain invisible or are not styled as expected. I am unsure whether the issue stems from how the scheme is imported, how the scale is constructed, or a conflict with other D3 modules.
What steps can help isolate the problem? Are there known compatibility considerations when combining d3.schemeObservable10 with d3.scaleOrdinal? How can I verify that the color scale is returning valid values?
26800 reputation · 25 Jan 2025, 04:58 UTC
import { schemeObservable10 } from 'd3'; or via CDN d3.schemeObservable10.undefined errors; if the scheme cannot be found, the color scale will return undefined for every datum.const color = d3.scaleOrdinal().domain(data.map(d => d.category)).range(schemeObservable10);console.log(color('A'), color('B')); – you should see hex strings such as "#ff7f0e". If you see undefined or empty strings, the scale is not receiving a valid range..attr('fill', d => color(d.category)).fill attribute is present and contains a valid CSS color value.fill: none or opacity: 0 on circle elements.['#1f77b4', '#ff7f0e']. If points appear, the issue is isolated to the scheme import or its format.fill: 'steelblue') to confirm that data binding and SVG creation are still working.By systematically checking the import, the scale’s return values, and the resulting SVG attributes, you can pinpoint whether the problem lies with the schemeObservable10 array, the scale construction, or an external style override.
Use comments to ask for clarification. Post a solution as an answer.
2,350 reputation · 25 Jan 2025, 01:56 UTC
To build on the previous suggestions, it is important to verify how the scale handles data values that fall outside the defined domain. In D3 v7, if you explicitly set a domain using .domain([...]), d3.scaleOrdinal will still assign a color to an unknown value by implicitly adding that value to the domain and picking the next available color from the range.
However, if your data contains null, undefined, or empty strings in the category field, the scale may return a value that the SVG fill attribute cannot interpret, or it may exhaust the 10 colors in d3.schemeObservable10. If your dataset has more than 10 unique categories, the scale will wrap around and reuse colors from the start of the array.
Check the browser inspector for the fill attribute. If you see fill="undefined", the issue is likely that the accessor function is passing a missing value to the scale. You can prevent this by adding a fallback:
.attr('fill', d => color(d.category) || 'grey')