java.lang.Object
org.rrd4j.graph.ImageWorker
Direct Known Subclasses:
BufferedImageWorker, SVGImageWorker

public abstract class ImageWorkerextends Object
Abstract base class for image workers in RRD graphs. Provides drawing operations for creating graph images with various output formats. Tracks last paint/stroke/font to avoid redundant state changes that produce duplicate inline styles in SVG output.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) static final int
    Default pixels of width given to a transition narrower than one pixel.
    private static final String
    Placeholder text used to measure text extents before the real text is known
    private Graphics2D
    Graphics context for drawing operations
    private static final int
    Largest image the buffer holds, in bytes
    private Font
    Last font set on the graphics context (for deduplication)
    private Paint
    Last paint set on the graphics context (for deduplication)
    private Stroke
    Last stroke set on the graphics context (for deduplication)
    private boolean
    Whether plot lines and areas are drawn as bezier curves instead of steps
    private int
    Most width, in pixels, given to a transition that would otherwise be a vertical line.
  • Constructor Summary

    Constructors
    Constructor
    Description
    Create a worker with no graphics context attached; a subclass calls setG2d(Graphics2D) with the context it draws into before use.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) static int
    areaOutlineFlat(double[] x, double[] yTop, int start, int end, double yBottom, int[] xDev, int[] yDev)
    Builds the closed outline of an area whose lower boundary is the graph baseline.
    (package private) static int
    areaOutlineVariable(double[] x, double[] yBottom, double[] yTop, int start, int end, int[] xDev, int[] yDev)
    Builds the closed outline of an area whose lower boundary is itself a plotted series, as used by stacked plots.
    (package private) void
    clip(int x, int y, int width, int height)
    Set the clipping region for drawing operations.
    (package private) void
    Dispose of the graphics context.
    (package private) void
    drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke)
    Draw a line with the given paint and stroke.
    (package private) void
    drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke)
    Draw a polyline with the given paint and stroke.
    (package private) void
    drawPolylineSmooth(double[] x, double[] y, Paint paint, Stroke stroke)
    Draw a polyline as a smoothed curve.
    (package private) void
    drawString(String text, int x, int y, Font font, Paint paint)
    Draw a string at the given position with the specified font and paint.
    (package private) void
    fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint)
    Fill a polygon with variable bottom points.
    (package private) void
    fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint)
    Fill a polygon with a flat bottom.
    (package private) void
    fillPolygonSmooth(double[] x, double yBottom, double[] yTop, Paint paint)
    Fill an area with a flat lower boundary, drawn as a smoothed curve.
    (package private) void
    fillRect(int x, int y, int width, int height, Paint paint)
    Fill a rectangle with the given paint.
    (package private) double
    Get the ascent of the given font.
    (package private) double
    Get the total height of the given font.
    (package private) byte[]
    Get the image as a byte array.
    (package private) double
    getStringWidth(String text, Font font)
    Get the width of the given text in the specified font.
    (package private) boolean
    Reports whether plots are drawn as bezier curves rather than as steps.
    (package private) void
    loadImage(RrdGraphDef.ImageSource imageSource, int x, int y, int w, int h)
    Load and draw an image from the given source.
    (package private) abstract void
    Write the image to the given output stream.
    (package private) void
    Write the image to the given path.
    (package private) static int
    reduceVertices(double[] x, double[] y, int from, int to, boolean reverse, int[] xDev, int[] yDev, int c)
    Append the step-collapsed vertices of y over [start, end) into xDev/yDev, continuing from index c.
    (package private) void
    Reset the graphics state.
    protected abstract void
    Reset the graphics state using the given context.
    protected void
    Resets cached state tracking.
    (package private) abstract void
    resize(int width, int height)
    Resize the image to the given dimensions.
    (package private) static int
    runAnchorX(double[] x, int start)
    Leftmost column a run of samples may be drawn at, matching where the step renderer anchors the same run.
    (package private) void
    Save the image to the given file path.
    (package private) void
    setAntiAliasing(boolean enable)
    Enable or disable anti-aliasing.
    protected void
    Sets the graphics context for drawing operations.
    (package private) void
    setSmoothing(boolean smoothing)
    Selects whether plots are drawn as bezier curves or as steps.
    (package private) void
    setTextAntiAliasing(boolean enable)
    Enable or disable text anti-aliasing.
    (package private) void
    setTransitionWidth(int pixels)
    Sets how much width a sub-pixel transition may borrow from the flat runs beside it.
    (package private) static GeneralPath
    smoothedRun(double[] x, double[] y, int start, int end, int[] xDev, int[] yDev, int transitionWidth)
    Builds the smoothed curve through one gap-free run of samples: the run is reduced to step-collapsed vertices, anchored and widened, and then interpolated.
    private static double[]
    toDouble(int[] iv)
    Widens integral coordinates for the spline, which works in double precision.
    (package private) void
    transform(int x, int y, double angle)
    Apply a translation and rotation transform.

    Methods inherited from class Object

    clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • DUMMY_TEXT

      private static final String DUMMY_TEXT
      Placeholder text used to measure text extents before the real text is known
      See Also:
    • IMG_BUFFER_CAPACITY

      private static final int IMG_BUFFER_CAPACITY
      Largest image the buffer holds, in bytes
      See Also:
    • DEFAULT_TRANSITION_WIDTH

      static final int DEFAULT_TRANSITION_WIDTH
      Default pixels of width given to a transition narrower than one pixel.
      See Also:
    • g2d

      private Graphics2D g2d
      Graphics context for drawing operations
    • lastPaint

      private Paint lastPaint
      Last paint set on the graphics context (for deduplication)
    • lastStroke

      private Stroke lastStroke
      Last stroke set on the graphics context (for deduplication)
    • lastFont

      private Font lastFont
      Last font set on the graphics context (for deduplication)
    • smoothing

      private boolean smoothing
      Whether plot lines and areas are drawn as bezier curves instead of steps
    • transitionWidth

      private int transitionWidth
      Most width, in pixels, given to a transition that would otherwise be a vertical line. See MonotoneSpline.widenTransitions(int[], int[], int).
  • Constructor Details

    • ImageWorker

      public ImageWorker()
      Create a worker with no graphics context attached; a subclass calls setG2d(Graphics2D) with the context it draws into before use.
  • Method Details

    • setG2d

      protected void setG2d(Graphics2D g2d)
      Sets the graphics context for drawing operations. Disposes of previous context if exists.
      Parameters:
      g2d - new graphics context
    • resetState

      protected void resetState()
      Resets cached state tracking. Called when the graphics context changes or when an SVG group boundary is opened/closed that may affect inherited state.
    • resize

      abstract void resize(int width, int height)
      Resize the image to the given dimensions.
      Parameters:
      width - the width of the rectangle, in image pixels
      height - the height of the rectangle, in image pixels
    • clip

      void clip(int x, int y, int width, int height)
      Set the clipping region for drawing operations.
      Parameters:
      x - the x coordinate of the region's left edge
      y - the y coordinate of the region's top edge
      width - the width of the region, in image pixels
      height - the height of the region, in image pixels
    • transform

      void transform(int x, int y, double angle)
      Apply a translation and rotation transform.
      Parameters:
      x - the x translation
      y - the y translation
      angle - the rotation angle
    • reset

      void reset()
      Reset the graphics state.
    • reset

      protected abstract void reset(Graphics2D g2d)
      Reset the graphics state using the given context.
      Parameters:
      g2d - the graphics context
    • fillRect

      void fillRect(int x, int y, int width, int height, Paint paint)
      Fill a rectangle with the given paint.
      Parameters:
      x - the x coordinate
      y - the y coordinate
      width - the width of the rectangle, in image pixels
      height - the height of the rectangle, in image pixels
      paint - the fill to apply inside the rectangle
    • fillPolygon

      void fillPolygon(double[] x, double yBottom, double[] yTop, Paint paint)
      Fill a polygon with a flat bottom.
      Parameters:
      x - the x coordinates
      yBottom - the bottom y coordinate
      yTop - the top y coordinates
      paint - the paint to fill with
    • areaOutlineFlat

      static int areaOutlineFlat(double[] x, double[] yTop, int start, int end, double yBottom, int[] xDev, int[] yDev)
      Builds the closed outline of an area whose lower boundary is the graph baseline.

      Extracted from fillPolygon(double[], double, double[], Paint) so the outline can be checked without a graphics context.

      Parameters:
      x - the x coordinates
      yTop - the top y coordinates
      start - first sample index of the run, inclusive
      end - one past the last sample index, exclusive
      yBottom - the flat baseline
      xDev - destination x coordinates, at least end - start + 2 long
      yDev - destination y coordinates, same length as xDev
      Returns:
      the number of vertices in the closed outline
    • fillPolygon

      void fillPolygon(double[] x, double[] yBottom, double[] yTop, Paint paint)
      Fill a polygon with variable bottom points.
      Parameters:
      x - the x coordinates
      yBottom - the bottom y coordinates
      yTop - the top y coordinates
      paint - the paint to fill with
    • areaOutlineVariable

      static int areaOutlineVariable(double[] x, double[] yBottom, double[] yTop, int start, int end, int[] xDev, int[] yDev)
      Builds the closed outline of an area whose lower boundary is itself a plotted series, as used by stacked plots.

      Extracted from fillPolygon(double[], double[], double[], Paint) so the outline can be checked without a graphics context.

      Parameters:
      x - the x coordinates
      yBottom - the lower boundary y coordinates
      yTop - the top y coordinates
      start - first sample index of the run, inclusive
      end - one past the last sample index, exclusive
      xDev - destination x coordinates, at least 2 * (end - start) long
      yDev - destination y coordinates, same length as xDev
      Returns:
      the number of vertices in the closed outline
    • reduceVertices

      static int reduceVertices(double[] x, double[] y, int from, int to, boolean reverse, int[] xDev, int[] yDev, int c)
      Append the step-collapsed vertices of y over [start, end) into xDev/yDev, continuing from index c.

      A run of samples sharing a value is emitted as a single segment rather than as one vertex per sample, which is what gives the plots their staircase shape: a flat stretch becomes one horizontal line and each value change becomes one near-vertical line. Both the step and the smoothed renderer reduce the same way, so they always describe the same data.

      The caller owns the buffers. Continuing from an existing c lets the two boundaries of a filled area share one dedup pass, so a vertical side edge collapses into the adjacent vertex instead of contributing a redundant one.

      Parameters:
      x - the x coordinates
      y - the y coordinates to reduce
      from - first sample index of the range, inclusive
      to - one past the last sample index of the range, exclusive; the same exclusive bound in both directions
      reverse - true to walk from to - 1 down to from instead of upwards
      xDev - destination x coordinates
      yDev - destination y coordinates
      c - index to start writing at
      Returns:
      the new write index
    • runAnchorX

      static int runAnchorX(double[] x, int start)
      Leftmost column a run of samples may be drawn at, matching where the step renderer anchors the same run.

      The step renderer feeds reduceVertices(double[], double[], int, int, boolean, int[], int[], int) a doubled x array, in which every sample's x is written twice, and a y array whose trailing NaN is overwritten by the value that follows it. A run that therefore begins just after a NaN sample starts one index early, on the NaN sample's own x, so the step path's first point is drawn at that earlier column. The smoothed renderer uses one x per sample and keeps its NaNs, so without this correction its run would begin at the first valid sample instead - exactly one sample period to the right, which is visible as a gap at the start of the trace and grows with the plot's sample spacing.

      Anchoring on x[start - 1] is the same rule for every run, whether the preceding sample is the leading edge of the window or the far side of a gap, because the doubled x array maps both to the same index. When the run starts at the first sample there is no preceding sample and the run simply starts at its own column, which is at or just left of the plot area's clipped left edge, so the trace covers the whole width.

      Parameters:
      x - the sample x coordinates, one per sample
      start - first sample index of the run, inclusive, as returned by PathIterator.getNextPath()
      Returns:
      the column the run's first vertex must be drawn at
    • drawLine

      void drawLine(int x1, int y1, int x2, int y2, Paint paint, Stroke stroke)
      Draw a line with the given paint and stroke.
      Parameters:
      x1 - the starting x coordinate
      y1 - the starting y coordinate
      x2 - the ending x coordinate
      y2 - the ending y coordinate
      paint - the color or gradient the line is drawn in
      stroke - the line thickness and end decoration to draw with
    • drawPolyline

      void drawPolyline(double[] x, double[] y, Paint paint, Stroke stroke)
      Draw a polyline with the given paint and stroke.
      Parameters:
      x - the x coordinates
      y - the y coordinates, one per vertex
      paint - the color or gradient the polyline is drawn in
      stroke - the line thickness and end decoration to draw with
    • setSmoothing

      void setSmoothing(boolean smoothing)
      Selects whether plots are drawn as bezier curves or as steps.

      Off by default, which keeps the staircase rendering. When on, line plots and areas with a flat lower boundary are drawn through MonotoneSpline, which smooths only the transitions and leaves genuinely flat stretches as straight lines.

      Parameters:
      smoothing - true to draw curves instead of steps
    • isSmoothing

      boolean isSmoothing()
      Reports whether plots are drawn as bezier curves rather than as steps.
      Returns:
      true if plots are drawn as bezier curves
    • setTransitionWidth

      void setTransitionWidth(int pixels)
      Sets how much width a sub-pixel transition may borrow from the flat runs beside it.
      Parameters:
      pixels - total width for one transition, at least 2
    • drawPolylineSmooth

      void drawPolylineSmooth(double[] x, double[] y, Paint paint, Stroke stroke)
      Draw a polyline as a smoothed curve.

      Each gap-free run of samples becomes one path; a run of NaN samples is a gap in the data and is never bridged.

      Parameters:
      x - the x coordinates
      y - the y coordinates, one per vertex
      paint - the color or gradient the curve is drawn in
      stroke - the line thickness and end decoration to draw with
    • smoothedRun

      static GeneralPath smoothedRun(double[] x, double[] y, int start, int end, int[] xDev, int[] yDev, int transitionWidth)
      Builds the smoothed curve through one gap-free run of samples: the run is reduced to step-collapsed vertices, anchored and widened, and then interpolated.

      Extracted from drawPolylineSmooth(double[], double[], Paint, Stroke) and fillPolygonSmooth(double[], double, double[], Paint), which were identical up to the closing edges, so that a test can inspect the control points the renderer really emits. That has to be done here rather than on the rendered SVG, because the emitted path data is a compressed relative form whose numbers are not the control points.

      A cubic Bezier stays inside the convex hull of its four control points, so a curve that keeps both control point y values inside the band of its own two endpoints cannot leave that band. MonotoneSpline is what guarantees it: every tangent is limited to at most three times the interval's secant, which bounds a control point's displacement from its endpoint by the distance between the two endpoints.

      Parameters:
      x - the sample x coordinates, one per sample
      y - the sample y coordinates for this run
      start - first sample index of the run, inclusive
      end - one past the last sample index of the run, exclusive
      xDev - scratch buffer for the reduced vertices, at least end - start long
      yDev - scratch buffer for the reduced y coordinates, same length as xDev
      transitionWidth - most width, in pixels, to give one sub-pixel transition
      Returns:
      the curve, or null when the run reduced to fewer than two vertices and so has nothing to draw
    • fillPolygonSmooth

      void fillPolygonSmooth(double[] x, double yBottom, double[] yTop, Paint paint)
      Fill an area with a flat lower boundary, drawn as a smoothed curve.

      The outline is emitted as a single closed subpath: the smoothed upper boundary forward, then down to the baseline and back along it. One subpath is required rather than two open ones, because SVG closes each subpath implicitly and two overlapping windings under the default nonzero rule would cancel and leave a hole.

      The smoothed curve cannot rise above the baseline. It is confined to the vertical band between the two samples it joins, and every sample is at or above the baseline the graph is drawn from, so the outline cannot fold back on itself.

      Parameters:
      x - the x coordinates
      yBottom - the flat lower boundary
      yTop - the top y coordinates
      paint - the paint to fill with
    • toDouble

      private static double[] toDouble(int[] iv)
      Widens integral coordinates for the spline, which works in double precision.
      Parameters:
      iv - source coordinates, one per spline point
      Returns:
      the values widened to double
    • drawString

      void drawString(String text, int x, int y, Font font, Paint paint)
      Draw a string at the given position with the specified font and paint.
      Parameters:
      text - the text to draw
      x - the x coordinate
      y - the y coordinate
      font - the font to render the string in
      paint - the color or gradient the glyphs are filled with
    • getFontAscent

      double getFontAscent(Font font)
      Get the ascent of the given font.
      Parameters:
      font - the font whose metrics are measured
      Returns:
      the font ascent
    • getFontHeight

      double getFontHeight(Font font)
      Get the total height of the given font.
      Parameters:
      font - the font whose metrics are measured
      Returns:
      the font height (ascent + descent)
    • getStringWidth

      double getStringWidth(String text, Font font)
      Get the width of the given text in the specified font.
      Parameters:
      text - the string to measure
      font - the font to measure it in
      Returns:
      the string width
    • setAntiAliasing

      void setAntiAliasing(boolean enable)
      Enable or disable anti-aliasing.
      Parameters:
      enable - true to enable, false to disable
    • setTextAntiAliasing

      void setTextAntiAliasing(boolean enable)
      Enable or disable text anti-aliasing.
      Parameters:
      enable - true to enable, false to disable
    • loadImage

      void loadImage(RrdGraphDef.ImageSource imageSource, int x, int y, int w, int h) throws IOException
      Load and draw an image from the given source.
      Parameters:
      imageSource - the image source
      x - the x coordinate
      y - the y coordinate
      w - the width the source is scaled to, and the subimage width
      h - the height the source is scaled to, and the subimage height
      Throws:
      IOException - if an I/O error occurs
    • dispose

      void dispose()
      Dispose of the graphics context.
    • makeImage

      void makeImage(Path path) throws IOException
      Write the image to the given path.
      Parameters:
      path - the output path
      Throws:
      IOException - if an I/O error occurs
    • makeImage

      abstract void makeImage(OutputStream os) throws IOException
      Write the image to the given output stream.
      Parameters:
      os - the output stream
      Throws:
      IOException - if an I/O error occurs
    • saveImage

      void saveImage(String path) throws IOException
      Save the image to the given file path.
      Parameters:
      path - the file path
      Throws:
      IOException - if an I/O error occurs
    • getImageBytes

      byte[] getImageBytes() throws IOException
      Get the image as a byte array.
      Returns:
      the image bytes
      Throws:
      IOException - if an I/O error occurs