使用javascript(p5js)的二维数组

时间:2018-04-13 13:16:32

标签: javascript html arrays multidimensional-array p5.js

我有以下数组想要显示为带有p5js(javascript)的堆积条形图。

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

4|     ▭

3|     ▭   ▭

2| ▭  ▭    ▭

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

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

/* 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;
  }
}

1 个答案:

答案 0 :(得分:1)

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

对于数据,您只需循环xData这是2D数组,并使用来自xy的{​​{1}}和xTicks位置的当前索引。你还需要稍微调整一下(+ - 5),这是10的一半,对于刻度文本也是如此。

请注意,yTicks rects的位置是基于其在月份数组中的索引,而不是基于其文本的索引,例如,如果您有y,它仍将位于前两个y位置,相反,您可以取最后一个文本字符Fiddle

var month1 = ["M01V03", "M01V04"]
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)
      })
    })
  }

}