Создайте столбчатую диаграмму с разным уровнем стека - PullRequest
0 голосов
/ 18 сентября 2018

этот код находится внутри фреймворка VUEJ.

Я работаю над созданием гистограммы с накоплением, но не смог использовать функцию стека D3.поэтому я попытался реализовать положение y и высоту прямоугольников другим способом.

Вот данные, которые у меня есть:

tasks: [
  {
    name:t1,
    taskTotal:1000
    taskStages: [
       { 
        stageTotal: 200 
       },
       { 
        stageTotal: 400 
       },{ 
        stageTotal: 400 
       }
    ]
    
  },
  {
    name:t2,
    taskTotal:500
    stages:[
          { 
            stageTotal: 200 
          },
          {
            stageTotal: 300
          }
    ],
  }
]

Я пытался сделать шкалы, специфичные для каждой задачи, но безуспешно.

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');
 }

Вот как это выглядит в настоящее время enter image description here

Я пытался заставить каждый этап задачи складываться на каждомдругой, я прочитал D3 Столбчатая диаграмма с разным уровнем стека

и https://bl.ocks.org/DimsumPanda/689368252f55179e12185e13c5ed1fee

1 Ответ

0 голосов
/ 20 сентября 2018

Нашел способ заставить его работать: опубликовать код для дальнейшего использования.

Чтобы решить эту проблему, нужно было перебирать задачи и для каждой задачи добавлять группу, а внутри каждой группы добавлять столбцы.

Таким образом, я не потерял кумулятивные суммы, необходимые для позиции 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'));
      });
...