You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3热力图异常:所有区域仅显示单一颜色问题排查

D3 Choropleth Map: All Regions Display Single Color (Color Scale Not Applying)

I'm trying to create a D3 choropleth map using ABS CSV data and GeoJSON geographic data, but during testing all regions are assigned a single color—there's no variation in shade based on value. I believe I've bound the values to each region's properties in the GeoJSON, but the color scale isn't working as expected.

Choropleth map showing uniform single color

My D3 Code

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>D3: Setting path fills dynamically to generate a choropleth</title> 
    <script type="text/javascript" src="d3.js"></script> 
    <style type="text/css"> /* No style rules here yet */ </style> 
</head> 
<body> 
<script type="text/javascript"> 
//Width and height 
var w = 1000; 
var h = 600; 

var path = d3.geoPath() 
    .projection(d3.geoMercator() 
        .center([151,-33.5]) 
        .scale(17000) 
        .translate([w/2,h/2])); 

//Define quantize scale to sort data values into buckets of color 
var color = d3.scaleQuantize() 
    .range(["rgb(237,248,233)","rgb(186,228,179)","rgb(116,196,118)","rgb(49,163,84)","rgb(0,109,44)"]); 
//Colors derived from ColorBrewer, by Cynthia Brewer, and included in 
//https://github.com/d3/d3-scale-chromatic 

//Create SVG element 
var svg = d3.select("body") 
    .append("svg") 
    .attr("width", w) 
    .attr("height", h); 

//Load in agriculture data 
d3.csv("ManagerArea.csv", function(data) { 
    //Set input domain for color scale 
    color.domain([ 
        d3.min(data, function(d) { return d.value; }), 
        d3.max(data, function(d) { return d.value; }) 
    ]); 

    //Load in GeoJSON data 
    d3.json("australia_adm2.json", function(json) { 
        //Merge the ag. data and GeoJSON 
        //Loop through once for each ag. data value 
        for (var i = 0; i < data.length; i++) { 
            //Grab state name 
            var dataState = data[i].state; 
            //Grab data value, and convert from string to float 
            var dataValue = parseFloat(data[i].value); 

            //Find the corresponding state inside the GeoJSON 
            for (var j = 0; j < json.features.length; j++) { 
                var jsonState = json.features[j].properties.sa4_name11; 

                if (dataState == jsonState) { 
                    //Copy the data value into the JSON 
                    json.features[j].properties.value = dataValue; 
                    //Stop looking through the JSON 
                    break; 
                } 
            } 
        } 

        //Bind data and create one path per GeoJSON feature 
        svg.selectAll("path") 
            .data(json.features) 
            .enter() 
            .append("path") 
            .attr("d", path) 
            .style("fill", function(d) { 
                //Get data value 
                var value = d.properties.value; 

                if (value) { 
                    //If value exists… 
                    return color(value); 
                } else { 
                    //If value is undefined… 
                    return "#ccc"; 
                } 
            }); 
    }); 
}); 
</script> 
</body> 
</html>

GeoJSON Data Structure Example

{"type":"FeatureCollection", "features": [ 
    {"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":...},"properties":{"cartodb_id":1,"sa4_name11":"Sydney - Baulkham Hills and Hawkesbury","right_dpop":38742,"right_opop":69540,"right_xcoord":150.8288053,"right_ycoord":-33.36860558}},...]

CSV Data

state,value
Capital Region,15558
Central Coast,15642
Central West,13074
Coffs Harbour - Grafton,6274
Far West and Orana,7968
Hunter Valley exc Newcastle,11717
Illawarra,13278
Mid North Coast,8758
Murray,8298
New England and North West,12884
Newcastle and Lake Macquarie,15980
Richmond - Tweed,12013
Riverina,11055
Southern Highlands and Shoalhaven,7191
Sydney - Baulkham Hills and Hawkesbury,19904
Sydney - Blacktown,14710
Sydney - City and Inner South,27758
Sydney - Eastern Suburbs,24778
Sydney - Inner South West,27081
Sydney - Inner West,24055
Sydney - North Sydney and Hornsby,39796
Sydney - Northern Beaches,24080
Sydney - Outer South West,12403
Sydney - Outer West and Blue Mountains,15767
Sydney - Parramatta,20323
Sydney - Ryde,13468
Sydney - South West,15090
Sydney - Sutherland,16901

Root Cause & Solution

The most likely issue is that you're setting the color scale's domain using string values instead of numeric values. When you load the CSV, the value field is parsed as a string by default. When you call d3.min(data, d => d.value) and d3.max(data, d => d.value), you're comparing strings lexicographically (e.g., "6274" is treated as larger than "39796" because "6" > "3"), which creates an invalid domain for your quantize scale. Since the scale expects numeric inputs, all your actual numeric values end up falling into the first color bucket, resulting in uniform coloring.

Fix 1: Convert values to numbers when setting the domain

Update the color.domain() section to parse d.value as a float:

color.domain([
    d3.min(data, function(d) { return parseFloat(d.value); }),
    d3.max(data, function(d) { return parseFloat(d.value); })
]);

Fix 2: Parse CSV values upfront (cleaner approach)

Modify your d3.csv call to convert the value to a number when loading the data, so you don't have to parse it repeatedly:

d3.csv("ManagerArea.csv", function(d) {
    // Convert value to number during CSV parsing
    return {
        state: d.state,
        value: parseFloat(d.value)
    };
}, function(data) {
    // Now data.value is numeric, so domain works correctly
    color.domain([
        d3.min(data, function(d) { return d.value; }),
        d3.max(data, function(d) { return d.value; })
    ]);

    // Rest of your code (loading GeoJSON, merging data, etc.) stays the same
});

Additional Checks

  • Verify that the state names in your CSV exactly match the sa4_name11 values in your GeoJSON (check for case sensitivity, extra spaces, or punctuation differences). Mismatches would result in gray regions, but it's still good to confirm.
  • Ensure you're using a compatible D3 version (your code uses v4/v5 syntax, so make sure your d3.js file is from that range—older versions have different scale APIs).

内容的提问来源于stack exchange,提问作者Jgreensie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:07:02