【问题标题】:Create a stacked bar chart with different stack level创建具有不同堆栈级别的堆积条形图
【发布时间】:2018-09-18 16:00:06
【问题描述】:

此代码位于 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 位置很好,我的问题是矩形和高度的 y 位置。

这是我目前拥有的代码:

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

【问题讨论】:

  • 你能把工作代码贴出来,方便帮助

标签: d3.js vue.js stacked-chart


【解决方案1】:

找到了一种让它工作的方法:发布代码以供将来参考。

我解决这个问题的方法是迭代任务并为每个任务添加一个组,并在每个组内添加条形。

这样我就不会丢失 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'));
      });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2019-08-27
    • 2021-09-28
    • 1970-01-01
    相关资源
    最近更新 更多