Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static final classFont family configuration for a specific language.private static final classResolved font family names for a render pass.(package private) static final classImmutable configuration for a single graph render pass.private static final classExplicit metadata for stat rendering behavior.Field Summary
FieldsModifier and TypeFieldDescriptionprivate final I2PAppContextThe app context.private final GraphListenerSource of the stat data being graphed.private final LogLogger for graph rendering.private static final ColorThe arrow on an axis break, which no theme draws.private static final doubleHeadroom left under the data minimum, as a fraction of the window's data range.private static final PatternMatches the start of a camel case word in a stat name.private static final intPeriods at or above which a narrow unsmoothed tile counts as condensed.private static final floatStroke width for a tile carrying enough periods that a heavier line would merge them.private static final StringTheme assumed when none is configured.private static final Map<String, GraphRenderer.FontConfig> Per-language font configuration.Font families available on this system.private static final ColorThe plot border, which no theme draws; the gridlines carry the frame instead.private static final GraphicsEnvironmentGraphics environment holding the available fonts.private static final ColorMinor grid colour for a tile with no room for a grid, which hides it outright.private static final StrokeThe stroke drawing the graph grid lines.private static final booleanWhether we are running on Windows.private static final ThreadLocal<SimpleDateFormat> SimpleDateFormats are expensive to construct and not thread-safe, so cache one per thread for each timezone variant instead of allocating new ones on everyrender(OutputStream)call.private static final floatNarrowest stroke a theme may ask for; below this a plot disappears.private static final StringWhether to render every series as a filled path under a thin line.private static final StringConfig key for the legend font.private static final StringConfig key for the unit label font.private static final StringConfig key for the title font.private static final StringConfig key for line smoothing.private static final StringConfig key for the console theme.private static final StringKeep the historical zero-floored y-axis even when the window's data lives in a narrow band far from zero.private static final intDefault legend font size.private static final intDefault unit label font size.private static final intDefault title font size.private static final ColorFill for the wide, chrome-less sidebar sparkline.private static final floatStroke width for the sidebar sparkline.private static final Map<String, GraphRenderer.StatMeta> Known stat metadata — add entries for new stats instead of extending heuristics.Post-processing replacements applied after prefix rules.Title replacement rules, ordered by key length descending (longest first) so that longer prefixes are matched before their shorter ancestors.private static final ColorNothing drawn: the canvas margin, the chrome-less sidebar tiles' axes and the grid a tile too small for one cannot show anything against whatever the page puts behind.private static final ThreadLocal<SimpleDateFormat> Per-thread UTC date format for the graph labels.Constructor Summary
ConstructorsConstructorDescriptionGraphRenderer(I2PAppContext ctx, GraphListener lsnr) Binds a renderer to the listener whose RRD it draws.Method Summary
Modifier and TypeMethodDescriptionprivate StringTranslate a string.private StringTranslate a string with a parameter.private static voidaccumulateRange(GraphRenderer.GraphRenderConfig cfg, double[] values) Fold one series into the running range, ignoring missing and infinite points.private voidaddSummaryPrints(RrdGraphDef def, String plotName, String suffix, String numberFormat) Emit the max/min/avg/now legend block for one series.private static voidHand the theme's dot pattern to the renderer.private static voidApply the theme's colours to the graph definition.(package private) static doubleaxisFloor(double dataMin, double dataMax, boolean forceZero) Choose the y-axis floor for a window, so a series that lives in a narrow band far from zero is not flattened against a zero baseline.private GraphRenderer.GraphRenderConfigbuildRenderConfig(int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts) Builds the immutable render configuration from parameters and context.private GraphRenderer.GraphRenderConfigbuildRenderConfig(int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts, boolean allLines, boolean meta) Assemble the render settings for one graph.private voidDraw the primary as a filled area, which is how a single-value graph has always been rendered.private voidDerives the unit base and decimal places for the stat.private voidAdds the comments and signature text to the graph.private voidAdds the stat's data sources to the graph.private voidCaps how many points are plotted so that each has room to be drawn.private voidDeclare and plot every extra series of a combined graph.private voidSets the graph's fonts from the config.private voidSets the grid style and rendering options.private voidAdds the legend lines to the graph.private voidAdds the router restart markers to the graph.private voidconfigureTimeZone(RrdGraphDef def, boolean useUtc) Sets the graph's time zone.private voidSets the graph title and vertical label.private static StringderiveTitle(String name) Derive a human-readable graph title from the rate stat name.(package private) static Color[]extraLineShadeForTest(String theme, int extraIndex) The value-shade stops an extra series would be drawn with.private static intextraPlot(int extraIndex) Which plot slot an extra series occupies.(package private) static intextraPlotForTest(int extraIndex) Which plot slot an extra series occupies.(package private) static ColorextraSeriesColor(String theme, boolean allLines, int extraIndex) The colour for an extra series: plot ordinal 1, i.e.private double[]fetchWindow(GraphListener lsnr, String dsName, long startSec, long endSec) Read one datasource over the render window.private floatStroke width for the line overlaid on a filled plot.private static StrokegridStroke(float dot, float gap) The stroke gridlines are drawn with, from a theme's stated dot and gap.(package private) static booleanWhether a tile is narrow and carrying condensed data, and so takes the theme's condensed plot width.private static booleanWhether a tile is carrying enough periods that a thicker line would merge them.private static booleanWhether a frame is the wide, chrome-less sidebar sparkline.private floatStroke width for a plotted series.private static ColorpaletteColor(String theme, int plot) The stroke colour for a plot on a frame, from the theme's CSS variables or the built-in palette.(package private) static ColorpaletteColorForTest(String theme) Package-visible accessor so tests can compare a series against the primary.private static Color[]plotLineShade(String theme, int plot) The stops that shade one plot line by its value, or null for a flat line.private static PaintplotPathPaint(String theme, int plot, int frameHeight) The fill for a plot as something to paint with: the theme's colour, or a gradient between two of them.voidrender(OutputStream out) Renders the whole archive at the default size, with legend, grid and title.voidrender(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit) Single graph, drawn as a filled area under a line.voidrender(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts) Render a graph with any number of extra series overlaid.voidrender(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts, boolean meta) Asrender(OutputStream), but optionally emitting the plot metadata rather than the image.voidrender(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, GraphListener lsnr2, String titleOverride, boolean showRestarts) Single or two-data-source graph.voidrender(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, GraphListener lsnr2, String titleOverride, boolean showRestarts, boolean meta) Asrender(OutputStream), but optionally emitting the plot metadata rather than the image.private voidrenderGraph(RrdGraphDef def, OutputStream out, GraphRenderer.GraphRenderConfig cfg) Renders the graph and writes the image.booleanrenderGroup(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int end, boolean showCredit, GraphListener primary, List<GraphListener> extras, String titleOverride, boolean showRestarts) Render a combined graph of several stats as overlaid lines.voidrenderLines(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts) Render a graph with every series, including the primary, drawn as a line.voidrenderLines(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts, boolean meta) AsrenderLines(OutputStream, int, int, boolean, boolean, boolean, boolean, int, int, boolean, List, String, boolean), but optionally emitting the plot metadata rather than the image.private voidMeasure the window's data range soaxisFloor(double, double, boolean)has something to scale.private static GraphRenderer.FontNamesselectFontNames(String lang) Per-language font family selection for graph rendering.private static booleanWhether rrd4j scales the value axis itself, ignoring a floor set on the definition.
Field Details
_log
Logger for graph rendering._listener
Source of the stat data being graphed._context
The app context.PROP_THEME_NAME
Config key for the console theme.- See Also:
DEFAULT_THEME
Theme assumed when none is configured.- See Also:
TRANSPARENT
Nothing drawn: the canvas margin, the chrome-less sidebar tiles' axes and the grid a tile too small for one cannot show anything against whatever the page puts behind.GRID_COLOR_HIDDEN
Minor grid colour for a tile with no room for a grid, which hides it outright.FRAME_COLOR
The plot border, which no theme draws; the gridlines carry the frame instead.SPARKLINE_AREA_COLOR
Fill for the wide, chrome-less sidebar sparkline.Neutral on purpose: that tile carries no legend and no labels, so its colour must not read as a first plot from the themed palette.
MIN_LINE_WIDTH
private static final float MIN_LINE_WIDTHNarrowest stroke a theme may ask for; below this a plot disappears.- See Also:
SPARKLINE_LINE_WIDTH
private static final float SPARKLINE_LINE_WIDTHStroke width for the sidebar sparkline.A legibility decision: at 250x50 with nothing else drawn, a hairline nearly vanishes. See
lineWidth(GraphRenderer.GraphRenderConfig).- See Also:
CROWDED_LINE_WIDTH
private static final float CROWDED_LINE_WIDTHStroke width for a tile carrying enough periods that a heavier line would merge them.A legibility decision, and the reason a theme's width is not obeyed unconditionally. See
lineWidth(GraphRenderer.GraphRenderConfig).- See Also:
PROP_FILL
Whether to render every series as a filled path under a thin line. @since 0.9.71+.- See Also:
ARROW_COLOR
The arrow on an axis break, which no theme draws.Already rrd4j's own default, so setting it is stating the intent rather than changing anything - which is the point: it used to be set for two of the four themes only, implying the arrow was a dark-theme decision when it never was.
IS_WIN
private static final boolean IS_WINWhether we are running on Windows.PROP_SMOOTH
PROP_ZERO_BASE
Keep the historical zero-floored y-axis even when the window's data lives in a narrow band far from zero. Off by default, so the data-driven floor applies.- See Also:
PROP_FONT_MONO
Config key for the unit label font.- See Also:
PROP_FONT_LEGEND
Config key for the legend font.- See Also:
PROP_FONT_TITLE
Config key for the title font.- See Also:
SIZE_MONO
SIZE_LEGEND
SIZE_TITLE
AXIS_FLOOR_MARGIN
private static final double AXIS_FLOOR_MARGINHeadroom left under the data minimum, as a fraction of the window's data range.Proportional rather than absolute, so it behaves the same for a rate that hovers around 0.05 and one that sits at 100,000.
- See Also:
GRID_STROKE
The stroke drawing the graph grid lines.CAMEL_CASE_PATTERN
Matches the start of a camel case word in a stat name.LOCAL_DATE_FMT
SimpleDateFormats are expensive to construct and not thread-safe, so cache one per thread for each timezone variant instead of allocating new ones on everyrender(OutputStream)call.UTC_DATE_FMT
Per-thread UTC date format for the graph labels.GE
Graphics environment holding the available fonts.FONTLIST
STAT_META
Known stat metadata — add entries for new stats instead of extending heuristics.CONDENSED_PERIODS
private static final int CONDENSED_PERIODSPeriods at or above which a narrow unsmoothed tile counts as condensed.The graphs page's narrow variant packs a few hundred minutes into a sub-400px frame; well below this a narrow tile has room for its points to separate.
- See Also:
TITLE_REPLACEMENTS
TITLE_POST_REPLACEMENTS
FONT_CONFIGS
Per-language font configuration. Legend uses title candidates.
Constructor Details
GraphRenderer
Binds a renderer to the listener whose RRD it draws.- Parameters:
ctx- the app context, for console properties, logging and translationslsnr- the listener supplying the RRD, the rate and the router clock
Method Details
filledLineWidth
Stroke width for the line overlaid on a filled plot.The line drawn over a filled area is not the plot line, so
--graph_plotLineWidthand its plain, wide and condensed siblings do not apply to it; it has--graph_plotLineWidthFilled. It used to be half the plot width, which tied an edge that exists to keep the fill readable to a weight chosen for a line that is not being drawn.Reads only the filled family. An edge on a fill does not take its weight from the plot line it sits on - letting it track that meant the two could never be set apart - but it does answer the same three questions the plot line does, through its own plain, wide and condensed variables. The width test is shared with
lineWidth(GraphRenderer.GraphRenderConfig)so the two families switch at the same frame width; the values are not shared.- Parameters:
cfg- the render configuration- Returns:
- stroke width in pixels
- See Also:
render
Renders the whole archive at the default size, with legend, grid and title.- Parameters:
out- where the SVG is written- Throws:
IOException- if the graph cannot be produced
render
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit) throws IOException Single graph, drawn as a filled area under a line.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature line- Throws:
IOException- if the graph cannot be produced
render
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, GraphListener lsnr2, String titleOverride, boolean showRestarts) throws IOException Single or two-data-source graph.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature linelsnr2- 2nd data source to plot on same graph, or null. Not recommended for events.titleOverride- If non-null, overrides the titleshowRestarts- if true, draw the vertical restart lines and "Router restarted" label- Throws:
IOException- if the graph cannot be produced
render
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, GraphListener lsnr2, String titleOverride, boolean showRestarts, boolean meta) throws IOException Asrender(OutputStream), but optionally emitting the plot metadata rather than the image.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature linelsnr2- 2nd data source to plot on same graph, or null. Not recommended for events.titleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restartmeta- true to write the geometry and series as JSON instead of drawing- Throws:
IOException- if the graph cannot be produced
render
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts) throws IOException Render a graph with any number of extra series overlaid. All series share one axis, so they must measure the same thing; seeGraphGroups. The primary is drawn first and supplies the axis range; each extra is drawn as a line, never an area, and is named in the legend.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature lineextras- extra series in legend order, or null or empty for nonetitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restart- Throws:
IOException- if the graph cannot be produced
render
public void render(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts, boolean meta) throws IOException Asrender(OutputStream), but optionally emitting the plot metadata rather than the image.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature lineextras- extra series in legend order, or null or empty for nonetitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restartmeta- true to write the geometry and series as JSON instead of drawing- Throws:
IOException- if the graph cannot be produced
renderLines
public void renderLines(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts) throws IOException Render a graph with every series, including the primary, drawn as a line.Used for combined graphs. Filling the primary would put a solid block behind the other series and hide any that cross it, which defeats the point of overlaying them.
- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature lineextras- extra series in legend order, or null or empty for nonetitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restart- Throws:
IOException- if the graph cannot be produced- See Also:
renderLines
public void renderLines(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts, boolean meta) throws IOException AsrenderLines(OutputStream, int, int, boolean, boolean, boolean, boolean, int, int, boolean, List, String, boolean), but optionally emitting the plot metadata rather than the image.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before nowshowCredit- true to show the signature lineextras- extra series in legend order, or null or empty for nonetitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restartmeta- true to write the geometry and series as JSON instead of drawing- Throws:
IOException- if the graph cannot be produced
buildRenderConfig
private GraphRenderer.GraphRenderConfig buildRenderConfig(int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts) Builds the immutable render configuration from parameters and context.- Parameters:
width- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before now; ignored unless positiveshowCredit- true to show the signature lineextras- extra series in legend order, or null or empty for nonetitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restart- Returns:
- the assembled configuration, never null
buildRenderConfig
private GraphRenderer.GraphRenderConfig buildRenderConfig(int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int endp, boolean showCredit, List<GraphListener> extras, String titleOverride, boolean showRestarts, boolean allLines, boolean meta) Assemble the render settings for one graph.- Parameters:
width- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- true to plot the event count rather than the statperiodCount- periods in the window; zero or more than the archive draws all of themendp- number of periods before now; ignored unless positiveshowCredit- true to show the signature lineextras- extra series in legend order, or null or empty for nonetitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restartallLines- draw the primary as a line rather than a filled areameta- true to write the geometry and series as JSON instead of drawing- Returns:
- the assembled configuration, never null
configureDownsampler
Caps how many points are plotted so that each has room to be drawn.Uncapped, the renderer is handed roughly one point per pixel, and once points are closer together than a pixel a value change falls inside a single column with no width to draw across. The cap is derived from the width instead, and only applied when smoothing is on, so the default rendering is untouched.
- Parameters:
def- the graph definitioncfg- the render configuration
configureTimeZone
Sets the graph's time zone.- Parameters:
def- the graph definitionuseUtc- whether to use UTC
configureFonts
Sets the graph's fonts from the config.- Parameters:
def- the graph definitioncfg- the render configuration
configureBaseAndDecimals
Derives the unit base and decimal places for the stat.- Parameters:
cfg- the render configuration to update
axisFloor
static double axisFloor(double dataMin, double dataMax, boolean forceZero) Choose the y-axis floor for a window, so a series that lives in a narrow band far from zero is not flattened against a zero baseline.Only the floor is ever returned. The ceiling and the tick rounding are left to rrd4j, which snaps the floor down to cover any value that does not fit and otherwise rounds both ends to its own idea of a sensible label value.
Pure, so the decision can be unit tested without a router, an RRD or a clock.
- Parameters:
dataMin- smallest finite value in the window, NaN if nonedataMax- largest finite value in the window, NaN if noneforceZero- true to keep the historical zero-floored axis- Returns:
- the floor to pass to RrdGraphDef.setMinValue
resolveAxisRange
Measure the window's data range soaxisFloor(double, double, boolean)has something to scale.The values cannot be taken off the definition before the graph is built: rrd4j computes them internally, while rendering. So this reads the same window from the listener's already-open RRD - the read
RrdGraphperforms a moment later anyway - and reduces it in one pass.Skipped entirely when a floor could not take effect anyway:
forceZeroasks for the historical axis, andusesMrtgScaling(GraphRenderer.GraphRenderConfig)means rrd4j rebuilds the range itself.- Parameters:
cfg- the render configuration, whose range fields are filled in
fetchWindow
Read one datasource over the render window.- Parameters:
lsnr- the listener holding the RRD, or nulldsName- datasource to readstartSec- window start, in secondsendSec- window end, in seconds- Returns:
- the archived values, or null if they could not be read
accumulateRange
Fold one series into the running range, ignoring missing and infinite points.One pass over a primitive array: no boxing, no sorting, nothing allocated per point.
- Parameters:
cfg- the render configuration, updated in placevalues- archived values, or null if unavailable
usesMrtgScaling
Whether rrd4j scales the value axis itself, ignoring a floor set on the definition.With
RrdGraphDef.setAltYMrtg(boolean)on, rrd4j's MRTG range expansion rebuilds the y range from the maximum alone and pins the floor at zero, so a floor set on the definition cannot move it. Small graphs turn the option off, which is why they are the ones the data-driven floor helps.Mirrors the decision in
configureGridAndRendering(RrdGraphDef, GraphRenderer.GraphRenderConfig)so the two cannot drift apart, and is only read afterconfigureBaseAndDecimals(GraphRenderer.GraphRenderConfig)has filled innoDecimalPlace.- Parameters:
cfg- the render configuration- Returns:
- true if rrd4j overwrites the range, so
axisFloor(double, double, boolean)cannot take effect
configureTitle
Sets the graph title and vertical label.- Parameters:
def- the graph definitioncfg- the render configuration
configureDataSources
private void configureDataSources(RrdGraphDef def, GraphRenderer.GraphRenderConfig cfg) throws IOException Adds the stat's data sources to the graph.- Parameters:
def- the graph definitioncfg- the render configuration- Throws:
IOException- if the rrd file cannot be read
configureArea
Draw the primary as a filled area, which is how a single-value graph has always been rendered.The one exception is the wide, chrome-less sparkline used in the sidebar, which stays a neutral grey: it is drawn small and unlabelled, so it takes a colour from neither the theme nor the plot palette and must not imply a second series.
- Parameters:
def- the graph definition being builtcfg- render configuration; the sparkline special case keys off its width, height and hide flags
configureLegend
Adds the legend lines to the graph.- Parameters:
def- the graph definitioncfg- the render configuration
renderGroup
public boolean renderGroup(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, int end, boolean showCredit, GraphListener primary, List<GraphListener> extras, String titleOverride, boolean showRestarts) throws IOException Render a combined graph of several stats as overlaid lines.- Parameters:
out- where the SVG is writtenwidth- image width in pixelsheight- image height in pixelshideLegend- true to omit the legendhideGrid- true to omit the grid lineshideTitle- true to omit the derived titleshowEvents- unused; event mode is not supported for combined graphsperiodCount- periods in the window; zero or more than the archive draws all of themend- number of periods before nowshowCredit- true to show the signature lineprimary- the series drawn first; also supplies the axis rangeextras- the remaining series, in legend ordertitleOverride- title to draw, or null for the primary stat descriptionshowRestarts- true to draw a vertical line per router restart- Returns:
- true if a graph was written
- Throws:
IOException- if the graph cannot be produced
configureExtraDataSources
private void configureExtraDataSources(RrdGraphDef def, GraphRenderer.GraphRenderConfig cfg) throws IOException Declare and plot every extra series of a combined graph.Each member becomes its own datasource drawn as a line, never an area, with a per-series colour and its description in the legend. Areas are reserved for the primary series: filling several overlaid series hides whichever one is behind.
The max/min/avg/now summary block is emitted for the first extra series only when there is exactly one, matching the long-standing combined-bandwidth graph. With more, four legend lines per series would bury the plot.
- Parameters:
def- the graph definition being builtcfg- render configuration; extras, theme, fillSeries and numberFormat drive the series rendering- Throws:
IOException- if a listener's datasource names cannot be read
addSummaryPrints
Emit the max/min/avg/now legend block for one series.- Parameters:
def- the graph definition being builtplotName- the series' datasource name to summarizesuffix- appended to the min/max/avg/last ids so they do not collide with the primary'snumberFormat- the rrd format string for each printed value
lineWidth
Stroke width for a plotted series.Three cases are decided here rather than by the theme, because each is a fact about one layout rather than a look the console wants:
- Grouped graphs stack up to six lines on one axis and are drawn thinner so they stay separable and the dense case does not fill in.
- The sidebar sparkline is drawn thick because it is small and unlabelled, and a hairline nearly vanishes at that size.
- A tile carrying many periods is drawn thinner for the same reason the grouped case is: the series is crowded.
Everything else - an ordinary plot, including one carrying a group of series - takes its weight from the theme. Grouping used to short-circuit to a hard-coded
ALL_LINES_WIDTHof 1.5 before any variable was read, which meant--graph_plotLineWidthand--graph_plotLineWidthWidenever reached a combined graph and a theme had no way to weight one. The theme now governs, and the constants left here are the cases where a layout reason, not taste, sets the weight: a bare sparkline that a hairline would erase, and a tile crowded enough that any weight merges the series.- Parameters:
cfg- the render configuration- Returns:
- stroke width in pixels
isSparkline
Whether a frame is the wide, chrome-less sidebar sparkline.Identified by its exact size with every other element hidden, which is the only combination the console requests and the only one drawn unlabelled.
- Parameters:
cfg- the render configuration to classify- Returns:
- true if the frame is the 250x50 sparkline with title, legend and grid all hidden
isCrowdedTile
Whether a tile is carrying enough periods that a thicker line would merge them.A wide tile keeps the thicker line because it has room to show the crowding; the narrow form is what needs thinning.
- Parameters:
cfg- the render configuration to classify- Returns:
- true at 720 or more periods, or 480 or more on a tile 600 pixels wide or less
isCondensedTile
Whether a tile is narrow and carrying condensed data, and so takes the theme's condensed plot width.Separate from
isCrowdedTile(GraphRenderer.GraphRenderConfig)because the two answer different questions. A crowded tile has enough periods that any width merges the series, so it takes a fixed hairline. A condensed tile is merely narrow for the number of periods it carries, so the weight stays the theme's to set - thinner than an ordinary plot, but not a hairline.Deliberately independent of smoothing. Smoothing used to exempt a tile from this, because an unsmoothed polyline crowds where a rounded curve does not - but smoothing is itself only a default, and a stepped series is what a user asking for step gets. Gating on it meant the same tile was drawn at two different weights depending on a setting whose value nobody reading the graph could see.
- Parameters:
cfg- the render configuration- Returns:
- true if a narrow, period-dense tile takes the theme's condensed plot width
extraSeriesColor
The colour for an extra series: plot ordinal 1, i.e. the theme's second hue.A frame carries at most two plots (
GraphGroups.MAX_SERIES), so "which colour is the extra series" has exactly one answer and it is a themeable one. The two-series bandwidth graph predates grouping and keeps the exact colour it always shipped with.- Parameters:
theme- console theme nameallLines- whether the primary is drawn as a line rather than a filled areaextraIndex- zero-based position among the extra series- Returns:
- the colour for that series
extraPlot
private static int extraPlot(int extraIndex) Which plot slot an extra series occupies.The primary always takes slot 0, so extras start at 1 and, since a frame carries at most two plots, every extra past the first clamps onto slot 1.
Every per-plot lookup for an extra series goes through here. Its stroke colour, its fill and its value shading. They used to compute the ordinal separately and one of them disagreed, which gave a series one plot's colour and another plot's gradient.
- Parameters:
extraIndex- zero-based position among the extra series- Returns:
- the plot ordinal, never less than 1
extraPlotForTest
static int extraPlotForTest(int extraIndex) Which plot slot an extra series occupies. Package-visible so a test can pin it.- Parameters:
extraIndex- zero-based position among the extra series- Returns:
- the plot ordinal, never less than 1
extraLineShadeForTest
The value-shade stops an extra series would be drawn with.Exposed so a test can check that the extra series asks for its own plot's stops rather than a neighbouring plot's. Comparing colours could not catch that, because every shipped theme draws both plots flat and a flat plot has no stops to compare.
- Parameters:
theme- console theme nameextraIndex- zero-based position among the extra series- Returns:
- bottom-to-top stops, or null when that plot is flat
paletteColor
plotPathPaint
The fill for a plot as something to paint with: the theme's colour, or a gradient between two of them.- Parameters:
theme- console theme nameplot- the plot ordinal; a frame carries at most twoframeHeight- the frame's height in pixels, which a gradient spans- Returns:
- the paint, never null
plotLineShade
The stops that shade one plot line by its value, or null for a flat line.Passed per line rather than set once on the definition, so two plots on one axis are shaded independently - the same independence their colours have.
- Parameters:
theme- the console theme nameplot- the plot ordinal, 0 for the first line and 1 for the second- Returns:
- bottom-to-top stops, or null when the theme named one colour or fewer
paletteColorForTest
configureRestartMarkers
Adds the router restart markers to the graph.- Parameters:
def- the graph definitioncfg- the render configuration
configureCommentsAndSignature
Adds the comments and signature text to the graph.- Parameters:
def- the graph definitioncfg- the render configuration
configureGridAndRendering
Sets the grid style and rendering options.- Parameters:
def- the graph definitioncfg- the render configuration
renderGraph
private void renderGraph(RrdGraphDef def, OutputStream out, GraphRenderer.GraphRenderConfig cfg) throws IOException Renders the graph and writes the image.- Parameters:
def- the graph definitionout- where the image is writtencfg- the render configuration- Throws:
IOException- if the image cannot be written
applyDash
Hand the theme's dot pattern to the renderer.A theme may state only the dot length, in which case jrobin derives the gap from the stroke width. When it states a gap too, that value is used unless it would merge the dots, which is decided in
RrdGraphConstants.minimumDashGap. A dot length of zero, from--graph_plotDash:0, asks for a solid line and leaves no gap to set.- Parameters:
def- the graph definition being builtcfg- render configuration; its theme selects the dot and gap values
applyTheme
Apply the theme's colours to the graph definition.Every one of them is the theme's to state in its own
console.css; this class holds only the fallbacks for a stylesheet that declares nothing, so a frame reads as part of the page it is drawn on.- Parameters:
def- the graph definition being builtcfg- render configuration; its theme and frame size select the colours
gridStroke
The stroke gridlines are drawn with, from a theme's stated dot and gap.- Parameters:
dot- ink length of one dot; zero asks for solid gridlinesgap- space after the dot, or zero to derive it from the stroke width- Returns:
- a 1-pixel-wide dashed stroke, or a solid one when dot is zero
deriveTitle
Derive a human-readable graph title from the rate stat name. Pure function — no side effects — uses ordered prefix map for deterministic results.- Parameters:
name- the raw rate stat name, e.g. tunnel.buildClient- Returns:
- the display title: prefix and post replacements applied, then word-capitalized
selectFontNames
Per-language font family selection for graph rendering. Pure function — no side effects — so it is safe to call from any thread.- Parameters:
lang- the active UI language code (e.g. "en", "zh", "jp", "ko")- Returns:
- resolved mono / legend / title family names for the current platform
_t
_t