【发布时间】:2019-11-06 17:15:21
【问题描述】:
我有一个演示 here
这是一个简单的 d3 图表。
条之间没有空间。我知道我可以添加这个
const x = d3.scaleBand()
.range([0, width])
//.padding(0.1)
这会在每个条形的两侧增加空间。
如何从第一个和最后一个柱中删除空间,以便第一个和最后一个柱位于图表边缘
【问题讨论】:
标签: d3.js
我有一个演示 here
这是一个简单的 d3 图表。
条之间没有空间。我知道我可以添加这个
const x = d3.scaleBand()
.range([0, width])
//.padding(0.1)
这会在每个条形的两侧增加空间。
如何从第一个和最后一个柱中删除空间,以便第一个和最后一个柱位于图表边缘
【问题讨论】:
标签: d3.js
使用.paddingInner([0.1]); 仅设置内部填充,如文档https://github.com/d3/d3-scale#band_paddingInner 中所述
这是可行的解决方案:
var originalData = [
{
date: "Jan",
value: 1507
},
{
date: "Feb",
value: 1600
},
{
date: "Mar",
value: 1281
},
{
date: "Apr",
value: 1898
},
{
date: "May",
value: 1749
},
{
date: "June",
value: 1270
},
{
date: "July",
value: 1712
},
{
date: "Aug",
value: 1270
},
{
date: "Sept",
value: 1257
},
{
date: "Oct",
value: 1257
},
{
date: "Nov",
value: 1277
},
{
date: "Dec",
value: 1057
}
]
///////////////////////////// Update function
const randomizeData = (data) => {
const rand = Math.floor(Math.random() * data.length) + 2
const newData = data.slice(0, rand)
update(newData)
}
///////////////////////////// Create SVG
const w = 400
const h = 250
const margin = {
top: 20,
bottom: 40,
left: 40,
right: 20
}
const width = w - margin.left - margin.right
const height = h - margin.top - margin.bottom
const svg = d3.select(".chart-container").append("svg")
.attr("id", "svg")
.attr("width", w)
.attr("height", h)
const chart = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
const x = d3.scaleBand()
.range([0, width])
.paddingInner([0.1]);
const y = d3.scaleLinear()
.rangeRound([height, 0])
const xAxis = chart.append("g").attr("class", "axis axis-x")
const yAxis = chart.append("g").attr("class", "axis axis-y")
///////////////////////////////// Update function
//Recalc Domains
//Redraw Axis
//Enter
//Update
//Exit
const update = (graphData) => {
// Recalc domains based on new data
// x is scaleBand
x.domain(graphData.map( (d) => d.date) );
y.domain([0, d3.max( graphData, (d) => d.value) ]);
const u = chart.selectAll(".bar")
.data(graphData)
// Enter
u.enter()
.append("rect")
.classed('bar', true)
.attr('x', (d) => x(d.date) )
.attr("y", (d) => y(d.value) )
.attr("width", x.bandwidth() )
.attr("height", (d) => height - y(d.value) )
// Update
u.attr('x', (d) => x(d.date) )
.attr("width", x.bandwidth() )
.attr("y", (d) => y(d.value) )
.attr("height", (d) => height - y(d.value) )
// Exit
u.exit()
.remove()
// Redraw axes based on new data
xAxis.call(d3.axisBottom(x))
.attr("transform", "translate(0," + height + ")");
yAxis.call(d3.axisLeft(y))
}
randomizeData(originalData);
var button = document.getElementById('btn');
button.addEventListener('click', () => randomizeData(originalData) );
h1, h2 {
font-family: Lato;
}
#svg{
background-color: lightgrey;
}
.bar{
shape-rendering: crispEdges;
fill: mediumvioletred;
}
.bar-label{
fill: white;
}
.bar-label{
text-anchor: end;
}
.grid line{
stroke: #bbb;
}
.grid .tick:nth-child(4) line{
stroke-width: 3;
stroke: #999;
}
.divide{
fill: lightgrey;
}
.update-btn{
display: block;
margin-top: 30px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="chart-container"></div>
<button class="update-btn" id="btn">Update</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
</body>
</html>
【讨论】: