此代码在VUEJ的框架内。
我正在创建一个堆积的条形图,但无法使用D3堆积功能。 所以我尝试以其他方式实现矩形的y位置和高度。
这是我拥有的数据:
tasks: [
{
name:t1,
taskTotal:1000
taskStages: [
{
stageTotal: 200
},
{
stageTotal: 400
},{
stageTotal: 400
}
]
},
{
name:t2,
taskTotal:500
stages:[
{
stageTotal: 200
},
{
stageTotal: 300
}
],
}
]
我曾尝试为每个任务量身定做秤,但没有成功。
每个Bar的x pos都很好,我的问题是矩形和高度的y pos。
这是我目前拥有的代码:
getScaleForTask(task){
return d3.scaleLinear()
.range([0,this.svgHeight - 20])
.domain([0,task.taskTotal])
},
TaskCumulativeTotal(taskStages){
const arrOFCumulativeSums = [0]
taskStages.reduce((sumOfStages,currStage) => {
arrOFCumulativeSums.push(currStage.stageTotal + sumOfStages)
return currStage.stageTotal + sumOfStages;
},0);
return arrOFCumulativeSums
},
chartBuilder(){
let currCumulativeSum;
let yScaleForTask;
const taskG = svg
.selectAll('g')
.data(this.tasks)
.enter()
.append('g')
.attr(
'transform',
(d, i) => `translate(${cunmulativeGroupXPos[i]},0)`,
);
// from here i'm stuck
const stageG = taskG
.selectAll('g')
.data(d =>{
yScaleForTask = this.getScaleForTask(d);
currCumulativeSum = this.TaskCumulativeTotal(d.taskStages);
return d.taskStages;
})
.enter()
.append('g')
.attr('transform', d => xScale(d.taskName)); // this determins the x pos
stageG
.append('rect')
.attr('width', 30)
.attr('y', (d,i) => yScaleForTask(currCumulativeSum[i]))
.attr('height', d => yScaleForTask(d.stageTotal))
.attr('fill', (d, i) => (i % 2 === 0 ? '#66ccff' : '#99ff66'))
.attr('stroke', 'grey');
}
我一直在努力使每个任务阶段相互叠加, 我确实读过D3 Stacked bar chart with different stack level
和 https://bl.ocks.org/DimsumPanda/689368252f55179e12185e13c5ed1fee
答案 0 :(得分:0)
找到一种使其工作的方法:发布代码以供将来参考。
我解决此问题的方法是遍历任务,并为每个任务添加一个组,并在每个组内部添加条形图。
这样,我就不会失去y位置所需的累计和。
chartBuilder() {
const longestTask = this.getLongestTask();
const taskNames = this.tasks.map(t => t.taskName);
const xScale = d3.scaleBand()
.domain(taskNames)
.rangeRound([0, this.svgWidth]);
const svg = d3.select('#stacked-svg-tasks');
const yScaleForTask = this.getScaleForTask(this.svgHeight - 20, longestTask);
const barWidthScale = Math.round(this.svgWidth / this.tasks.length) - this.GbGS;
// adding data to show as bar chart
this.tasks.forEach((task, taskIndex) => {
const currCumulativeSum = this.CumulativeTimeOfStages(task.taskStages);
const data = [task];
const currTask = svg
.selectAll(`bar${taskIndex}`)
.data(data)
.enter()
.append('g')
.attr('class', `bar${taskIndex}`)
.attr(
'transform',
`translate(${xScale(task.taskName)},0)`,
)
.selectAll('rect')
.data(d => d.taskStages)
.enter()
.append('rect')
.attr('y', (d, i) => this.svgHeight - yScaleForTask(currCumulativeSum[i]))
.attr('width', barWidthScale)
.attr('height', d => yScaleForTask(d.totalTime))
.attr('fill', (d, i) => (i % 2 === 0 ? '#66ccff' : '#99ff66'));
});