我在这里有一个codepen - https://codepen.io/anon/pen/GyeEpJ?editors=0010#0
它是一个堆积的条形图,顶部有折线图
折线图点显示在下方栏的左侧。
如何定位线中的点,使它们出现在x轴上的刻度线上方。
let dataline = d3.line()
.x((d) => {
return x(d.date);
})
.y((d) =>{
return y(d.total);
});
let layersLineArea = chart.append('g')
.attr('class', 'layers-lines');
let layersLine = layersLineArea.append('path')
.data([totalData])
.attr("class", "line")
.attr('d', dataline);
答案 0 :(得分:1)
您正在使用不适用于折线图的带尺。
最简单的解决方案是在线路生成器中增加一半的带宽:
let dataline = d3.line()
.x((d) => {
return x(d.date) + x.bandwidth()/2;
})
.y((d) =>{
return y(d.total);
});
以下是您更改的代码:
let keys = [];
let maxVal = [];
let dataToStack = [];
let totalData = [];
let legendKeys = ['usedInf', 'newInf'];
let w = 800;
let h = 450;
let margin = {
top: 60,
bottom: 40,
left: 50,
right: 20,
};
let width = w - margin.left - margin.right;
let height = h - margin.top - margin.bottom;
let colors = ['#FFC400', '#FF4436', '#FFEBB6', '#FFC400', '#B4EDA0'];
let data = [{
"one": 10,
"two": 12,
"three": 18,
"four": 22,
"five": 30,
"six": 44,
"seven": 125,
"date": "2015-05-31T00:00:00"
}, {
"one": 30,
"two": 42,
"three": 38,
"four": 62,
"five": 90,
"six": 144,
"seven": 295,
"date": "2015-06-30T00:00:00"
}, {
"one": 30,
"two": 92,
"three": 18,
"four": 100,
"five": 120,
"six": 10,
"seven": 310,
"date": "2015-07-31T00:00:00"
}, ];
for (let i = 0; i < data.length; i++) {
dataToStack.push({
date: data[i]['date'].toString(),
usedInf: data[i]['one'] + data[i]['two'] + data[i]['three'],
newInf: data[i]['four'] + data[i]['five'] + data[i]['six']
});
totalData.push({
date: data[i]['date'].toString(),
total: data[i]['seven']
});
}
//------------------------- Stack ------------------------//
let stack = d3.stack()
.keys(legendKeys);
let stackedSeries = stack(dataToStack);
//------------------------- Stack ------------------------//
let x = d3.scaleBand()
.domain(dataToStack.map(function(d) {
//let date = new Date(d.date);
return d.date;
}))
.rangeRound([0, width])
.padding(0.05);
let y = d3.scaleLinear()
.domain([0, d3.max(stackedSeries, function(d) {
return d3.max(d, (d) => {
return d[1];
})
})])
.range([height, 0]);
let svg = d3.select('.chart').append('svg')
.attr('class', 'chart')
.attr('width', w)
.attr('height', h);
let chart = svg.append('g')
.classed('graph', true)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//------------------------- Bar Chart ------------------------//
let layersBarArea = chart.append('g')
.attr('class', 'layers-bars');
let layersBar = layersBarArea.selectAll('.layer-bar').data(stackedSeries)
.enter()
.append('g')
.attr('class', 'layer-bar')
.style('fill', (d, i) => {
return colors[i];
});
layersBar.selectAll('rect')
.data((d) => {
return d
})
.enter()
.append('rect')
.attr('height', (d, i) => {
return y(d[0]) - y(d[1]);
})
.attr('y', (d) => {
return y(d[1]);
})
.attr('x', (d, i) => {
return x(d.data.date)
})
.attr('width', x.bandwidth());
//------------------------- Bar Chart ------------------------//
//------------------------- Line Chart ------------------------//
let dataline = d3.line()
.x((d) => {
return x(d.date) + x.bandwidth() / 2;
})
.y((d) => {
return y(d.total);
});
let layersLineArea = chart.append('g')
.attr('class', 'layers-lines');
let layersLine = layersLineArea.append('path')
.data([totalData])
.attr("class", "line")
.attr('d', dataline);
//------------------------- Line Chart ------------------------//
chart.append('g')
.classed('x axis', true)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
chart.append('g')
.classed('y axis', true)
.call(d3.axisLeft(y)
.ticks(10));
&#13;
.line {
fill: none;
stroke: #00D7D2;
stroke-width: 5px;
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="chart"></div>
&#13;