com.davisor.graphics.chart
Class HexGridFactory

java.lang.Object
  extended bycom.davisor.graphics.chart.ChartFactory
      extended bycom.davisor.graphics.chart.AxisFactory
          extended bycom.davisor.graphics.chart.GridFactory
              extended bycom.davisor.graphics.chart.HexGridFactory
All Implemented Interfaces:
com.davisor.core.Dupable, com.davisor.core.MIMETypes, com.davisor.core.Public

public class HexGridFactory
extends GridFactory

HexGridFactory implements a grid chart filled with hexagonal cells. The hexagons stand on one of their vertices, and they are arranged into rectangular grid as shown below.

                          |--| margin
                               -
        .     .     .     .    |
      ..:..^..:..^..:..^..:... -
        :/   \:/   \:/   \:
    2   |     |     |     |
        |     |     |     |
      ..:\....^.....^..../:...
        : \ / : \ / : \ / : \ 
    1   :  Y  :  Y  :  Y  :  |
        :  |  :  |  :  |  :  |
 -    ..:..^..:..^..:..^..:./.
 |      :/   \:/   \:/   \:/
 1  0   |     Y     Y     Y
 |      |     |     |     |
 -    ..:\.../:\.../:\.../:... -
        : `v' : `v' : `v' :    |
                               -
           0     1     2  |--| margin

        |--1--|
 
Laying hexagons on rectangular grid raises some difficult problems. First, hexagon natural cell coordinates where axes are in 60 degreen angle must be mapped to rectangular cell coordinates where the axes are in 90 angle. Second, hexagon natural 60-degree symmetric unit radius must be mapped on corresponding uneven horizontal and vertical radiuses. Finally, when laid out on a rectangular grid, some extra margin space is needed around the outer edge of the grid to make room for the uneven hexagon boundary line that exceeds the boundaries of corresponding rectangular grid.

The cell coordinate problem may be solved by shifing hexagon rows left so that cells with equal X coordinates lie in straigh columns, within the limitations set by hexagonal topology of course. When map is zoomed in by dividing hexagons into smaller hexagons, the shifting pattern becomes more complex:

         /\    /\     ::
        /  \  /\/\   ::::
       /\  / /\/\/  :::::
      /  \/ /\/\/  :::::
      \  /\ \/\/\  :::::
       \/  \ \/\/\  :::::
       /\  / /\/\/  :::::
      /  \/ /\/\/  :::::
      \  /  \/\/   ::::
       \/    \/     ::
 level: 1     2     3     ...
 
The Y -axis step value controls the zooming level, and therefore also the number of rows that are shifted to the same direction at a time.

The second problem is solved by first using a hexagon radius R that makes the hexagons one unit step wide, and then scaling the hexagons vertically by 1/A so that the vertical distance between hexagon rows becomes also one unit step high. The resulting distoted hexagon is no more symmetric along the hexagon natural 60-degreen angles, but it is symmetric horizontally and vertically. The createHexagon(float, float) method provides a tool to create such hexagon shapes.

Thanks to the vertical scaling, the bounding box of the distorted unit hexagon exceeds vertial unit size. The hexagons will not however cover each other as the hexagon rows interleave in the way hexagons do, but on the bottom and top boundaries of such a hexagon map, extra space is needed or the outer tips of the edgemost hexagons will be clipped of. The amoun of this extra space can be computed with the computeHexagonMargin(int, float, float, int) method.

Since:
JDK1.2

Nested Class Summary
 
Nested classes inherited from class com.davisor.graphics.chart.AxisFactory
AxisFactory.AxisContext, AxisFactory.AxisMetrics
 
Nested classes inherited from class com.davisor.graphics.chart.ChartFactory
ChartFactory.ChartContext, ChartFactory.ChartMetrics
 
Field Summary
protected static float A
           
protected static float C
           
protected static java.awt.geom.GeneralPath HEXAGON
           
protected static float R
           
protected static float RX
           
protected static float RY
           
 
Fields inherited from class com.davisor.graphics.chart.AxisFactory
DEFAULTLABELTYPE, FLIPX, FLIPY, MAJORMARGIN, MINORMARGIN, MINSIZE
 
Fields inherited from class com.davisor.graphics.chart.ChartFactory
ALL, BRIGHT, CHANNEL, COS, DARK, DOTSEQUENCE, DOTSTROKE, DOTSTROKEWIDTH, DUMPFACTORYNAME, ENCODERINFO, FONT, FRC, HAS_3D, I, LABEL, LABELFIELDNAMES, LABELFIELDS, MIME_DEFAULT, NONE, NORMAL, NULLSTROKE, PERCENT, PI2, SHAPE, SIN, STROKE, STROKEWIDTH, TIC, VALUE, X, Y, Z
 
Fields inherited from interface com.davisor.core.MIMETypes
FILETYPE_BMP, FILETYPE_CSS, FILETYPE_DOC, FILETYPE_ECMA, FILETYPE_GIF, FILETYPE_HTML, FILETYPE_HTML_CSS, FILETYPE_INDEX, FILETYPE_INDEX_DOC, FILETYPE_INDEX_HTML, FILETYPE_INDEX_HTML_CSS, FILETYPE_INDEX_PDF, FILETYPE_INDEX_PPT, FILETYPE_INDEX_SVG, FILETYPE_INDEX_XHTML, FILETYPE_INDEX_XLS, FILETYPE_INDEX_XMSE, FILETYPE_INDEX_XMSP, FILETYPE_INDEX_XMSW, FILETYPE_INDEX_XSLFO, FILETYPE_JPEG, FILETYPE_PDF, FILETYPE_PNG, FILETYPE_PNG_WBMP, FILETYPE_PPM, FILETYPE_PPT, FILETYPE_SVG, FILETYPE_TEXT, FILETYPE_WBMP, FILETYPE_XHTML, FILETYPE_XLS, FILETYPE_XML, FILETYPE_XMSE, FILETYPE_XMSP, FILETYPE_XMSW, FILETYPE_XSLFO, FILETYPE_XSLFO_CSS, MIME_BMP, MIME_CSS, MIME_DOC, MIME_ECMA, MIME_GIF, MIME_HTML, MIME_HTML_CSS, MIME_INDEX, MIME_INDEX_DOC, MIME_INDEX_HTML, MIME_INDEX_HTML_CSS, MIME_INDEX_PDF, MIME_INDEX_PPT, MIME_INDEX_SVG, MIME_INDEX_XHTML, MIME_INDEX_XLS, MIME_INDEX_XMSE, MIME_INDEX_XMSP, MIME_INDEX_XMSW, MIME_INDEX_XSLFO, MIME_JPEG, MIME_OTHER, MIME_PDF, MIME_PNG, MIME_PNG_WBMP, MIME_PPM, MIME_PPT, MIME_SVG, MIME_TEXT, MIME_WBMP, MIME_XHTML, MIME_XLS, MIME_XML, MIME_XMSE, MIME_XMSP, MIME_XMSW, MIME_XSLFO, MIME_XSLFO_CSS
 
Constructor Summary
HexGridFactory()
          Default constructor.
HexGridFactory(GridFactory factory)
          Copy constructor.
 
Method Summary
static float[] computeHexagonMargin(int dim, float size, float steps, int level)
          Computes how much margin space the edgemost hexagons in a fixed size hexagonal grid need around them, and what would the cell size then be.
protected  java.awt.Shape createCellShape(java.awt.geom.Rectangle2D drawingArea, int[] steps, int level)
          Creates a new hexagon grid element shape object scaled to fill a cell of given size.
static java.awt.Shape createHexagon(float width, float height)
          Creates a new hexagon shape object scaled to "fill" a cell of given size.
protected  Chart drawChart(AxisFactory.AxisContext context, AxisFactory.AxisMetrics metrics, ChartAxes axes, boolean fillGrid, boolean drawAxes, boolean drawLabel, boolean drawGrid, Chart chart, int[] steps, int level)
          Creates a grid chart.
 com.davisor.core.Dupable dup()
          Makes a deep copy of this object.
protected  java.awt.geom.Point2D getCellPoint(int x, int y, java.awt.geom.Rectangle2D drawingArea, int[] steps, int level)
          Computes the coordinates of the centermost point of the hexagon [x,y].
 
Methods inherited from class com.davisor.graphics.chart.GridFactory
drawCells, drawChart, drawLabels, getIdealSize, resolveLimits
 
Methods inherited from class com.davisor.graphics.chart.AxisFactory
computeMinorMargin, createChart, createChart, createContext, createContext, createContext, createContext, createMetrics, createMetrics, createMetrics, createMetrics, drawAxis, drawMarkers, drawTics, drawXYAxes, drawXYZAxes, fillGrid, fillMarkers, formatDouble, getIdealSize, hasGridLines, isSilent, labelAxis, labelMarkers, resolveLabels, resolveLabels, resolveMarkerSizes, resolveOverlap, titleAxis, transpose
 
Methods inherited from class com.davisor.graphics.chart.ChartFactory
annotate, combineProperties, createChannelType, createChannelType, createChart, createChart, createChart, createChart, createChart, createFormat, createPaintChannelType, createPaintChannelType, createShapeChannelType, createShapeChannelType, createSummary, drawLabel, getContentType, getDefaultPaint, getFactory, getFactory, getGroup, getIsometricCoefficients, getLegendShape, getName, has3D, hasSVG, isClassAvailable, isMultiSeriesMode, main, mayHaveLegend, registerFactory, resolveDataLimits, resolveDataLimits, rotateSize, shade, unregisterFactory
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

A

protected static final float A

R

protected static final float R

C

protected static final float C

RX

protected static final float RX

RY

protected static final float RY

HEXAGON

protected static final java.awt.geom.GeneralPath HEXAGON
Constructor Detail

HexGridFactory

public HexGridFactory()
Default constructor.


HexGridFactory

public HexGridFactory(GridFactory factory)
Copy constructor.

Method Detail

drawChart

protected Chart drawChart(AxisFactory.AxisContext context,
                          AxisFactory.AxisMetrics metrics,
                          ChartAxes axes,
                          boolean fillGrid,
                          boolean drawAxes,
                          boolean drawLabel,
                          boolean drawGrid,
                          Chart chart,
                          int[] steps,
                          int level)
                   throws InvalidDataException
Creates a grid chart.

This method allocate plot offset margins for hexagon top and bottom spikes and for horizontally shifted rows, and then invokes corresponding superclass method to do the actual drawing.

Overrides:
drawChart in class GridFactory
Parameters:
context - chart context
metrics - chart metrics
axes - chart axes
fillGrid - enables or disables axis background filling
drawAxes - determine which axes may be drawn
drawLabel - determine if default labeling is to be applied
drawGrid - determine if axis grid is to be drawn
chart - chart to draw into
steps - number of grid elements
level - grid zoom level
Throws:
InvalidDataException - if data is invalid for chart drawing
See Also:
computeHexagonMargin(int, float, float, int), AxisFactory.AxisMetrics.setPlotOffset(int,float)

dup

public com.davisor.core.Dupable dup()
                             throws com.davisor.core.DupNotSupportedError
Makes a deep copy of this object.

Throws:
com.davisor.core.DupNotSupportedError - if the object cannot be deep-copied

createCellShape

protected java.awt.Shape createCellShape(java.awt.geom.Rectangle2D drawingArea,
                                         int[] steps,
                                         int level)
Creates a new hexagon grid element shape object scaled to fill a cell of given size.

Specified by:
createCellShape in class GridFactory
Parameters:
drawingArea - area where cells will be drawn
steps - number of cell layers
level - zooming level
See Also:
createHexagon(float, float)

getCellPoint

protected java.awt.geom.Point2D getCellPoint(int x,
                                             int y,
                                             java.awt.geom.Rectangle2D drawingArea,
                                             int[] steps,
                                             int level)
Computes the coordinates of the centermost point of the hexagon [x,y].

This method assumes that enough margin space has been reserved outside the hexagon cells, as described by computeHexagonMargin(int, float, float, int).

Specified by:
getCellPoint in class GridFactory
Parameters:
x - cell x coordinate
y - cell y coordinate
drawingArea - area where cells will be drawn
steps - number of cells
level - zooming level

computeHexagonMargin

public static float[] computeHexagonMargin(int dim,
                                           float size,
                                           float steps,
                                           int level)
Computes how much margin space the edgemost hexagons in a fixed size hexagonal grid need around them, and what would the cell size then be.

       cellsize
          : : 
 offset/2 : : offset/2
      . . : : . .
  ___ :_:_:_:_:_:..
   |  | :.....:.|.. offset/2
   |  | :.:.:.: |..........
 size | :.:.:.: |.......... cellsize
   |  | :.:.:.:.|..
  _|_ |_________|.. offset/2
    
      |--size---|

  
In particular, with the number of steps and the amount of available space known, this method solves to following equations for 'offset' and 'cellsize':
 steps * cellsize + offset = size
                    aspect = offset/cellsize

         horizontal aspect = level * 0.5 
           vertical aspect = C
 

Parameters:
dim - width/height dimension selector
size - grid size along the given dimension
steps - the number of grid cells along the given dimension
level - zooming level
Returns:
[offset,cellsize]

createHexagon

public static java.awt.Shape createHexagon(float width,
                                           float height)
Creates a new hexagon shape object scaled to "fill" a cell of given size. The returned shape will be a hexagon standing on it's tip, with points running in clockwise direction.

A hexagon that stands on it's tip and that that "fills" a cell must exceed it's rectangular boundaries as follows:

   ........... -
 - ..:..^..:.. |
 |   :/   \:   |           _____
 1   |     |  1/A     A = V 3/4
 |   |     |   |          
 - ..:\.../:.. |
   ..:..v..:.. -

     |--1--|
 
The returned shape will therefore meet given width exactly, but be 1/A times taller than requested. The origo of the shape will be at it's center.

Parameters:
width - cell width
height - cell height
Returns:
new hexagon shape, as described above


Copyright © 2001-2004 Davisor Oy. All Rights Reserved.