// GraphPlotter.java // (C) 2007 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany // first published 22.05.2007 on http://yacy.net // // This is a part of YaCy, a peer-to-peer based web search engine // // $LastChangedDate$ // $LastChangedRevision$ // $LastChangedBy$ // // LICENSE // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package net.yacy.visualization; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; /* this class is a container for graph coordinates and it can draw such coordinates into a graph * all coordinates are given in a artificial coordinate system, in the range from * -1 to +1. The lower left point of the graph has the coordinate -1, -1 and the upper * right is 1,1 * 0,0 is the center of the graph */ public class GraphPlotter { // a ymageGraph is a set of points and borders between the points // to reference the points, they must all have a nickname private final Map points; private final Set borders; private double leftmost, rightmost, topmost, bottommost; public GraphPlotter() { this.points = new HashMap(); this.borders = new HashSet(); this.leftmost = 1.0; this.rightmost = -1.0; this.topmost = -1.0; this.bottommost = 1.0; } public coordinate getPoint(final String name) { return this.points.get(name); } public coordinate[] getBorder(final String name) { final int p = name.indexOf("$"); if (p < 0) return null; final coordinate from = getPoint(name.substring(0, p)); final coordinate to = getPoint(name.substring(p + 1)); if ((from == null) || (to == null)) return null; return new coordinate[] {from, to}; } public coordinate addPoint(final String name, final double x, final double y, final int layer) { final coordinate newc = new coordinate(x, y, layer); final coordinate oldc = this.points.put(name, newc); assert oldc == null; // all add shall be unique if (x > this.rightmost) this.rightmost = x; if (x < this.leftmost) this.leftmost = x; if (y > this.topmost) this.topmost = y; if (y < this.bottommost) this.bottommost = y; return newc; } public boolean hasBorder(final String fromPoint, final String toPoint) { return this.borders.contains(fromPoint + "-" + toPoint); } public void setBorder(final String fromPoint, final String toPoint) { final coordinate from = this.points.get(fromPoint); final coordinate to = this.points.get(toPoint); assert from != null; assert to != null; this.borders.add(fromPoint + "$" + toPoint); } public static class coordinate { public double x, y; public int layer; public coordinate(final double x, final double y, final int layer) { assert x >= -1; assert x <= 1; assert y >= -1; assert y <= 1; this.x = x; this.y = y; this.layer = layer; } } public void print() { // for debug purpose: print out all coordinates final Iterator> i = this.points.entrySet().iterator(); Map.Entry entry; String name; coordinate c; while (i.hasNext()) { entry = i.next(); name = entry.getKey(); c = entry.getValue(); System.out.println("point(" + c.x + ", " + c.y + ", " + c.layer + ") [" + name + "]"); } final Iterator j = this.borders.iterator(); while (j.hasNext()) { System.out.println("border(" + j.next() + ")"); } } public RasterPlotter draw( final int width, final int height, final int leftborder, final int rightborder, final int topborder, final int bottomborder, final String color_back, final String color_dot, final String color_line, final String color_lineend, final String color_text ) { final RasterPlotter.DrawMode drawMode = (RasterPlotter.darkColor(color_back)) ? RasterPlotter.DrawMode.MODE_ADD : RasterPlotter.DrawMode.MODE_SUB; final RasterPlotter image = new RasterPlotter(width, height, drawMode, color_back); final double xfactor = ((this.rightmost - this.leftmost) == 0.0) ? 0.0 : (width - leftborder - rightborder) / (this.rightmost - this.leftmost); final double yfactor = ((this.topmost - this.bottommost) == 0.0) ? 0.0 : (height - topborder - bottomborder) / (this.topmost - this.bottommost); // draw dots and names final Iterator> i = this.points.entrySet().iterator(); Map.Entry entry; String name; coordinate c; int x, y; while (i.hasNext()) { entry = i.next(); name = entry.getKey(); c = entry.getValue(); x = (xfactor == 0.0) ? width / 2 : (int) (leftborder + (c.x - this.leftmost) * xfactor); y = (yfactor == 0.0) ? height / 2 : (int) (height - bottomborder - (c.y - this.bottommost) * yfactor); image.setColor(color_dot); image.dot(x, y, 6, true, 100); image.setColor(color_text); PrintTool.print(image, x, y + 10, 0, name.toUpperCase(), 0); } // draw lines final Iterator j = this.borders.iterator(); coordinate[] border; image.setColor(color_line); int x0, x1, y0, y1; while (j.hasNext()) { border = getBorder(j.next()); if (border == null) continue; if (xfactor == 0.0) { x0 = width / 2; x1 = width / 2; } else { x0 = (int) (leftborder + (border[0].x - this.leftmost) * xfactor); x1 = (int) (leftborder + (border[1].x - this.leftmost) * xfactor); } if (yfactor == 0.0) { y0 = height / 2; y1 = height / 2; } else { y0 = (int) (height - bottomborder - (border[0].y - this.bottommost) * yfactor); y1 = (int) (height - bottomborder - (border[1].y - this.bottommost) * yfactor); } // draw the line, with the dot at the beginning of the line image.lineDot(x1, y1, x0, y0, 3, 4, color_line, color_lineend); } return image; } }