Class LineGraph

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>, AbstractGraph.HasLogScaleY, AbstractGraph.Shifter, AbstractGraph.Shifting, AbstractGraph.Zoomer, AbstractGraph.Zooming, BasicTooltipProvider, ContextMenu.Listener, ContextMenu.Provider, Tooltip.Provider

LineGraph visualizes time series data as one or more line plots inside a resizable, pannable and zoomable canvas. It extends AbstractGraph<double[]> and implements interactions for shifting and zooming (Shifting, Zooming), optional logarithmic y-axis scaling (HasLogScaleY) and provides tooltips (BasicTooltipProvider).

Concepts and data layout:

  • Each element stored in the internal RingBuffer is a double[] whose first element is the time stamp and subsequent elements are the values to plot for each line (index 1..n). Some modules use a specific layout (e.g. mean, mean-sdev, mean+sdev).
  • The graph maintains an x-range [xMin, xMax] and a y-range [yMin, yMax] via the Style object. The x-range is expressed in the same time units as the first element of the data arrays. The buffer capacity and style.xIncr determine the maximum historical range available for panning (the absolute bounds are [absMin, absMax] where absMax is hard-coded to 0.0 and absMin = absMax - capacity*xIncr).
  • The graph can operate with autoscaling for the y-axis (style.autoscaleY) or with fixed y-limits. When autoscale is enabled, added data updates yMin/yMax to at least cover observed values; ranges are expanded but never shrunk automatically.
  • Logarithmic y-scaling is supported (style.logScaleY), but it requires strictly positive values; if negative or zero values are present the graph disables log-scaling and issues a warning. When autoscaling and log-scaling interact, small positive minima are adjusted to a fraction of the maximum to avoid log(0).

Main behaviors and responsibilities:

  • Construction: create a LineGraph with a Mean view and a Module that supplies trait names, colors and data semantics.
  • Parsing: parse(String args) accepts a comma-separated argument string (no spaces around commas) and recognizes options: log, xmin <value>, xmax <value>, ymin <value>, ymax <value>. ymin/ymax disable autoscale when specified.
  • Data ingestion: addData(double t, double[] data) prepends time and delegates to addData(double[]). addData(double[]) appends the data array into the RingBuffer (the caller must ensure the first element is time and the array is not modified afterwards). addData updates the autoscaled y-range and may disable log-scaling if non-positive values are encountered.
  • Resetting/initialization: reset() prepares the buffer, initializes autoscaled y-range and recomputes the number of steps along x relative to the current view. Buffer size is at least DEFAULT_BUFFER_SIZE or the view width, and steps are clamped between 1 and buffer capacity.
  • Painting: paint(boolean force) renders the lines, optional markers and axes frame. The method clips drawing to the plotting area, supports linear or log y-scaling, and draws colored lines and markers using the module-provided color scheme. Painting is scheduled on the UI thread using schedulePaint() to coalesce multiple requests.
  • Interaction:
    • shift(dx, dy) pans the x-range in multiples of style.xIncr. Small mouse/touch deltas that do not exceed a single increment are accumulated until sufficient movement occurs. Shifting respects the absolute data bounds determined by the buffer capacity.
    • zoom() resets the view to a default zoom focused on the latest data (xMax = 0.0 and xMin = xMax - max(1, DEFAULT_STEPS*xIncr)).
    • zoom(double zoom, double x, double y) zooms around the right-hand end (xMax is treated as the reference) and enforces a minimum number of steps (MIN_STEPS). Zooming also snaps bounds to integer multiples of style.xIncr and clamps to the available history.
  • Tooltips: getTooltipAt(int x,int y) converts pixel coordinates to normalized plotting coordinates and delegates to getTooltipAt(double x, double y). The tooltip builder searches the buffer to interpolate the time and values at the requested x position and returns an HTML table with the x-value, y-value and per-trait values (or mean ± sdev when applicable). Tooltips are suppressed while the left mouse button is held and when the point lies outside bounds.
  • Context menu: populateContextMenuAt adds a "Clear" action that clears the graph history and triggers an immediate repaint.

Fields of interest (summary):

  • steps: number of steps shown along the x-axis (clamped to [1, buffer.capacity]).
  • buffer: RingBuffer<double[]> storing historical data arrays (time + values).
  • style: visual and interaction configuration (xMin/xMax/yMin/yMax, xIncr, autoscaleY, logScaleY, markerSize, lineWidth, etc.).
  • paintScheduled: coalesces deferred paint requests.
  • pinchScale / pinch: state used for touch pinch gestures (scale and center).

Important implementation notes and caveats:

  • The buffer stores references to the provided double[] objects for performance — callers must not modify arrays after passing them to addData(double[]).
  • Log-scaling requires strictly positive y-values. If negative or zero values exist the graph will disable log-scale and emit a warning.
  • Painting occurs on the UI thread and is scheduled via GWT Scheduler; callers should avoid heavy synchronous work on the UI thread during paint() to keep the UI responsive.
  • Precision: x- and y-axis snapping to style.xIncr is used to keep numeric bounds aligned with the data grid; floating point rounding may occur when snapping or computing steps.

This class is intended for use within the EvoLudo UI framework and relies on the surrounding infrastructure (Style, RingBuffer, Module, Mean view, drawing context MyContext2d and Scheduler). It focuses on correctness of visualization, responsive UI updates via scheduled paints and robust handling of autoscaling and log-scaling edge cases.

Usage example (conceptual):

  LineGraph g = new LineGraph(meanView, module);
  g.parse("ymin 0.0,ymax 1.0"); // configure
  g.addData(t, new double[]{t, v1, v2, ...});
  g.zoom(2.0, sx, sy); // zoom in
  // tooltips and context menu are integrated into the hosting UI
Author:
Christoph Hauert
  • Field Details

    • steps

      double steps
      The default number of (time) steps shown on this graph.
    • nLines

      int nLines
      The number of lines to plot.
    • paintScheduled

      private boolean paintScheduled
      The flag to indicate whether painting is already scheduled. Subsequent requests are ignored.
    • pinchScale

      double pinchScale
      The field to track the progress of the pinch gesture.
    • pinch

      Point2D pinch
      The center of the pinch gesture.
    • totDx

      int totDx
      The total shift in the x-direction.
    • totDy

      int totDy
      The total shift in the y-direction.
    • MIN_STEPS

      protected static final int MIN_STEPS
      The minimum number of steps along the x-axis.
      See Also:
    • DEFAULT_STEPS

      protected static final int DEFAULT_STEPS
      The default number of steps along the x-axis.
      See Also:
    • clearMenu

      private ContextMenuItem clearMenu
      The context menu item to clear the graph.
  • Constructor Details

    • LineGraph

      public LineGraph(Mean view, Module<?> module)
      Create new line graph for view. The id is used to distinguish different graphs of the same module to visualize different components of the data and represents the index of the data column.
      Parameters:
      view - the view of this graph
      module - the module backing the graph
  • Method Details

    • onLoad

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

      public boolean parse(String args)
      Description copied from class: AbstractGraph
      Parse the arguments for the graph. Default implementation does nothing.
      Overrides:
      parse in class AbstractGraph<double[]>
      Parameters:
      args - the arguments for the graph
      Returns:
      true if parsing was successful
    • parseArgs

      private void parseArgs(String args)
      Parse command line options for the graph. The following options are recognized:
      • log: enable logarithmic scaling on the y-axis
      • xmin <value>: set the minimum x-axis value
      • xmax <value>: set the maximum x-axis value
      • ymin <value>: set the minimum y-axis value
      • ymax <value>: set the maximum y-axis value
      Parameters:
      args - the command line arguments (comma separated, no spaces)
    • setColors

      public void setColors(String[] colors)
      Description copied from class: AbstractGraph
      Assign a list of colors to the graph.
      Overrides:
      setColors in class AbstractGraph<double[]>
      Parameters:
      colors - the list of colors
    • getNLines

      public int getNLines()
      Get the number of lines plotted in this graph.
      Returns:
      the number of lines
    • reset

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

      public void addData(double t, double[] data)
      Add data to the graph. The time t is prepended to the data as the first element.
      Parameters:
      t - the time of the data
      data - the data to add
      Implementation Notes:
      The data array is cloned and the time prepended before adding it to the buffer.
    • addData

      public void addData(double[] data)
      Add data to the graph.
      Parameters:
      data - the data to add
      Implementation Notes:
      The data array is directly added to the buffer. It is the caller's responsibility to ensure that the first entry represents time and the data remains unmodified.
    • setLogY

      void setLogY(boolean logY)
      Description copied from class: AbstractGraph
      Set the y-axis to logarithmic scale if logY is true and if yMin &ge; 0. If yMin == 0 it is increased to 0.01 * yMax. If yMin < 0 logarithmic scale requests are ignored.
      Overrides:
      setLogY in class AbstractGraph<double[]>
      Parameters:
      logY - true to set logarithmic scale on y-axis
    • noLogY

      private void noLogY()
      Helper method to disable log scale on y-axis and issue warning.
    • compareData

      private int compareData(double[] o1, double[] o2)
      Compare two data arrays based on their minimum value (ignoring first entry, time). Returns a negative integer, zero, or a positive integer if the minimum of the first argument is less than, equal to, or greater than the second, respectively.
      Parameters:
      o1 - the first data array
      o2 - the second data array
      Returns:
      a negative integer, zero, or a positive integer
    • 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
    • computeYScale

      private double[] computeYScale(double h)
      Compute y-axis scale info: [ymin, yrange, yScale]
      Parameters:
      h - the height of the plotting area
      Returns:
      an array containing [ymin, yScale]
    • drawLines

      private void drawLines(double width, double[] yinfo, int nLines)
      Draw the line plots and (suppressed) markers at the newest sample.
      Parameters:
      width - the width of the plotting area
      yinfo - the y-axis transform info
      nLines - the number of lines to draw
    • drawLatestMarkers

      private void drawLatestMarkers(double start, double[] current, int nLines, double[] yinfo)
      Draw markers for the newest sample (extracted helper).
      Parameters:
      start - the starting x-coordinate
      current - the current data array
      nLines - the number of lines to draw
      yinfo - the y-axis transform info
    • drawSegmentClipped

      private void drawSegmentClipped(double start, double end, double[] prev, double[] current, int nLines, double[] yinfo, double width)
      Draw a historical segment between 'start' and 'end', handling clipping against the visible window (-w .. 0) and log/linear y transforms.
      Parameters:
      start - starting x-coordinate of the segment
      end - ending x-coordinate of the segment
      prev - the previous data array
      current - the current data array
      nLines - the number of lines to draw
      yinfo - the y-axis transform info
      width - the width of the plotting area
    • drawMarkers

      private void drawMarkers(double width, double ymin, int nLines)
      Draw horizontal marker lines (if any) using the same y transform.
      Parameters:
      width - the width of the plotting area
      ymin - the minimum y-value
      nLines - the number of lines to draw
    • schedulePaint

      protected void schedulePaint()
      Schedule painting of the graph. If painting is already scheduled, subsequent requests are ignored.
      See Also:
    • 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
    • shift

      public void shift(int dx, int dy)
      Description copied from class: AbstractGraph
      Shift the (zoomed) graph within the view port by (dx, dy). Default implementation for graphs that implement Shifting.
      Specified by:
      shift in interface AbstractGraph.Shifter
      Overrides:
      shift in class AbstractGraph<double[]>
      Parameters:
      dx - the horizontal shift of the graph
      dy - the vertical shift of the graph
      See Also:
    • zoom

      public void zoom()
      Description copied from class: AbstractGraph
      Reset zoom. Default implementation for graphs that implement Zooming.
      Specified by:
      zoom in interface AbstractGraph.Zooming
      Overrides:
      zoom in class AbstractGraph<double[]>
      See Also:
    • zoom

      public void zoom(double zoom, double x, double y)
      Description copied from class: AbstractGraph
      Helper method to adjust zoom level with the zoom center at the scaled coordinates (fx, fy), specified as a fraction of the view port in horizontal and vertical directions, respectively.
      Overrides:
      zoom in class AbstractGraph<double[]>
      Parameters:
      zoom - the new zoom level
      x - the scaled x-coordinate of the zoom center
      y - the scaled y-coordinate of the zoom center
      See Also:
    • getSteps

      public double getSteps()
      Get the number of steps along the x-axis.
      Returns:
      the number of steps
    • setSteps

      public void setSteps(double steps)
      Set the number of steps along the x-axis.
      Parameters:
      steps - the number of steps
    • 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(double x, double y)
      Description copied from interface: BasicTooltipProvider
      Get the tooltip at the scaled coordinates (x,y) with the origin in the lower left corner of the graph.
      Specified by:
      getTooltipAt in interface BasicTooltipProvider
      Parameters:
      x - the x coordinate
      y - the y coordinate
      Returns:
      the tooltip
    • appendTipHeader

      private void appendTipHeader(StringBuilder tip, double mouset, double yval)
      Build and append the static header rows (label, x and y rows) to the tooltip.
      Parameters:
      tip - builder receiving the markup
      mouset - x-axis value under the cursor
      yval - y-axis value under the cursor
    • findInterpolationForMouse

      private double[] findInterpolationForMouse(double mouset)
      Scan the buffer and determine the two surrounding samples and the interpolation factor for the supplied mouse time.
      Parameters:
      mouset - the mouse time
      Returns:
      the interpolated data array (time + values) or null if not found
    • appendTipInterpolation

      private void appendTipInterpolation(StringBuilder tip, double mouset)
      Append interpolated values (either Continuous mean±sdev or trait values) to the tooltip builder using the precomputed interpolation result.
      Parameters:
      tip - the tooltip builder
      mouset - the mouse time
    • appendTipContinuous

      private void appendTipContinuous(StringBuilder tip, double[] inter, Color[] colors)
      Append mean ± sdev row for Continuous modules.
      Parameters:
      tip - the tooltip builder
      inter - the interpolated data array
      colors - the colors for each trait
    • appendTipTraits

      private void appendTipTraits(StringBuilder tip, double[] inter, Color[] colors)
      Append individual trait rows for non-Continuous modules.
      Parameters:
      tip - the tooltip builder
      inter - the interpolated data array
      colors - the colors for each trait
    • interpolate

      private double interpolate(double left, double right, double x)
      Interpolate linearly between current and prev at x.
      Parameters:
      left - the left value
      right - the right value
      x - the location inbetween
      Returns:
      the interpolated value
    • 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: