javascript 的二维数组 (p5js)

2Dimensional Arrays with javascript (p5js)

我有以下数组,想用 p5js (javascript) 显示为堆叠条形图。

您可以在下面看到一个 arrayOfMonths (month1, month2,...),它将显示在堆叠条形图的 X 轴上。现在,每个月都有许多其他(0 到很多)元素。这些是我想在 Y 轴上显示的元素,例如 month1 有 2 个元素,我想在 X 轴上的第一个元素上创建两个矩形,依此类推,如下所示:

4|     ▭

3|     ▭   ▭

2| ▭  ▭    ▭

1| ▭  ▭ ▭ ▭
▬▬▬▬▬▬▬▬▬▬▬▬▬▬
   m1 m2 m3 m4

如果您知道如何处理二维数组,请告诉我 :) 谢谢...

/* Needed Variables Declaration */
var month1 = ["M01V01","M01V02"];
var month2 = ["M02V01","M02V02","M02V03","M02V04"];
var month3 = ["M03V01"];
var month4 = ["M04V01","M04V02","M04V03"];
var arrayOfMonths = [month1,month2,month3,month4];
var arrayOfResponses = ["1", "2", "3","4","5"];

function addValues(){

 var locX = canvasWidth-(canvasWidth-125);
  var locY = canvasHeight-25;
  var barWidth = 50; 
  var barData = canvasHeight/(numOfResponses+2);
  
  for(var x=0; x<arrayOfMonths.length; x++){
    /* Draw Stack Bars (rectangles) */
    for(var y=0; y<arrayOfMonths[x].length; y++){
      
      
      /* ADD TEXT TO X AXIS */
      if(y<=x){
        
       locX = canvasWidth-(canvasWidth-125);
        locY -= 125;
        text(arrayOfMonths[x][y], locX, locY);
        
        fill(random(255),random(255),random(255));
      rect(locX, locY, barWidth, barData);
      }
      // locX+=canvasWidth/(numOfMonths+1);
      
    locX+=100;    
   
      //locY -= 150; 
    }
    //locX = canvasWidth-(canvasWidth-125);  
    //locY = canvasHeight-210;
  }
}

根据您的数据,这是您可以做到的一种方法。您可以将 x 和 y 轴上的元素数量 map 设置为图表的大小或这些轴的大小,因此每个索引在轴的 0 - data.lengthstart - end 之间缩放。您还可以使用 xTicks 的第一个元素作为它们之间的 space 大小,然后您只需根据该数据绘制轴。

对于数据,您只需循环 xData,这是一个二维数组,并将当前索引用于 xTicksyTicksxy 位置。您还需要稍微调整 rects (+ - 5),即 10 的一半,ticks 文本也是如此。

请注意,y rects 的位置是基于其在月份数组中的索引而不是其文本,因此例如,如果您有 var month1 = ["M01V03", "M01V04"],它仍将位于前两个 y 位置,而不是您可以获取文本的最后一个字符 Fiddle

var month1 = ["M01V01", "M01V02"];
var month2 = ["M02V01", "M02V02", "M02V03", "M02V04"];
var month3 = ["M03V01"];
var month4 = ["M04V01", "M04V02", "M04V03"];
var months = [month1, month2, month3, month4];
var responses = ["1", "2", "3", "4", "5"];

let graph;

function setup() {
  createCanvas(400, 250);
  graph = new Graph(months, responses, 200, 300);
}

function draw() {
  background(50, 50, 150);
  graph.show();
  graph.showData();
}

class Graph {
  constructor(xData, yData, height, width) {
    this.xData = xData;
    this.yData = yData;
    this.height = height;
    this.width = width;
    this.xStart = 60;
    this.yStart = window.height - 30;

    this.xTicks = this.xData.map((e, i) => {
      return map(i, 0, this.xData.length, this.xStart, this.width);
    })

    this.yTicks = this.yData.map((e, i) => {
      return map(i, 0, this.yData.length, this.yStart - this.height, this.yStart);
    })

    this.xSpace = this.xTicks[0];
  }

  show() {
    this.xAxis();
    this.yAxis();
  }

  xAxis() {
    stroke(255);
    strokeWeight(1);
    line(this.xStart, this.yStart, this.xStart + this.width, this.yStart);
    strokeWeight(2)
    this.xTicks.forEach((x, i) => {
      stroke(255)
      line(x + this.xSpace, this.yStart + 2, x + this.xSpace, this.yStart - 2)
      noStroke()
      fill(255);
      text(`m${i + 1}`, x + this.xSpace - 7, this.yStart + 14)
    })
  }

  yAxis() {
    stroke(255);
    strokeWeight(1);
    line(this.xStart, this.yStart, this.xStart, this.yStart - this.height);
    strokeWeight(2)
    this.yTicks.forEach((y, i) => {
      stroke(255)
      line(this.xStart - 2, this.yStart - y, this.xStart + 2, this.yStart - y);
      noStroke()
      fill(255);
      textSize(10)
      text(this.yData[i], this.xStart - 15, this.yStart - y + 3)
    })
  }

  showData() {
    this.xData.forEach((arr, i) => {
      arr.forEach((item, j) => {
        noFill();
        stroke(255);
        rect(this.xTicks[i] + this.xSpace - 5, this.yStart - this.yTicks[j] - 5, 10, 10)
      })
    })
  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>