【问题标题】:D3.js pie chart color scaleD3.js 饼图色标
【发布时间】:2017-03-01 18:41:21
【问题描述】:

考虑这样的数据集:

var pie_data = [{
    "hard_skill": "Strategy",
    "course_area_percentage": 9
}, {
    "hard_skill": "Analytics",
    "course_area_percentage": 18
}, {
    "hard_skill": "Economics",
    "course_area_percentage": 11
}, {
    "hard_skill": "Finance",
    "course_area_percentage": 7
}, {
    "hard_skill": "HR",
    "course_area_percentage": 5
}, {
    "hard_skill": "Innovation",
    "course_area_percentage": 2
}, {
    "hard_skill": "International",
    "course_area_percentage": 5
}, {
    "hard_skill": "Marketing",
    "course_area_percentage": 7
}, {
    "hard_skill": "Operations",
    "course_area_percentage": 14
}, {
    "hard_skill": "Others",
    "course_area_percentage": 11
}, {
    "hard_skill": "Project",
    "course_area_percentage": 11
}]

我正在创建一个饼图,以便将所有这些技能显示为图表的切片。然后的想法是为具有更高百分比的技能提供更绿的颜色(意味着它更重要),从红色到绿色的颜色等级。

我尝试使用具有不同范围和域的d3.scale.ordinal() and d3.scale.linear(),但颜色与上述模式不匹配。它们似乎是倒置的,像这样:

我的色标代码:

var pie_colorScale = d3.scale.ordinal()
    //.domain([0,pie_data.length])
    //.range(["#d7191c", "#eef200", "#008e15"]);                    
    //.range(["#d7191c","#f19d00","#eef200","#3fe256", "#008e15"]);
    .range(["#008e15", "#3fe256", "#eef200", "#f19d00", "#d7191c"]);

颜色到值的映射是否必须手动设置?

【问题讨论】:

    标签: javascript d3.js charts pie-chart


    【解决方案1】:

    鉴于您想要的结果...

    然后的想法是为具有更高百分比的技能提供更绿的颜色(意味着它更重要),从红色到绿色的颜色等级。

    ...,序数尺度不是合适的选择。

    您可以使用范围内有两种颜色的线性刻度,“红色”和“绿色”,但结果并不好。因此,此解决方案使用了“红色”、“黄色”和“绿色”范围内的三种颜色。

    这样做的诀窍是在域中使用三个值:

    var color = d3.scale.linear()
        .domain([d3.min(pie_data, d => d.course_area_percentage),
            d3.mean(pie_data, d => d.course_area_percentage),
            d3.max(pie_data, d => d.course_area_percentage)
        ])
        .range(["red", "yellow", "green"]);
    

    这是一个演示:

    var pie_data = [{
      "hard_skill": "Strategy",
      "course_area_percentage": 9
    }, {
      "hard_skill": "Analytics",
      "course_area_percentage": 18
    }, {
      "hard_skill": "Economics",
      "course_area_percentage": 11
    }, {
      "hard_skill": "Finance",
      "course_area_percentage": 7
    }, {
      "hard_skill": "HR",
      "course_area_percentage": 5
    }, {
      "hard_skill": "Innovation",
      "course_area_percentage": 2
    }, {
      "hard_skill": "International",
      "course_area_percentage": 5
    }, {
      "hard_skill": "Marketing",
      "course_area_percentage": 7
    }, {
      "hard_skill": "Operations",
      "course_area_percentage": 14
    }, {
      "hard_skill": "Others",
      "course_area_percentage": 11
    }, {
      "hard_skill": "Project",
      "course_area_percentage": 11
    }]
    var width = 500,
      height = 500,
      radius = Math.min(width, height) / 2;
    
    
    var color = d3.scale.linear()
    	.domain([d3.min(pie_data, d=>d.course_area_percentage),
    	d3.mean(pie_data, d=>d.course_area_percentage),
    	d3.max(pie_data, d=>d.course_area_percentage)])
    	.range(["red", "yellow", "green"]);
    
    var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);
    
    var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d.course_area_percentage;
      });
    
    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    
    var g = svg.selectAll(".arc")
      .data(pie(pie_data))
      .enter().append("g")
      .attr("class", "arc");
    
    g.append("path")
      .attr("d", arc)
      .style("stroke", "gray")
      .style("fill", function(d) {
        return color(d.data.course_area_percentage);
      });
    
    g.append("text")
    .attr("text-anchor", "middle")
      .attr("transform", function(d) {
        return "translate(" + arc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .text(function(d) {
        return d.data.hard_skill;
      });
    
    function type(d) {
      d.population = +d.population;
      return d;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

    作为替代解决方案,如果您想使用您在问题中编写的颜色数组...

    .range(["#008e15", "#3fe256", "#eef200", "#f19d00", "#d7191c"]);
    

    ...您应该改用量化(或分位数)比例:

    var color = d3.scale.quantize()
        .domain(d3.extent(pie_data, d => d.course_area_percentage))
        .range(["#d7191c", "#f19d00", "#eef200", "#3fe256", "#008e15"]);
    

    这里是演示:

    var pie_data = [{
      "hard_skill": "Strategy",
      "course_area_percentage": 9
    }, {
      "hard_skill": "Analytics",
      "course_area_percentage": 18
    }, {
      "hard_skill": "Economics",
      "course_area_percentage": 11
    }, {
      "hard_skill": "Finance",
      "course_area_percentage": 7
    }, {
      "hard_skill": "HR",
      "course_area_percentage": 5
    }, {
      "hard_skill": "Innovation",
      "course_area_percentage": 2
    }, {
      "hard_skill": "International",
      "course_area_percentage": 5
    }, {
      "hard_skill": "Marketing",
      "course_area_percentage": 7
    }, {
      "hard_skill": "Operations",
      "course_area_percentage": 14
    }, {
      "hard_skill": "Others",
      "course_area_percentage": 11
    }, {
      "hard_skill": "Project",
      "course_area_percentage": 11
    }]
    var width = 500,
      height = 500,
      radius = Math.min(width, height) / 2;
    
    
    var color = d3.scale.quantize()
    	.domain(d3.extent(pie_data, d=>d.course_area_percentage))
    	.range(["#d7191c", "#f19d00", "#eef200", "#3fe256", "#008e15"]);
    
    var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);
    
    var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) {
        return d.course_area_percentage;
      });
    
    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
    
    var g = svg.selectAll(".arc")
      .data(pie(pie_data))
      .enter().append("g")
      .attr("class", "arc");
    
    g.append("path")
      .attr("d", arc)
    	.style("stroke", "gray")
      .style("fill", function(d) {
        return color(d.data.course_area_percentage);
      });
    
    g.append("text")
    .attr("text-anchor", "middle")
      .attr("transform", function(d) {
        return "translate(" + arc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .text(function(d) {
        return d.data.hard_skill;
      });
    
    function type(d) {
      d.population = +d.population;
      return d;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

    【讨论】:

    • 您提出的第一个解决方案似乎足以满足这种情况。在您的第二个解决方案中,颜色插值使不同的值具有相同的颜色,在我的情况下这并不完美。我需要展示这些区域之间的所有差异。第一个线性比例可以解决问题。
    • 这正是线性刻度和量化/分位数刻度之间的区别。量化/分位数比例将使用范围内的颜色。因此,如果该范围只有 5 种颜色,您将在图表中获得 5 种颜色。另一方面,线性刻度会在最小值/最大值之间创建几种不同的颜色。
    猜你喜欢
    • 2011-12-24
    • 2014-02-19
    • 2014-03-23
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    相关资源
    最近更新 更多