Class HistoGraph

All Implemented Interfaces:
HasAllDragAndDropHandlers, HasAllFocusHandlers, HasAllGestureHandlers, HasAllKeyHandlers, HasAllMouseHandlers, HasAllTouchHandlers, HasBlurHandlers, HasClickHandlers, HasContextMenuHandlers, HasDoubleClickHandlers, HasDragEndHandlers, HasDragEnterHandlers, HasDragHandlers, HasDragLeaveHandlers, HasDragOverHandlers, HasDragStartHandlers, HasDropHandlers, HasFocusHandlers, HasGestureChangeHandlers, HasGestureEndHandlers, HasGestureStartHandlers, HasKeyDownHandlers, HasKeyPressHandlers, HasKeyUpHandlers, HasMouseDownHandlers, HasMouseMoveHandlers, HasMouseOutHandlers, HasMouseOverHandlers, HasMouseUpHandlers, HasMouseWheelHandlers, HasTouchCancelHandlers, HasTouchEndHandlers, HasTouchMoveHandlers, HasTouchStartHandlers, MouseDownHandler, MouseMoveHandler, MouseOutHandler, MouseUpHandler, MouseWheelHandler, TouchEndHandler, TouchMoveHandler, TouchStartHandler, HasAttachHandlers, EventHandler, HasHandlers, EventListener, AcceptsOneWidget, Focusable, HasFocus, HasOneWidget, HasVisibility, HasWidgets, HasWidgets.ForIsWidget, IsWidget, RequiresResize, SourcesClickEvents, SourcesFocusEvents, SourcesKeyboardEvents, SourcesMouseEvents, SourcesMouseWheelEvents, Iterable<Widget>, BasicTooltipProvider, ContextMenu.Listener, ContextMenu.Provider, Tooltip.Provider

public class HistoGraph extends AbstractGraph<double[]> implements BasicTooltipProvider
A histogram graph used to render and interact with binned data.

HistoGraph renders a histogram from a backing two-dimensional double[][] data array. Each HistoGraph instance references a specific row in that array (the row index) and therefore multiple HistoGraph instances may share the same underlying data buffer but operate on different rows. The number of bins rendered is determined by the length of the referenced data row.

Data model and normalization

  • The backing data is a double[][] provided via setData(double[][]). The graph uses the configured row to access its own bin values.
  • Normalization may be controlled in two mutually exclusive ways:
    • setNormalized(boolean) toggles normalization relative to the graph's sample count (nSamples). If enabled, values returned by getData(int) are already normalized.
    • setNormalized(int) sets normIdx, a separate data row used to normalize per-bin values (per-bin denominators are read from that row). When normIdx >= 0 normalization uses the values in the specified row and the graph will render values as data[row][i] / data[normIdx][i].
    Note: calling setNormalized(boolean) with true clears a previously set normIdx and vice versa — these modes conflict.
  • nSamples tracks the total number of added samples; addData(int) and addData(double) increment this counter (and update normalization row when normIdx >= 0).

Bins, range and dynamic resizing

  • The graph maps an x-coordinate to a bin via x2bin(double) and maps bin indices back to an x-coordinate (bin center) with bin2x(int).
  • Several behaviors assume the number of bins (nBins) is even: doubleMinRange() and doubleMaxRange() fold and shift bin contents when the numeric x-range must be doubled. These methods require that nBins is even; this is a precondition for correct range-doubling.
  • addData(double) will automatically expand the numeric x-range when a value falls outside the current style.xMin..style.xMax range by repeatedly calling the range-doubling helpers until the value fits. The number of bins remains constant during these range changes.

Rendering and autoscaling

  • The paint(boolean) method draws the histogram bars using the current style (colors, frame, axis ranges). If style.autoscaleY is enabled the graph will adapt style.yMin and style.yMax automatically based on the observed data values or the configured normalization row.
  • When autoscaling normalized data the graph uses a fixed table of thresholds (see the private autoscale matrix) to pick a convenient set of y-levels and step values; when data exceeds 1.0 it rounds up/down to "nice" boundaries.
  • Bars are clipped and mapped into pixel space using bounds and the current y-range; rendering ensures minimal visible height for very small values.

Markers and interactivity

  • Markers (inner class HistoGraph.Marker) annotate the histogram at an x-coordinate and are drawn as vertical lines spanning bin boundaries. Markers can have a color, description and optional dash pattern (linestyle). Markers are added with addMarker(double, String, String) (or the overload that accepts a dash pattern) and cleared with clearMarkers().
  • When markers are drawn the bin they hit is saved into HistoGraph.Marker.bin which allows the graph to include marker descriptions in tooltips.
  • The graph provides tooltip text for a pixel coordinate via getTooltipAt(int, int) and for a bin index via getTooltipAt(int). Tooltip content varies by the histogram view.type (degree, fitness, trait and several statistics types have specialized tooltip formats).
  • Context menu support includes a check-box item for toggling autoscaling of the y-axis; it can be enabled/disabled via enableAutoscaleYMenu(boolean).

Usage notes and important constraints

  • Because the data array may be shared across multiple HistoGraph instances, callers must take care when manipulating the shared data buffer concurrently.
  • The range-doubling implementation assumes an even nBins. Using an odd number of bins will break doubleMinRange() / doubleMaxRange().
  • Most methods guard against a null data array; however many operations are no-ops or return default values (e.g. -1 for missing bins) when no data is set.
Author:
Christoph Hauert
See Also:
  • Field Details

    • autoscale

      private static final double[][] autoscale
      The list of thresholds for automatically scaling the y-axis. The first element of each row is the maximum value for the y-axis, the second element is the minimum value for the y-axis, and the third element is the number of levels for the y-axis.

      For example, the scale changes from 0-1 with 4 levels to 0-0.5 with 5 levels if the maximum value drops below 0.4.

    • autoscaleidx

      private int autoscaleidx
      The index of the current autoscale setting.
    • binmarkers

      private ArrayList<HistoGraph.Marker> binmarkers
      The list of markers for the histogram.
    • data

      double[][] data
      The data array backing the histogram. This may be shared by multiple HistoGraphs, each accessing a different row in the array.
    • row

      int row
      The index of the data row.
    • message

      String message
      The message to display if no histogram is available.
    • isNormalized

      private boolean isNormalized
      The flag to indicate whether the data is normalized.
    • normIdx

      private int normIdx
      The index of the data row used for normalization.
    • nSamples

      double nSamples
      The number of samples in the histogram.
    • nBins

      int nBins
      The number of bins.
      See Also:
      Implementation Notes:
      The number of bins needs to be even for doubling the range of the histogram.
    • MAX_BINS

      public static final int MAX_BINS
      The maximum number of bins for the histogram.
      See Also:
    • MIN_BIN_WIDTH

      public static final int MIN_BIN_WIDTH
      The minimum width of a bin.
      See Also:
    • autoscaleYMenu

      private ContextMenuCheckBoxItem autoscaleYMenu
      The context menu to select autoscaling of the y-axis.
    • enableAutoscaleYMenu

      private boolean enableAutoscaleYMenu
      The flag to indicate whether the autoscale y-axis menu is enabled.
  • Constructor Details

    • HistoGraph

      public HistoGraph(Histogram view, Module<?> module, int row)
      Create new histogram graph for module running in view. The row is used to identify data entries that apply to this histogram and represents the index of the data row.
      Parameters:
      view - the view of this graph
      module - the module backing the graph
      row - the index of the data row
  • Method Details

    • addMarker

      public void addMarker(double x, String color, String descr)
      Add marker to histogram at x with color color and description descr.
      Parameters:
      x - the x-coordinate of the marker
      color - the color of the marker
      descr - the description of the marker
    • addMarker

      public void addMarker(double x, String color, String descr, int[] linestyle)
      Add marker to histogram at x with color color, description descr, and linestyle linestyle.
      Parameters:
      x - the x-coordinate of the marker
      color - the color of the marker
      descr - the description of the marker
      linestyle - the linestyle of the marker
    • clearMarkers

      public void clearMarkers()
      Clear all markers from the histogram.
    • getNoteAt

      public String getNoteAt(int bin)
      Get the description of the marker at bin bin or null if no marker is set.
      Parameters:
      bin - the index of the bin
      Returns:
      the description of the marker
    • onLoad

      protected void onLoad()
      Overrides:
      onLoad in class AbstractGraph<double[]>
    • getMaxBins

      public int getMaxBins()
      Calculate the maximum number of bins for the histogram with a width of at least MIN_BIN_WIDTH.
      Returns:
      the maximum number of bins
      See Also:
    • setNormalized

      public void setNormalized(boolean isNormalized)
      Set whether the data is normalized. If isNormalized is true, the sum of the data in each bin is normalized to 1.0.
      Note: This conflicts with setNormalized(int).
      Parameters:
      isNormalized - true if the data is normalized, false otherwise
    • setNormalized

      public void setNormalized(int normIdx)
      Set the index of the data row that is used for normalization. If multiple HistoGraphs share the same data, they all need to use the same row for normalization.
      Note: This conflicts with setNormalized(boolean).
      Parameters:
      normIdx - the index of the data row for normalization
    • getSamples

      public double getSamples()
      Get the number of samples for this histogram.
      Returns:
      the number of samples
    • getSamples

      public double getSamples(int idx)
      Get the total number of samples in bin with index idx. For data that is not normalized the number of samples is returned.
      Parameters:
      idx - the index of the bin
      Returns:
      the number of samples
      See Also:
    • getData

      public double[][] getData()
      Get the data for the histogram.
      Note: The data may be shared by multiple HistoGraphs, each refering to a row in the double[][] array specified by the graphs row.
      Returns:
      the 2D data array for storing the histogram data
    • getData

      public double getData(int idx)
      Get the data for the histogram in bin with index idx. Whether this returns raw or normalized data depends on the setting of the graph.
      Parameters:
      idx - the index of the bin
      Returns:
      the histogram data for the bin idx
      See Also:
    • setData

      public void setData(double[][] data)
      Set the data for the histogram.
      Note: The data may be shared by multiple HistoGraphs, each refering to a row in the double[][] array specified by the graphs row.
      Parameters:
      data - the 2D data array for storing the histogram data
    • addData

      public void addData(int bin)
      Add data point to histogram by increasing the count of the bin with index bin by one. For normalized data the normalization is updated accordingly.
      Parameters:
      bin - the index of the bin in the histogram
      See Also:
    • addData

      public void addData(int bin, double incr)
      Add data point to histogram by increasing the count of the bin with index bin by incr. For normalized data the normalization is updated accordingly.
      Parameters:
      bin - the index of the bin in the histogram
      incr - the increment to add to the bin
      See Also:
    • addData

      public void addData(double x)
      Add data point x to histogram. The data point is added to the histogram for \(x\in[x_\text{min},x_\text{max}]\). If \(x>x_\text{max}]\) or \(x<x_\text{min}]\) the range is doubled to \([x_\text{min}, x_\text{max} + (x_\text{max}-x_\text{min})]\)) or \([x_\text{min} - (x_\text{max}-x_\text{min}), x_\text{max}]\)), respectively. The number of bins remains unchanged.
      Important: The number of bins needs to be even!
      Parameters:
      x - the new data point
      See Also:
    • clearData

      public void clearData()
      Clear the histrogram data.
    • doubleMinRange

      private void doubleMinRange()
      Double the range of the histogram by lowering the minimum value.
      Implementation Notes:
      The number of bins needs to be even!
    • doubleMaxRange

      private void doubleMaxRange()
      Double the range of the histogram by increasing the maximum value.
      Implementation Notes:
      The number of bins needs to be even!
    • x2bin

      public int x2bin(double x)
      Convert x-coordinate to bin index.
      Parameters:
      x - the x-coordinate
      Returns:
      the index of the bin
    • bin2x

      public double bin2x(int bin)
      Convert the bin index to x-coordinate.
      Parameters:
      bin - the index of the bin
      Returns:
      the x-coordinate
    • reset

      public void reset()
      Description copied from class: AbstractGraph
      Reset the graph. Clear canvas and messages.
      Overrides:
      reset in class AbstractGraph<double[]>
    • export

      public void export(AbstractGraph.MyContext2d ctx)
      Description copied from class: AbstractGraph
      Export the graphical context ctx.
      Specified by:
      export in class AbstractGraph<double[]>
      Parameters:
      ctx - the graphical context to export
    • clearMessage

      public void clearMessage()
      Description copied from class: AbstractGraph
      Clear the message.
      Overrides:
      clearMessage in class AbstractGraph<double[]>
    • paint

      public boolean paint(boolean force)
      Description copied from class: AbstractGraph
      Draw the graph. For re-drawing the graph, set force to true.
      Overrides:
      paint in class AbstractGraph<double[]>
      Parameters:
      force - true to force re-drawing of graph
      Returns:
      true if painting skipped
    • handleSmallYMax

      private int handleSmallYMax(double yMax)
      Handle the case where yMax <= 1.0 by selecting an autoscale index and updating GraphStyle.yMax.
      Parameters:
      yMax - observed maximum bin height
      Returns:
      number of y-levels to use
    • handleLargeYMax

      private void handleLargeYMax(double yMax, double[] myData)
      Handle the case where yMax > 1.0 by rounding the maximum up if necessary and determining/rounding yMin when applicable.
      Parameters:
      yMax - observed maximum bin height
      myData - histogram counts
    • computeNormBounds

      private double[] computeNormBounds(double[] myData, double[] norm)
      Compute min/max from per-bin normalization row; returns {yMin, yMax}. If no valid normalization entries are found returns {0.0, 1.0}.
      Parameters:
      myData - histogram counts
      norm - per-bin normalization data
      Returns:
      two-element array {yMin, yMax}
    • selectAutoscaleIndexForYMax

      private int selectAutoscaleIndexForYMax(double yMax)
      Adjust autoscaleidx to match the given yMax.
      Parameters:
      yMax - observed maximum bin height
      Returns:
      number of y-levels for the selected autoscale row
    • drawBars

      private void drawBars(double[] myData, double[] norm, double barwidth, double h, double map)
      Draw bars for the histogram using either per-bin normalization row or global normalization flag.
      Parameters:
      myData - histogram values
      norm - per-bin normalization data (may be null)
      barwidth - width of a bar in pixels
      h - total graph height
      map - conversion factor from value to pixels
    • drawMarkers

      protected void drawMarkers()
      Draw the marked bins.
    • getBinAt

      public int getBinAt(int x, int y)
      Get the index of the bin at (x, y). Returns -1 if no bin is found.
      Parameters:
      x - the x-coordinate
      y - the y-coordinate
      Returns:
      the index of the bin
    • getTooltipAt

      public String getTooltipAt(int x, int y)
      Description copied from interface: Tooltip.Provider
      Get the tooltip information for the location with coordinates (x, y). The returned string may include HTML elements for formatting.
      Specified by:
      getTooltipAt in interface Tooltip.Provider
      Parameters:
      x - the x-coordinate for the tooltip
      y - the y-coordinate for the tooltip
      Returns:
      the (formatted) string with the tooltip info
    • getTooltipAt

      public String getTooltipAt(int bar)
      Description copied from interface: BasicTooltipProvider
      Get the tooltip for the location with index index. The index typically refers to an individual node but may equally refer to a location on a lattice for PDE models or trait distributions.
      Specified by:
      getTooltipAt in interface BasicTooltipProvider
      Parameters:
      bar - the index of the location
      Returns:
      the tooltip
    • appendTipDegree

      private void appendTipDegree(StringBuilder tip, int bar)
      Append degree tooltip.
      Parameters:
      tip - the tooltip string builder
      bar - the bar index
    • appendBinTooltip

      private void appendBinTooltip(StringBuilder tip, int bar)
      Append tooltip for bin at mouse coordinates.
      Parameters:
      tip - the tooltip string builder
      bar - the bar index
    • appendTipFixProb

      private void appendTipFixProb(StringBuilder tip, int bar)
      Append fixation probability tooltip.
      Parameters:
      tip - the tooltip string builder
      bar - the bar index
    • appendTipFixTime

      private void appendTipFixTime(StringBuilder tip, int bar)
      Append fixation time tooltip.
      Parameters:
      tip - the tooltip string builder
      bar - the bar index
    • appendTipStationary

      private void appendTipStationary(StringBuilder tip, int bar)
      Append stationary distribution tooltip.
      Parameters:
      tip - the tooltip string builder
      bar - the bar index
    • enableAutoscaleYMenu

      public void enableAutoscaleYMenu(boolean enable)
      Enable or disable the autoscale y-axis menu.
      Parameters:
      enable - true to enable the autoscale menu
    • populateContextMenuAt

      public void populateContextMenuAt(ContextMenu menu, int x, int y)
      Description copied from class: AbstractGraph
      Populate context menu menu in listening widget at (relative) position (x,y).

      Adds buffer size menu and queries the view to add further functionality.

      Specified by:
      populateContextMenuAt in interface ContextMenu.Provider
      Overrides:
      populateContextMenuAt in class AbstractGraph<double[]>
      Parameters:
      menu - context menu entries are added here
      x - horizontal coordinate (relative to listening widget)
      y - horizontal coordinate (relative to listening widget)
      See Also: