我有一个基于D3
的分组条形图。有没有一种方法可以减少每个组中各个条之间的间距,而不是各组之间的间距。每个栏都有固定的宽度。
摘要如下:
//DATA
var data = [
{
category: "test4",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test4",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
category: "test3",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test3",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
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"
}
];
var groupData = d3
.nest()
.key(function(d) {
return d.column + d.category;
})
.rollup(function(v) {
return {
...v[0],
total: v[0].type1 + v[0].type2 + v[0].type3
};
})
.entries(data)
.map(function(d) {
return { ...d.value };
});
//INITIAL SETUP
var margin = { top: 30, right: 10, bottom: 50, left: 40 };
var width = groupData.length * 80 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var barwidth = 40;
var tip = d3
.tip()
.attr("class", "d3-tip")
.html(function(d) {
return "<span>Test</span>";
});
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 + ")");
graph.call(tip);
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();
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)(groupData);
y.domain([
0,
d3.max(groupData, function(d) {
return d.total;
})
]);
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)
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
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"));
#chart-area {
width: 600px;
overflow-x: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js"></script>
<div id="chart-area"></div>
答案 0 :(得分:1)
在innerScale中更改paddingOuter
。例如:
x1.paddingOuter(0.5);
这是具有此更改的代码。
//DATA
var data = [
{
category: "test4",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test4",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
category: "test3",
type1: 100,
type2: 200,
type3: 0,
column: "column1"
},
{
category: "test3",
type1: 0,
type2: 0,
type3: 500,
column: "column2"
},
{
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"
}
];
var groupData = d3
.nest()
.key(function(d) {
return d.column + d.category;
})
.rollup(function(v) {
return {
...v[0],
total: v[0].type1 + v[0].type2 + v[0].type3
};
})
.entries(data)
.map(function(d) {
return { ...d.value };
});
//INITIAL SETUP
var margin = { top: 30, right: 10, bottom: 50, left: 40 };
var width = groupData.length * 80 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var barwidth = 40;
var tip = d3
.tip()
.attr("class", "d3-tip")
.html(function(d) {
return "<span>Test</span>";
});
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 + ")");
graph.call(tip);
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();
x0.domain(
data.map(function(d) {
return d.category;
})
);
x1
.domain(
data.map(function(d) {
return d.column;
})
)
.range([0, x0.bandwidth()])
.paddingOuter(0.5);
z.domain(Object.keys(data[0]).filter(x => x !== "category" && x !== "column"));
var keys = z.domain(); //["type1", "type2", "type3"];
var stackData = stack.keys(keys)(groupData);
y.domain([
0,
d3.max(groupData, function(d) {
return d.total;
})
]);
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)
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
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"));
#chart-area {
width: 600px;
overflow-x: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.min.js"></script>
<div id="chart-area"></div>
如您所见,这将同时减小分组的条之间的距离并增加组之间的距离(因为显然,我没有更改外部刻度的范围)。另外,与您的问题无关:您正在覆盖内部比例尺中的填充。