Coverage Report - org.jfree.chart.plot.HCPlotState
 
Classes in this File Line Coverage Branch Coverage Complexity
HCPlotState
97%
74/76
100%
24/24
4.667
 
 1  
 /* =======================================================================
 2  
  * A visualisation library extension for JFreeChart. Please see JFreeChart
 3  
  * for further information.
 4  
  * =======================================================================
 5  
  * Copyright (C) 2006  University of Helsinki, Department of Computer Science
 6  
  *
 7  
  * This library is free software; you can redistribute it and/or
 8  
  * modify it under the terms of the GNU Lesser General Public
 9  
  * License as published by the Free Software Foundation; either
 10  
  * version 2.1 of the License, or (at your option) any later version.
 11  
  *
 12  
  * This library is distributed in the hope that it will be useful,
 13  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  
  * Lesser General Public License for more details.
 16  
  *
 17  
  * You should have received a copy of the GNU Lesser General Public
 18  
  * License along with this library; if not, write to the Free Software
 19  
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 20  
  * -----------------------------
 21  
  * Contact:  ohtu@cs.helsinki.fi
 22  
  * -----------------------------
 23  
  *
 24  
  */
 25  
 
 26  
 package org.jfree.chart.plot;
 27  
 
 28  
 import java.awt.geom.Rectangle2D;
 29  
 import java.awt.Point;
 30  
 import java.awt.Rectangle;
 31  
 
 32  
 import org.jfree.chart.entity.HCTreeNodeEntity;
 33  
 import org.jfree.data.hc.HCTreeNode;
 34  
 import org.jfree.chart.renderer.RendererState;
 35  
 
 36  
 import org.jfree.ui.RectangleEdge;
 37  
 
 38  
 /**
 39  
  * A state object used with a {@link HCPlot}.
 40  
  *
 41  
  * The class also implements some convenience methods for calculating
 42  
  * useful things based on plot state.
 43  
  *
 44  
  * @author  viski project
 45  
  */
 46  
 public class HCPlotState extends RendererState {
 47  
 
 48  
     private int blockMinX;
 49  
     private int blockMinY;
 50  
     private int sizeOfNodeSymbol;
 51  
 
 52  
     private double blockWidth;
 53  
     private double blockHeight;
 54  
     private double columnTreeHeightUnitInPixels;
 55  
     private double rowTreeHeightUnitInPixels;
 56  
 
 57  
 
 58  
     /** 
 59  
      * Creates a new state object.
 60  
      *
 61  
      * @param info  xxx
 62  
      * @param blockMinX  xxx
 63  
      * @param blockMinY  xxx
 64  
      * @param sizeOfNodeSymbol  xxx
 65  
      * @param blockWidth  xxx
 66  
      * @param blockHeight  xxx
 67  
      * @param columnTreeHeightUnitInPixels  xxx
 68  
      * @param rowTreeHeightUnitInPixels  xxx
 69  
      */
 70  
     public HCPlotState(
 71  
             PlotRenderingInfo info,
 72  
             int blockMinX,
 73  
             int blockMinY,
 74  
             int sizeOfNodeSymbol,
 75  
 
 76  
             double blockWidth,
 77  
             double blockHeight,
 78  
             double columnTreeHeightUnitInPixels,
 79  
             double rowTreeHeightUnitInPixels ) {
 80  
 
 81  15
         super(info);
 82  
 
 83  15
         this.blockMinX = blockMinX;
 84  15
         this.blockMinY = blockMinY;
 85  15
         this.sizeOfNodeSymbol = sizeOfNodeSymbol;
 86  15
         this.blockWidth = blockWidth;
 87  15
         this.blockHeight = blockHeight;
 88  15
         this.columnTreeHeightUnitInPixels = columnTreeHeightUnitInPixels;
 89  15
         this.rowTreeHeightUnitInPixels = rowTreeHeightUnitInPixels;
 90  
 
 91  15
     }
 92  
     
 93  
     /**
 94  
      * Returns the size of a visual symbol of a clustering tree node.
 95  
      *
 96  
      * @return  the width and height of a node symbol in pixels.
 97  
      */
 98  
     public int getSizeOfNodeSymbol() {
 99  
 
 100  337
         return this.sizeOfNodeSymbol;
 101  
 
 102  
     }
 103  
 
 104  
     /**
 105  
      * Returns  the width of a heatmap block.
 106  
      *
 107  
      * @return the width of a heatmap block in pixels. The return
 108  
      * value is a double.
 109  
      */
 110  
     public double getBlockWidth() {
 111  
 
 112  42
         return this.blockWidth;
 113  
 
 114  
     }
 115  
 
 116  
     /**
 117  
      * Returns the height of a heatmap block.
 118  
      *
 119  
      * @return  the height of a heatmap block in pixels. The return
 120  
      * value is a double.
 121  
      */
 122  
     public double getBlockHeight() {
 123  
 
 124  38
         return this.blockHeight;
 125  
 
 126  
     }
 127  
 
 128  
     /**
 129  
      * Returns the number of pixels one column clustering tree height unit
 130  
      * translates to.
 131  
      *
 132  
      * @return  the size in pixels of a height unit.
 133  
      */
 134  
     public double getColumnTreeHeightUnitInPixels() {
 135  
 
 136  33
         return this.columnTreeHeightUnitInPixels;
 137  
 
 138  
     }
 139  
 
 140  
     /**
 141  
      * Returns the number of pixels one row clustering tree height unit
 142  
      * translates to.
 143  
      *
 144  
      * @return  the size in pixels of a height unit.
 145  
      */
 146  
     public double getRowTreeHeightUnitInPixels() {
 147  
 
 148  25
         return this.rowTreeHeightUnitInPixels;
 149  
 
 150  
     }
 151  
 
 152  
     /**
 153  
      * Returns the X-coordinate of the specified heatmap column.
 154  
      *
 155  
      * @param column  the heatmap column
 156  
      * @return  X-coordinate of the left edge of the column in pixels.
 157  
      */
 158  
     public int getHeatMapXCoordinate(int column) {
 159  
 
 160  272
         return (int)(column * this.blockWidth + this.blockMinX);
 161  
 
 162  
     }
 163  
 
 164  
     /**
 165  
      * Returns the Y-coordinate of the specified heatmap row.
 166  
      *
 167  
      * @param row  the heatmap row
 168  
      * @return  T-coordinate of the top edge of the row in pixels.
 169  
      */
 170  
     public int getHeatMapYCoordinate(int row) {
 171  
 
 172  266
         return (int)(row * this.blockHeight + this.blockMinY);
 173  
 
 174  
     }
 175  
 
 176  
     /**
 177  
      * Returns the area usable for drawing a subtree of a clustering tree.
 178  
      *
 179  
      * @param totalArea  the area reserved for the whole tree.
 180  
      * @param usedArea  the area already used for other parts of the tree.
 181  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 182  
      *
 183  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 184  
      *
 185  
      * @return  the area as a Rectangle object.
 186  
      */
 187  
     public Rectangle calculateSubTreeArea(
 188  
             Rectangle2D totalArea,
 189  
             Rectangle2D usedArea,
 190  
             RectangleEdge edge) {
 191  
 
 192  33
         if (edge == RectangleEdge.TOP) {
 193  
 
 194  17
             return new Rectangle (
 195  
                 (int)(totalArea.getMinX()+usedArea.getWidth()),
 196  
                 (int)totalArea.getMinY(),
 197  
                 (int)(totalArea.getWidth()-usedArea.getWidth()),
 198  
                 (int)totalArea.getHeight()
 199  
             );
 200  
 
 201  16
         } else if (edge == RectangleEdge.BOTTOM) {
 202  
 
 203  1
             return new Rectangle (
 204  
                 (int)(totalArea.getMinX()+usedArea.getWidth()),
 205  
                 (int)totalArea.getMinY(),
 206  
                 (int)(totalArea.getWidth()-usedArea.getWidth()),
 207  
                 (int)totalArea.getHeight()
 208  
             );
 209  
 
 210  
         }
 211  15
         else if (edge == RectangleEdge.LEFT) {
 212  
 
 213  13
             return new Rectangle (
 214  
                 (int)totalArea.getMinX(),
 215  
                 (int)(totalArea.getMinY()+usedArea.getHeight()),
 216  
                 (int)totalArea.getWidth(),
 217  
                 (int)(totalArea.getHeight()-usedArea.getHeight())
 218  
             );
 219  
 
 220  
         }
 221  2
         else if (edge == RectangleEdge.RIGHT) {
 222  
 
 223  1
             return new Rectangle (
 224  
                 (int)totalArea.getMinX(),
 225  
                 (int)(totalArea.getMaxY()+usedArea.getHeight()),
 226  
                 (int)totalArea.getWidth(),
 227  
                 (int)(totalArea.getHeight()-usedArea.getHeight())
 228  
             );
 229  
 
 230  
         }
 231  1
         else throw new IllegalArgumentException("Invalid edge.");
 232  
 
 233  
     }
 234  
 
 235  
     /**
 236  
      * Returns the center point of a branch node of a clustering tree.
 237  
      *
 238  
      * @param height  height of this node.
 239  
      * @param leftEntity  entity describing the node representing the
 240  
      * left child.
 241  
      * @param rightEntity  entity describing the node representing the
 242  
      * right child.
 243  
      * @param area  area where the tree is being drawn.
 244  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 245  
      *
 246  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 247  
      *
 248  
      * @return  the center of a branch node.
 249  
      */
 250  
     public Point calculateBranchNodeCenter(
 251  
             double height,
 252  
             HCTreeNodeEntity leftEntity,
 253  
             HCTreeNodeEntity rightEntity,
 254  
             Rectangle2D area,
 255  
             RectangleEdge edge) {
 256  
 
 257  33
         if (edge == RectangleEdge.TOP) {
 258  
 
 259  17
             return new Point (
 260  
                 (int)((leftEntity.getCenter().getX()+rightEntity.getCenter().getX())/2),
 261  
                 (int)(area.getMaxY()-height*this.columnTreeHeightUnitInPixels)
 262  
             );
 263  
 
 264  16
         } else if (edge == RectangleEdge.BOTTOM) {
 265  
 
 266  1
             return new Point (
 267  
                 (int)((leftEntity.getCenter().getX()+rightEntity.getCenter().getX())/2),
 268  
                 (int)(area.getMinY()+height*this.columnTreeHeightUnitInPixels)
 269  
             );
 270  
 
 271  
         }
 272  15
         else if (edge == RectangleEdge.LEFT) {
 273  
 
 274  13
             return new Point (
 275  
                 (int)(area.getMaxX()-height*this.rowTreeHeightUnitInPixels),
 276  
                 (int)((leftEntity.getCenter().getY()+rightEntity.getCenter().getY())/2)
 277  
             );
 278  
 
 279  
         }
 280  2
         else if (edge == RectangleEdge.RIGHT) {
 281  
 
 282  1
             return new Point (
 283  
                 (int)(area.getMinX()+height*this.rowTreeHeightUnitInPixels),
 284  
                 (int)((leftEntity.getCenter().getY()+rightEntity.getCenter().getY())/2)
 285  
             );
 286  
 
 287  
         }
 288  1
         else throw new IllegalArgumentException("Invalid edge.");
 289  
     }
 290  
 
 291  
     /**
 292  
      * Returns the area reserved by a branch node and the corresponding
 293  
      * subtree of a clustering tree.
 294  
      *
 295  
      * @param height  height of this node.
 296  
      * @param leftEntity  entity describing the node representing the
 297  
      * left child.
 298  
      * @param rightEntity  entity describing the node representing the
 299  
      * right child.
 300  
      * @param area  area where the tree is being drawn.
 301  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 302  
      *
 303  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 304  
      *
 305  
      * @return  the area as a Rectangle object.
 306  
      */
 307  
     public Rectangle calculateBranchNodeArea(
 308  
             double height,
 309  
             HCTreeNodeEntity leftEntity,
 310  
             HCTreeNodeEntity rightEntity,
 311  
             Rectangle2D area,
 312  
             RectangleEdge edge) {
 313  
 
 314  33
         if (edge == RectangleEdge.TOP) {
 315  
 
 316  17
             return new Rectangle (
 317  
                 (int)(leftEntity.getCenter().getX()),
 318  
                 (int)(area.getMaxY()
 319  
                       - height*this.columnTreeHeightUnitInPixels),
 320  
                 (int)(rightEntity.getCenter().getX()
 321  
                       - leftEntity.getCenter().getX()),
 322  
                 (int)(height*this.columnTreeHeightUnitInPixels)
 323  
             );
 324  
 
 325  16
         } else if (edge == RectangleEdge.BOTTOM) {
 326  
 
 327  1
             return new Rectangle (
 328  
                 (int)(leftEntity.getCenter().getX()),
 329  
                 (int)(area.getMinY()),
 330  
                 (int)(rightEntity.getCenter().getX()
 331  
                       - leftEntity.getCenter().getX()),
 332  
                 (int)(height*this.columnTreeHeightUnitInPixels)
 333  
             );
 334  
 
 335  15
         } else if (edge == RectangleEdge.LEFT) {
 336  
 
 337  13
             return new Rectangle (
 338  
                 (int)(area.getMaxX()
 339  
                       - height*this.rowTreeHeightUnitInPixels),
 340  
                 (int)(leftEntity.getCenter().getY()),
 341  
                 (int)(height*this.rowTreeHeightUnitInPixels),
 342  
                 (int)(rightEntity.getCenter().getY()
 343  
                       - leftEntity.getCenter().getY())
 344  
             );
 345  
 
 346  2
         } else if (edge == RectangleEdge.RIGHT) {
 347  
 
 348  1
             return new Rectangle (
 349  
                 (int)(area.getMinX()),
 350  
                 (int)(leftEntity.getCenter().getY()),
 351  
                 (int)(height*this.rowTreeHeightUnitInPixels),
 352  
                 (int)(rightEntity.getCenter().getY()
 353  
                       - leftEntity.getCenter().getY())
 354  
             );
 355  
 
 356  
         }
 357  1
         else throw new IllegalArgumentException("Invalid edge.");
 358  
 
 359  
     }
 360  
     
 361  
     /**
 362  
      * Returns the area reserved for a clustering tree leaf. 
 363  
      *
 364  
      * @param area  area where the tree is being drawn.
 365  
      * @param info  the object describing this node.
 366  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 367  
      *
 368  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 369  
      *
 370  
      * @return  the area.
 371  
      */
 372  
     public Rectangle calculateLeafNodeArea(
 373  
             Rectangle2D area,
 374  
             HCTreeNodeInfo info,
 375  
             RectangleEdge edge) {
 376  
 
 377  
         int index;
 378  48
         HCTreeNode node = info.getNode();
 379  
 
 380  
         try {
 381  48
             index = info.getVisibleDataRange().getLeftBound();
 382  0
         } catch (Exception e) {
 383  0
             index = 0;
 384  
             // This can never happen.
 385  48
         }
 386  
 
 387  48
         if (edge == RectangleEdge.TOP) {
 388  
 
 389  24
             return new Rectangle(
 390  
                 getHeatMapXCoordinate(index),
 391  
                 (int)(area.getMaxY()-
 392  
                       node.getHeight()*this.columnTreeHeightUnitInPixels),
 393  
                 (int)getBlockWidth(),
 394  
                 (int)(node.getHeight()*this.columnTreeHeightUnitInPixels)
 395  
             );
 396  
 
 397  24
         } else if (edge == RectangleEdge.BOTTOM) {
 398  
 
 399  1
             return new Rectangle(
 400  
                 getHeatMapXCoordinate(index),
 401  
                 (int)(area.getMinY()),
 402  
                 (int)getBlockWidth(),
 403  
                 (int)(node.getHeight()*this.columnTreeHeightUnitInPixels)
 404  
             );
 405  
 
 406  
         }
 407  23
         else if (edge == RectangleEdge.LEFT) {
 408  
 
 409  20
             return new Rectangle(
 410  
                 (int)(area.getMaxX()-
 411  
                       (int)(node.getHeight()*this.rowTreeHeightUnitInPixels)),
 412  
                 getHeatMapYCoordinate(index),
 413  
                 (int)(node.getHeight()*this.rowTreeHeightUnitInPixels),
 414  
                 (int)getBlockHeight()
 415  
             );
 416  
 
 417  3
         } else if (edge == RectangleEdge.RIGHT) {
 418  
 
 419  1
             return new Rectangle(
 420  
                 (int)(area.getMinX()),
 421  
                 getHeatMapYCoordinate(index),
 422  
                 (int)(node.getHeight()*this.rowTreeHeightUnitInPixels),
 423  
                 (int)getBlockHeight()
 424  
             );
 425  
 
 426  2
         } else throw new IllegalArgumentException("Invalid edge.");
 427  
         
 428  
     }
 429  
 
 430  
     /**
 431  
      * Returns the center point of a clustering tree leaf node.
 432  
      *
 433  
      * @param area  area where the leaf node is being drawn.
 434  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 435  
      *
 436  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 437  
      *
 438  
      * @return  the center of a leaf node.
 439  
      */
 440  
     public Point calculateLeafNodeCenter(Rectangle2D area, RectangleEdge edge) {
 441  5
         if (edge == RectangleEdge.TOP) {
 442  
 
 443  1
             return new Point (
 444  
                 (int)(area.getCenterX()),
 445  
                 (int)(area.getMaxY())
 446  
             );
 447  
 
 448  4
         } else if (edge == RectangleEdge.BOTTOM) {
 449  
 
 450  1
             return new Point (
 451  
                 (int)(area.getCenterX()),
 452  
                 (int)(area.getMinY())
 453  
             );
 454  
 
 455  3
         } else if (edge == RectangleEdge.LEFT) {
 456  
 
 457  1
             return new Point (
 458  
                 (int)(area.getMaxX()),
 459  
                 (int)(area.getCenterY())
 460  
             );
 461  
 
 462  2
         } else if (edge == RectangleEdge.RIGHT) {
 463  
 
 464  1
             return new Point (
 465  
                 (int)(area.getMinX()),
 466  
                 (int)(area.getCenterY())
 467  
             );
 468  
 
 469  1
         } else throw new IllegalArgumentException("Invalid edge.");
 470  
 
 471  
     }
 472  
 
 473  
     /**
 474  
      * Returns the center point of a closed branch node.
 475  
      *
 476  
      * @param area  area where the tree is being drawn.
 477  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 478  
      * @param info  an object describing the node.
 479  
      *
 480  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 481  
      *
 482  
      * @return  the center of a closed branch node.
 483  
      */
 484  
     public Rectangle calculateClosedNodeArea(
 485  
             Rectangle2D area,
 486  
             HCTreeNodeInfo info,
 487  
             RectangleEdge edge) {
 488  
 
 489  43
         return calculateLeafNodeArea(area,info,edge);
 490  
 
 491  
     }
 492  
 
 493  
     /**
 494  
      * Returns the center point of a closed branch node.
 495  
      *
 496  
      * @param height  height of this node.
 497  
      * @param area  area where the subtree is being drawn.
 498  
      * @param edge  the edge of the heatmap where this tree is being drawn.
 499  
      *
 500  
      * @throws IllegalArgumentException  if the given edge parameter is illegal.
 501  
      *
 502  
      * @return  the center of a closed branch node.
 503  
      */
 504  
     public Point calculateClosedNodeCenter(
 505  
             Rectangle2D area, double height, RectangleEdge edge
 506  
     ) {
 507  
 
 508  47
         if (edge == RectangleEdge.TOP) {
 509  
 
 510  24
             return new Point (
 511  
                 (int)(area.getCenterX()),
 512  
                 (int)(area.getMaxY()-height*this.columnTreeHeightUnitInPixels)
 513  
             );
 514  
 
 515  23
         } else if (edge == RectangleEdge.BOTTOM) {
 516  
 
 517  1
             return new Point (
 518  
                 (int)(area.getCenterX()),
 519  
                 (int)(area.getMinY()+height*this.columnTreeHeightUnitInPixels)
 520  
             );
 521  
 
 522  22
         } else if (edge == RectangleEdge.LEFT) {
 523  
 
 524  20
             return new Point (
 525  
                 (int)(area.getMaxX()-height*this.rowTreeHeightUnitInPixels),
 526  
                 (int)(area.getCenterY())
 527  
             );
 528  
 
 529  2
         } else if (edge == RectangleEdge.RIGHT) {
 530  
 
 531  1
             return new Point (
 532  
                 (int)(area.getMinX()+height*this.rowTreeHeightUnitInPixels),
 533  
                 (int)(area.getCenterY())
 534  
             );
 535  
 
 536  
         }
 537  1
         else throw new IllegalArgumentException("Invalid edge.");
 538  
 
 539  
     }
 540  
 
 541  
 }
 542