我使用D3分组了条形图。图表是使用d3.stack()
构建的,但是数据与y轴域不匹配,并且条形图的高度非常小。有人可以让我知道我在想什么吗?
摘要:
//DATA
var data = [
{
category: "test1",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test1",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
category: "test2",
type1: 150,
type2: 100,
type3: 0,
column: "column1"
},
{
category: "test2",
type1: 0,
type2: 0,
type3: 400,
column: "column2"
}
];
//INITIAL SETUP
var margin = { top: 30, right: 10, bottom: 80, left: 80 };
var width = document.documentElement.offsetWidth - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var barwidth = 40;
var graph = d3
.select("#chart-area")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x0 = d3
.scaleBand()
.rangeRound([0, width])
.paddingInner(0.1);
var x1 = d3.scaleBand().padding(0.05);
var y = d3.scaleLinear().range([height, 0]).domain([0,500]);
var y1 = d3.scaleBand();
var z = d3.scaleOrdinal().range(["#98abc5", "#8a89a6"]);
var stack = d3.stack().offset(d3.stackOffsetExpand);
x0.domain(
data.map(function(d) {
return d.category;
})
);
x1
.domain(
data.map(function(d) {
return d.column;
})
)
.range([0, x0.bandwidth()])
.padding(0.2);
z.domain(Object.keys(data[0]).filter(x => x !== "category" && x !== "column"));
var keys = z.domain(); //["type1", "type2", "type3"];
var stackData = stack.keys(keys)(data);
var serie = graph
.selectAll(".serie")
.data(stackData)
.enter()
.append("g")
.attr("class", "serie")
.attr("fill", function(d) {
return z(d.key);
});
serie
.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "serie-rect")
.attr("transform", function(d) {
return "translate(" + x0(d.data.category) + ",0)";
})
.attr("x", function(d) {
return x1(d.data.column)+x1.bandwidth()/ 2 - 20;
})
.attr("y", function(d) {
return y(d[1]);
})
.attr("height", function(d) {
return y(d[0]) - y(d[1]);
})
.attr("width", barwidth);
graph
.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x0));
graph
.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chart-area"></div>
答案 0 :(得分:1)
这里的问题只是使用stack.offset(d3.stackOffsetExpand)
。
如果您查看API,则会看到d3.stackOffsetExpand
:
应用零基线并标准化每个点的值,以使顶线始终为一。
因此,您所有的值都从0
到1
。
这里是没有d3.stackOffsetExpand
的相同代码:
//DATA
var data = [
{
category: "test1",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test1",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
category: "test2",
type1: 150,
type2: 100,
type3: 0,
column: "column1"
},
{
category: "test2",
type1: 0,
type2: 0,
type3: 400,
column: "column2"
}
];
//INITIAL SETUP
var margin = { top: 30, right: 10, bottom: 80, left: 80 };
var width = document.documentElement.offsetWidth - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var barwidth = 40;
var graph = d3
.select("#chart-area")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x0 = d3
.scaleBand()
.rangeRound([0, width])
.paddingInner(0.1);
var x1 = d3.scaleBand().padding(0.05);
var y = d3.scaleLinear().range([height, 0]).domain([0,500]);
var y1 = d3.scaleBand();
var z = d3.scaleOrdinal().range(["#98abc5", "#8a89a6"]);
var stack = d3.stack();
x0.domain(
data.map(function(d) {
return d.category;
})
);
x1
.domain(
data.map(function(d) {
return d.column;
})
)
.range([0, x0.bandwidth()])
.padding(0.2);
z.domain(Object.keys(data[0]).filter(x => x !== "category" && x !== "column"));
var keys = z.domain(); //["type1", "type2", "type3"];
var stackData = stack.keys(keys)(data);
var serie = graph
.selectAll(".serie")
.data(stackData)
.enter()
.append("g")
.attr("class", "serie")
.attr("fill", function(d) {
return z(d.key);
});
serie
.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "serie-rect")
.attr("transform", function(d) {
return "translate(" + x0(d.data.category) + ",0)";
})
.attr("x", function(d) {
return x1(d.data.column)+x1.bandwidth()/ 2 - 20;
})
.attr("y", function(d) {
return y(d[1]);
})
.attr("height", function(d) {
return y(d[0]) - y(d[1]);
})
.attr("width", barwidth);
graph
.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x0));
graph
.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chart-area"></div>
另一方面,如果您确实想使用d3.stackOffsetExpand
,请相应地更改y
域:
var y = d3.scaleLinear().range([height, 0]);
通过删除域,它默认为[0, 1]
。
以下是具有此更改的代码:
//DATA
var data = [
{
category: "test1",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test1",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
category: "test2",
type1: 150,
type2: 100,
type3: 0,
column: "column1"
},
{
category: "test2",
type1: 0,
type2: 0,
type3: 400,
column: "column2"
}
];
//INITIAL SETUP
var margin = { top: 30, right: 10, bottom: 80, left: 80 };
var width = document.documentElement.offsetWidth - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var barwidth = 40;
var graph = d3
.select("#chart-area")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x0 = d3
.scaleBand()
.rangeRound([0, width])
.paddingInner(0.1);
var x1 = d3.scaleBand().padding(0.05);
var y = d3.scaleLinear().range([height, 0]);
var y1 = d3.scaleBand();
var z = d3.scaleOrdinal().range(["#98abc5", "#8a89a6"]);
var stack = d3.stack().offset(d3.stackOffsetExpand);
x0.domain(
data.map(function(d) {
return d.category;
})
);
x1
.domain(
data.map(function(d) {
return d.column;
})
)
.range([0, x0.bandwidth()])
.padding(0.2);
z.domain(Object.keys(data[0]).filter(x => x !== "category" && x !== "column"));
var keys = z.domain(); //["type1", "type2", "type3"];
var stackData = stack.keys(keys)(data);
var serie = graph
.selectAll(".serie")
.data(stackData)
.enter()
.append("g")
.attr("class", "serie")
.attr("fill", function(d) {
return z(d.key);
});
serie
.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "serie-rect")
.attr("transform", function(d) {
return "translate(" + x0(d.data.category) + ",0)";
})
.attr("x", function(d) {
return x1(d.data.column)+x1.bandwidth()/ 2 - 20;
})
.attr("y", function(d) {
return y(d[1]);
})
.attr("height", function(d) {
return y(d[0]) - y(d[1]);
})
.attr("width", barwidth);
graph
.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x0));
graph
.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chart-area"></div>