0%

Grouped Bar

不同地区、不同季度销售量。

设计思路

表格给出的数据具有同类项:同季度或者同地区。

可以把相同季度的数据组合,以区域为横轴,销售量为纵轴,每个季度中画出4个季度的销售量(方案1)。

也可以反过来,以季度为横轴,销售量为纵轴,每个季度中画出3个区域的销售量(方案2)。

方案

方案1

HTML

<html>
<head> <p>Sales of different Regions and Quarters</p> </head>
<body>
<meta charset="utf-8">
<script src = "https://d3js.org/d3.v4.js"></script>
<div id = "sales" ></div>
<script>
// title
var p = d3.select("body")
.selectAll("p")
.style("color","#1979a9")
.style("font-size","24px");

// dimensions and margins
var margin = { top: 10, right: 30, bottom: 20, left: 50 },
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#sales")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g") // group
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Data
d3.csv("https://raw.githubusercontent.com/Co10/d3_files/master/CSV_files/01/quarter_region_data.csv", function(data) {

// List of subgroups = header of the csv files = soil condition here
var subgroups = data.columns.slice(1)

// List of groups = species here = value of the first column called group -> I show them on the X axis
var groups = d3.map(data, function(d) { return (d.group) }).keys()

// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.4])
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(0));

// Add Y axis
var y = d3.scaleLinear()
.domain([0, 90])
.range([height, 0]);
svg.append("g")
.call(d3.axisLeft(y));

// Another scale for subgroup position?
var xSubgroup = d3.scaleBand()
.domain(subgroups)
.range([0, x.bandwidth()])
.padding([0.2])

// color
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#248760','#e33617','#ecb814','#66abdd'])

var gbars = svg.append("g")
.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d) { return "translate(" + x(d.group) + ",0)"; });
gbars.selectAll("rect")
.data(function(d) { return subgroups.map(function(key) { return {key: key, value: d[key]}; }); })
.enter().append("rect")
.attr("x", function(d) { return xSubgroup(d.key); })
.attr("y", function(d) { return y(d.value); })
.attr("width", xSubgroup.bandwidth())
.attr("height", function(d) { return height - y(d.value); })
.attr("fill", function(d) { return color(d.key); });

svg.append("text")
.attr("x",5)
.attr("y",0)
.text("Sales")
.style("font-size", "12px")
.attr("alignment-baseline","middle")

svg.append("circle")
.attr("cx",280)
.attr("cy",10)
.attr("r", 4)
.style("fill", color(1))
svg.append("circle")
.attr("cx",280)
.attr("cy",30)
.attr("r", 4)
.style("fill", color(2))
svg.append("circle")
.attr("cx",280)
.attr("cy",50)
.attr("r", 4)
.style("fill", color(3))
svg.append("circle")
.attr("cx",280)
.attr("cy",70)
.attr("r", 4)
.style("fill", color(4))
svg.append("text")
.attr("x", 290)
.attr("y", 10)
.text("Quarter 1")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
svg.append("text")
.attr("x", 290)
.attr("y", 30)
.text("Quarter 2")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
svg.append("text")
.attr("x", 290)
.attr("y", 50)
.text("Quarter 3")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
svg.append("text")
.attr("x", 290)
.attr("y", 70)
.text("Quarter 4")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
})
</script>
</body>
</html>

方案2

HTML

<html>
<head> <p>Sales of different Quarters and Regions</p> </head>
<body>
<meta charset="utf-8">
<script src = "https://d3js.org/d3.v4.js"></script>
<div id = "sales" ></div>
<script>
// title
var p = d3.select("body")
.selectAll("p")
.style("color", "#1979a9")
.style("font-size","24px");

// dimensions and margins
var margin = { top: 10, right: 30, bottom: 20, left: 50 },
width = 460 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#sales")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g") // group
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Data
d3.csv("https://raw.githubusercontent.com/Co10/d3_files/master/CSV_files/01/region_quarter_data.csv", function(data) {

// List of subgroups = header of the csv files = soil condition here
var subgroups = data.columns.slice(1)

// List of groups = species here = value of the first column called group -> I show them on the X axis
var groups = d3.map(data, function(d) { return (d.group) }).keys()

// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.4])
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).tickSize(0));

// Add Y axis
var y = d3.scaleLinear()
.domain([0, 90])
.range([height, 0]);
svg.append("g")
.call(d3.axisLeft(y));

// Another scale for subgroup position?
var xSubgroup = d3.scaleBand()
.domain(subgroups)
.range([0, x.bandwidth()])
.padding([0.2])

// color
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#99cccc','#66b2b2','#329999'])

var gbars = svg.append("g")
.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d) { return "translate(" + x(d.group) + ",0)"; });
gbars.selectAll("rect")
.data(function(d) { return subgroups.map(function(key) { return {key: key, value: d[key]}; }); })
.enter().append("rect")
.attr("x", function(d) { return xSubgroup(d.key); })
.attr("y", function(d) { return y(d.value); })
.attr("width", xSubgroup.bandwidth())
.attr("height", function(d) { return height - y(d.value); })
.attr("fill", function(d) { return color(d.key); });

svg.append("text")
.attr("x",5)
.attr("y",0)
.text("Sales")
.style("font-size", "12px")
.attr("alignment-baseline","middle")

svg.append("circle")
.attr("cx",350)
.attr("cy",10)
.attr("r", 4)
.style("fill", color(1))
svg.append("circle")
.attr("cx",350)
.attr("cy",30)
.attr("r", 4)
.style("fill", color(2))
svg.append("circle")
.attr("cx",350)
.attr("cy",50)
.attr("r", 4)
.style("fill", color(3))

svg.append("text")
.attr("x", 360)
.attr("y", 10)
.text("East")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
svg.append("text")
.attr("x", 360)
.attr("y", 30)
.text("West")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
svg.append("text")
.attr("x", 360)
.attr("y", 50)
.text("North")
.style("font-size", "12px")
.attr("alignment-baseline","middle")

svg.append("text")
.attr("x", 360)
.attr("y", 380)
.text("Quarter")
.style("font-size", "12px")
.attr("alignment-baseline","middle")
})
</script>
</body>
</html>

实现方法

通过 d3.map 实现组合。

总结

方案1主要比较的是同一地区、不同季度的销售额:东部:第三季度尤为突出;西部:二、三季度较为突出;北部:4季度持平。

方案2主要比较的是同一季度、不同地区的销售额:1、2、4季度均是东部 < 西部 < 北部的明显阶梯形式,然而第三季度东部反常,销售额极高。

由于题目也没给太多信息(卖的是什么,销售额的单位),可以反思,是否是第三季度东部地区的销售额的数据错了。

参考模板

https://www.d3-graph-gallery.com/graph/barplot_grouped_basicWide.html