/** * Constructor * * @param points an array of points */ public GPointsArray(GPointsArray points) { this.points = new ArrayList<GPoint>(points.getNPoints()); for (int i = 0; i < points.getNPoints(); i++) { this.points.add(new GPoint(points.get(i))); } }
/** * Constructor * * @param parent the parent Processing applet * @param type the histogram type. It can be GPlot.VERTICAL or GPlot.HORIZONTAL * @param dim the plot box dimensions in pixels * @param plotPoints the points positions in the plot reference system */ public GHistogram(PApplet parent, int type, float[] dim, GPointsArray plotPoints) { this.parent = parent; this.type = (type == GPlot.VERTICAL || type == GPlot.HORIZONTAL) ? type : GPlot.VERTICAL; this.dim = dim.clone(); this.plotPoints = new GPointsArray(plotPoints); visible = true; separations = new float[] {2}; bgColors = new int[] {this.parent.color(150, 150, 255)}; lineColors = new int[] {this.parent.color(100, 100, 255)}; lineWidths = new float[] {1}; int nPoints = plotPoints.getNPoints(); differences = new ArrayList<Float>(nPoints); leftSides = new ArrayList<Float>(nPoints); rightSides = new ArrayList<Float>(nPoints); initializeArrays(nPoints); updateArrays(); labelsOffset = 8; drawLabels = false; rotateLabels = false; fontName = "SansSerif.plain"; fontColor = this.parent.color(0); fontSize = 11; font = this.parent.createFont(fontName, fontSize); }
/** * Sets all the points in the array * * @param pts the new points. The number of points could differ from the original. */ public void set(GPointsArray pts) { if (pts.getNPoints() == points.size()) { for (int i = 0; i < points.size(); i++) { points.get(i).set(pts.get(i)); } } else if (pts.getNPoints() > points.size()) { for (int i = 0; i < points.size(); i++) { points.get(i).set(pts.get(i)); } for (int i = points.size(); i < pts.getNPoints(); i++) { points.add(new GPoint(pts.get(i))); } } else { for (int i = 0; i < pts.getNPoints(); i++) { points.get(i).set(pts.get(i)); } points.subList(pts.getNPoints(), points.size()).clear(); } }
/** Updates the differences, leftSides and rightSides arrays */ protected void updateArrays() { int nPoints = plotPoints.getNPoints(); if (nPoints == 1) { leftSides.set(0, (type == GPlot.VERTICAL) ? 0.2f * dim[0] : 0.2f * dim[1]); rightSides.set(0, leftSides.get(0)); } else if (nPoints > 1) { // Calculate the differences between consecutive points for (int i = 0; i < nPoints - 1; i++) { if (plotPoints.isValid(i) && plotPoints.isValid(i + 1)) { float separation = separations[i % separations.length]; float diff; if (type == GPlot.VERTICAL) { diff = plotPoints.getX(i + 1) - plotPoints.getX(i); } else { diff = plotPoints.getY(i + 1) - plotPoints.getY(i); } if (diff > 0) { differences.set(i, (diff - separation) / 2f); } else { differences.set(i, (diff + separation) / 2f); } } else { differences.set(i, 0f); } } // Fill the leftSides and rightSides arrays leftSides.set(0, differences.get(0)); rightSides.set(0, differences.get(0)); for (int i = 1; i < nPoints - 1; i++) { leftSides.set(i, differences.get(i - 1)); rightSides.set(i, differences.get(i)); } leftSides.set(nPoints - 1, differences.get(nPoints - 2)); rightSides.set(nPoints - 1, differences.get(nPoints - 2)); } }
/** * Removes one of the points from the histogram * * @param index the point position */ public void removePlotPoint(int index) { plotPoints.remove(index); initializeArrays(plotPoints.getNPoints()); updateArrays(); }
/** * Adds a new plot points to the histogram * * @param newPlotPoints the new points positions in the plot reference system */ public void addPlotPoints(GPointsArray newPlotPoints) { plotPoints.add(newPlotPoints); initializeArrays(plotPoints.getNPoints()); updateArrays(); }
/** * Adds a new plot point to the histogram * * @param index the position to add the point * @param newPlotPoint the new point position in the plot reference system */ public void addPlotPoint(int index, GPoint newPlotPoint) { plotPoints.add(index, newPlotPoint); initializeArrays(plotPoints.getNPoints()); updateArrays(); }
/** * Sets one of the histogram plot points * * @param index the point position * @param newPlotPoint the new point positions in the plot reference system */ public void setPlotPoint(int index, GPoint newPlotPoint) { plotPoints.set(index, newPlotPoint); updateArrays(); }
/** Draws the histogram labels */ protected void drawHistLabels() { parent.pushStyle(); parent.textMode(MODEL); parent.textFont(font); parent.textSize(fontSize); parent.fill(fontColor); parent.noStroke(); if (type == GPlot.VERTICAL) { if (rotateLabels) { parent.textAlign(RIGHT, CENTER); for (int i = 0; i < plotPoints.getNPoints(); i++) { if (plotPoints.isValid(i) && plotPoints.getX(i) >= 0 && plotPoints.getX(i) <= dim[0]) { parent.pushMatrix(); parent.translate(plotPoints.getX(i), labelsOffset); parent.rotate(-HALF_PI); parent.text(plotPoints.getLabel(i), 0, 0); parent.popMatrix(); } } } else { parent.textAlign(CENTER, TOP); for (int i = 0; i < plotPoints.getNPoints(); i++) { if (plotPoints.isValid(i) && plotPoints.getX(i) >= 0 && plotPoints.getX(i) <= dim[0]) { parent.text(plotPoints.getLabel(i), plotPoints.getX(i), labelsOffset); } } } } else { if (rotateLabels) { parent.textAlign(CENTER, BOTTOM); for (int i = 0; i < plotPoints.getNPoints(); i++) { if (plotPoints.isValid(i) && -plotPoints.getY(i) >= 0 && -plotPoints.getY(i) <= dim[1]) { parent.pushMatrix(); parent.translate(-labelsOffset, plotPoints.getY(i)); parent.rotate(-HALF_PI); parent.text(plotPoints.getLabel(i), 0, 0); parent.popMatrix(); } } } else { parent.textAlign(RIGHT, CENTER); for (int i = 0; i < plotPoints.getNPoints(); i++) { if (plotPoints.isValid(i) && -plotPoints.getY(i) >= 0 && -plotPoints.getY(i) <= dim[1]) { parent.text(plotPoints.getLabel(i), -labelsOffset, plotPoints.getY(i)); } } } } parent.popStyle(); }
/** * Draws the histogram * * @param plotBasePoint the histogram base point in the plot reference system */ public void draw(GPoint plotBasePoint) { if (visible) { // Calculate the baseline for the histogram float baseline = 0; if (plotBasePoint.isValid()) { baseline = (type == GPlot.VERTICAL) ? plotBasePoint.getY() : plotBasePoint.getX(); } // Draw the rectangles parent.pushStyle(); parent.rectMode(CORNERS); parent.strokeCap(SQUARE); for (int i = 0; i < plotPoints.getNPoints(); i++) { if (plotPoints.isValid(i)) { // Obtain the corners float x1, x2, y1, y2; if (type == GPlot.VERTICAL) { x1 = plotPoints.getX(i) - leftSides.get(i); x2 = plotPoints.getX(i) + rightSides.get(i); y1 = plotPoints.getY(i); y2 = baseline; } else { x1 = baseline; x2 = plotPoints.getX(i); y1 = plotPoints.getY(i) - leftSides.get(i); y2 = plotPoints.getY(i) + rightSides.get(i); } if (x1 < 0) { x1 = 0; } else if (x1 > dim[0]) { x1 = dim[0]; } if (-y1 < 0) { y1 = 0; } else if (-y1 > dim[1]) { y1 = -dim[1]; } if (x2 < 0) { x2 = 0; } else if (x2 > dim[0]) { x2 = dim[0]; } if (-y2 < 0) { y2 = 0; } else if (-y2 > dim[1]) { y2 = -dim[1]; } // Draw the rectangle float lw = lineWidths[i % lineWidths.length]; parent.fill(bgColors[i % bgColors.length]); parent.stroke(lineColors[i % lineColors.length]); parent.strokeWeight(lw); if (Math.abs(x2 - x1) > 2 * lw && Math.abs(y2 - y1) > 2 * lw) { parent.rect(x1, y1, x2, y2); } else if ((type == GPlot.VERTICAL && x2 != x1 && !(y1 == y2 && (y1 == 0 || y1 == -dim[1]))) || (type == GPlot.HORIZONTAL && y2 != y1 && !(x1 == x2 && (x1 == 0 || x1 == dim[0])))) { parent.rect(x1, y1, x2, y2); parent.line(x1, y1, x1, y2); parent.line(x2, y1, x2, y2); parent.line(x1, y1, x2, y1); parent.line(x1, y2, x2, y2); } } } parent.popStyle(); // Draw the labels if (drawLabels) { drawHistLabels(); } } }
/** * Adds a new set of points to the array * * @param pts the new set of points */ public void add(GPointsArray pts) { for (int i = 0; i < pts.getNPoints(); i++) { points.add(new GPoint(pts.get(i))); } }