/** * Plots a scatter graph of several graphs. Stacks the graphs on top of each other * * @param graphs The graphs to plot */ public void plotStackedScatterGraph(final List<Graph> graphs) { // Make all graphs equal sized by adding zeros int maxSize = 0; for (Graph g : graphs) { maxSize = maxSize < g.getPoints().size() ? g.getPoints().size() : maxSize; } for (Graph g : graphs) { while (g.getPoints().size() < maxSize) { g.addPoint(new Point(0, 0, g, 0, 0)); } } final int max = maxSize; RepeatingCommand rc = new RepeatingCommand() { private int counter; private List<Float> lastCoords = null; @Override public boolean execute() { if (counter == 0 && listener != null) { listener.plottingStarts(); } canvas.setGlobalCompositeOperation(Canvas.DESTINATION_OVER); Graph g = graphs.get(counter); counter++; if (g.isLineCaps()) { canvas.setLineJoin(Canvas.BEVEL); } canvas.setStrokeStyle(g.getColor()); canvas.setFillStyle(g.getFillColor()); canvas.beginPath(); canvas.moveTo(-1, zero); float lastX = -1; List<Float> theseCoords = new LinkedList<Float>(); for (int i = 0; i < max; i++) { Point p = g.getPoints().get(i); if (lastCoords == null) { canvas.moveTo(p.x, p.y); canvas.strokeRect(p.x, p.y, 2, 2); canvas.moveTo(p.x, p.y); theseCoords.add((float) p.y); } else { float diff = lastCoords.get(i) - zero; canvas.moveTo(p.x, p.y + diff); canvas.strokeRect(p.x, p.y + diff, 2, 2); canvas.moveTo(p.x, p.y + diff); theseCoords.add(p.y + diff); } lastX = p.x; } canvas.moveTo(lastX, zero); canvas.closePath(); canvas.stroke(); canvas.fill(); lastCoords = theseCoords; canvas.setGlobalCompositeOperation(Canvas.SOURCE_OVER); if (counter == graphs.size() && listener != null) { listener.plottingEnds(); } return counter < graphs.size(); } }; iRender(rc, graphs.size()); }
/** * Plots a bar graph with overlapping graphs. Orders bars so the bar with the least value is * topmost. * * @param graphs */ public void plotBarGraph(List<Graph> graphs) { final long start = new Date().getTime(); // Make all graphs equal sized by adding zeros int maxSize = 0; for (Graph g : graphs) { maxSize = maxSize < g.getPoints().size() ? g.getPoints().size() : maxSize; } // Render graphs (Iterates through every point) final int max = maxSize; for (int i = 0; i < maxSize; i++) { // Create rendering order map final List<Point> points = new LinkedList<VCanvasPlotter.Point>(); for (Graph g : graphs) { if (g.getPoints().size() > i) { points.add(g.getPoints().get(i)); } } // Order points so they always are visible Collections.sort( points, new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { Float val1 = zero - o1.y; Float val2 = zero - o2.y; if (val1 >= zero && val2 >= 0) { // Both are positive return val1.compareTo(val2); } else if (val1 <= zero && val2 <= zero) { // Both are negative return val2.compareTo(val1); } else { // One is negative, one is positive return val1.compareTo(val2); } } }); final int index = i; RepeatingCommand rc = new RepeatingCommand() { private int counter = 0; private float x = points.get(0).x; @Override public boolean execute() { if (counter == 0 && index == 0 && listener != null) { listener.plottingStarts(); } Point p = points.get(counter); counter++; if (useShadows) { enableShadows(0, PlotMode.BAR); } canvas.setStrokeStyle("rgba(0,0,0,0)"); Graph g = p.g; canvas.setFillStyle(g.getColor()); float height = p.y - zero; float width = p.width; float y = zero; if (p.x >= x && p.x < x + p.width) { /* * If the bar x-coordinate is between the first bar * x-coordinate and its width the stack them on top of * eachother */ if (p.width > 2) { // Ensure space between the next bar and this one canvas.fillRect(x - width, y, width - 2, height); } else if (p.width > 0) { canvas.fillRect(x - width, y, width, height); } } else { /* * Else stack them beside each other */ if (p.width > 2) { // Ensure space between the next bar and this one canvas.fillRect(p.x - width, y, width - 2, height); } else if (p.width > 0) { canvas.fillRect(p.x - width, y, width, height); } } if (counter == points.size() && index == max - 1 && listener != null) { long end = new Date().getTime(); VConsole.log( "VCanvasPlotter: Plotting " + index + " bar graphs took " + (end - start) + "ms"); if (useShadows) { disableShadows(); } listener.plottingEnds(); } return counter < points.size(); } }; iRender(rc, graphs.size()); } }
/** * Plots a graph with stacked graphs * * @param graphs */ public void plotStackedBarGraph(List<Graph> graphs) { // Make all graphs equal sized by adding zeros int maxSize = 0; for (Graph g : graphs) { maxSize = maxSize < g.getPoints().size() ? g.getPoints().size() : maxSize; } // Render graphs (Iterates through every point) final int max = maxSize; for (int i = 0; i < maxSize; i++) { // Create rendering order map final List<Point> points = new LinkedList<VCanvasPlotter.Point>(); for (Graph g : graphs) { if (g.getPoints().size() > i) { points.add(g.getPoints().get(i)); } } final int index = i; RepeatingCommand rc = new RepeatingCommand() { private int counter; private float x = points.get(0).x; float localZero = zero; @Override public boolean execute() { if (counter == 0 && index == 0 && listener != null) { listener.plottingStarts(); } canvas.setStrokeStyle("rgba(0,0,0,0)"); Point p = points.get(counter); counter++; if (useShadows) { enableShadows(0, PlotMode.BAR); } Graph g = p.g; canvas.setFillStyle(g.getColor()); float height = p.y - zero; float width = p.width; // float x = p.x; float y = localZero; if (p.x >= x && p.x < x + p.width) { /* * If the bar x-coordinate is between the first bar * x-coordinate and its width the stack them on top of * eachother */ if (p.width > 2) { // Ensure space between the next bar and this one canvas.fillRect(x, y, width - 2, height); } else if (p.width > 0) { canvas.fillRect(x, y, width, height); } localZero += height; } else { /* * Else stack them beside each other */ if (p.width > 2) { // Ensure space between the next bar and this one canvas.fillRect(p.x, y, width - 2, height); } else if (p.width > 0) { canvas.fillRect(p.x, y, width, height); } } if (counter == points.size() && index == max - 1 && listener != null) { if (useShadows) { disableShadows(); } listener.plottingEnds(); } return counter < points.size(); } }; iRender(rc, graphs.size()); } }
/** * Plots a line graph where the lines position depends on each other. * * @param graphs The list of graphs to plot. First graph is plotted bottom most and sequential * graphs on top of the previous one. */ public void plotStackedLineGraph(final List<Graph> graphs) { // Make all graphs equal sized by adding zeros int maxSize = 0; for (Graph g : graphs) { maxSize = maxSize < g.getPoints().size() ? g.getPoints().size() : maxSize; } final int max = maxSize; RepeatingCommand rc = new Scheduler.RepeatingCommand() { private int counter = 0; private List<Float> lastCoords = null; @Override public boolean execute() { Graph g = graphs.get(counter); if (counter == 0 && listener != null) { listener.plottingStarts(); canvas.setGlobalCompositeOperation(Canvas.DESTINATION_OVER); if (useShadows) { enableShadows(g.getLineThickness(), PlotMode.LINE); } rendering = true; } counter++; if (g.getPoints().size() > 0) { float lastX = -1; List<Float> yCoords = new LinkedList<Float>(); List<Float> xCoords = new LinkedList<Float>(); for (int i = 0; i < max; i++) { if (g.getPoints().size() > i) { Point p = g.getPoints().get(i); if (lastCoords == null) { canvas.lineTo(p.x, p.y); yCoords.add((float) p.y); } else { float diff = lastCoords.get(i) - zero; canvas.lineTo(p.x, p.y + diff); yCoords.add(p.y + diff); } lastX = p.x; xCoords.add(lastX); } } color = g.getColor(); fillColor = g.getFillColor(); if (g.getPoints().size() == 1) { plotScatterGraph(xCoords, yCoords); } else { plotLineGraph(xCoords, yCoords, g.isLineCaps(), g.getLineThickness()); } lastCoords = yCoords; } if (counter == graphs.size() && listener != null) { canvas.setGlobalCompositeOperation(Canvas.SOURCE_OVER); if (useShadows) { disableShadows(); } listener.plottingEnds(); } return counter < graphs.size(); } }; iRender(rc, graphs.size()); }