java.lang.Object
net.i2p.router.web.GraphThemeColors

public final class GraphThemeColorsextends Object
The display values a graph frame draws with, overridable per theme with CSS custom properties.

Seventeen variables cover every themed part of a tile: the two plot strokes and fills, the series dot pattern, both stroke widths, the text colour, the axis rules, both grids and their dot patterns, the plot background, the edge shading, the restart rule, and the gridline a tile too small for a minor grid keeps.

Fonts are the exception and are not here. A graph reads --monospaced and --bodyfont from the console's own font stylesheet, so a second pair here could only disagree with the page it is drawn on.

The stylesheet is the canonical statement of a theme's look. The values held in this class are one fallback set - light's, because light is the console's default look - reached only when a theme's stylesheet declares nothing at all: an unknown theme name, or a layout with no stylesheet. Neither case has a theme identity to honour, so nothing here is per-theme; anything that genuinely differs between themes differs in the CSS.

A theme opts in by declaring variables in its console.css:

:root{
  --graph_plotLine1:#64c8a0;
  --graph_plotFill1:#64c8a05a;
  --graph_plotDash:1.5;
  --graph_plotLineWidthWide:2.5;
}
Anything absent keeps the built-in default, so no theme has to be edited and a typo in one declaration costs that one value rather than the whole frame.

Not every stroke width is the theme's: GraphRenderer overrides it for a grouped axis, a crowded tile and the sidebar sparkline, because those are legibility decisions about one layout rather than a look.

Why the file is read server-side

A graph image is served as <img src="/viewstat.jsp?...">, which makes the SVG an isolated document: page CSS does not reach it and page custom properties are invisible inside. Declaring the variables in the SVG itself would only let a user edit a file they cannot reach, so the theme's own stylesheet is parsed here and the resolved values are handed to the renderer. That also means getComputedStyle is not involved and the minigraph's client-side path does not apply here.

Caching

One small file per theme, parsed at most once and held in a ConcurrentHashMap, since every graph tile on a console page asks for the same palette. Themes do not change while the router runs, so there is no invalidation hook; a theme edit takes effect on the next restart, the same as any other installed resource.
  • Field Details

    • THEME_SUBDIR

      public static final String THEME_SUBDIR
      Where the console keeps its themes, relative to the router base directory.

      docs/themes/console, which is where the theme picker scans (ConfigUIHelper) and where an installed router puts them - not under webapps, which holds the deployed console war. Getting this wrong is silent: every lookup takes the "no stylesheet" path and falls back to the built-in defaults, so a theme edit appears to do nothing at all.

      See Also:
    • VAR_PLOT_DASH

      public static final String VAR_PLOT_DASH
      Dash length, in pixels, of the multi-plot dot pattern; zero asks for a solid line.
      See Also:
    • VAR_TEXT_COLOR

      public static final String VAR_TEXT_COLOR
      Text colour: axis labels, tick labels, the legend and the title.
      See Also:
    • VAR_AXIS_COLOR

      public static final String VAR_AXIS_COLOR
      The two axis rules.
      See Also:
    • VAR_GRID_MINOR

      public static final String VAR_GRID_MINOR
      The minor gridlines.
      See Also:
    • VAR_GRID_MAJOR

      public static final String VAR_GRID_MAJOR
      The major gridlines.
      See Also:
    • VAR_GRID_MINOR_DASH

      public static final String VAR_GRID_MINOR_DASH
      Dot length for the minor gridlines; zero asks for solid gridlines.
      See Also:
    • VAR_GRID_MAJOR_DASH

      public static final String VAR_GRID_MAJOR_DASH
      Dot length for the major gridlines; zero asks for solid gridlines.
      See Also:
    • VAR_BACKGROUND

      public static final String VAR_BACKGROUND
      The plot area's own background, behind the gridlines.
      See Also:
    • VAR_EDGE_SHADE

      public static final String VAR_EDGE_SHADE
      The shading band drawn along the bottom and left edges of the plot area.
      See Also:
    • VAR_RESTART_MARKER

      public static final String VAR_RESTART_MARKER
      The vertical rule and legend entry marking a router restart.
      See Also:
    • VAR_GRID_COMPACT

      public static final String VAR_GRID_COMPACT
      The gridline a tile too small for a minor grid keeps, which is not necessarily either of its two grids: the shipped themes split on which one they would rather drop.
      See Also:
    • VAR_PLOT_LINE_WIDTH

      public static final String VAR_PLOT_LINE_WIDTH
      Stroke width, in pixels, of a plot line on a tile up to WIDE_WIDTH.
      See Also:
    • VAR_PLOT_LINE_WIDTH_WIDE

      public static final String VAR_PLOT_LINE_WIDTH_WIDE
      Stroke width, in pixels, of a plot line past WIDE_WIDTH, where the series is long enough that a thinner stroke breaks up into dashes.
      See Also:
    • VAR_PLOT_LINE_WIDTH_CONDENSED

      public static final String VAR_PLOT_LINE_WIDTH_CONDENSED
      Stroke width, in pixels, of a plot line on a narrow tile carrying condensed data.

      Distinct from VAR_PLOT_LINE_WIDTH because the ordinary weight is tuned for a series with room to separate. Pack the same number of points into a narrower frame and the polyline's segments crowd together, so the weight that reads well on a roomy plot fills in on a condensed one. Themes ship 2 here against 3 for the ordinary plot.

      See Also:
    • VAR_PLOT_LINE_WIDTH_FILLED

      public static final String VAR_PLOT_LINE_WIDTH_FILLED
      Stroke width, in pixels, of the line drawn over a filled plot.

      Its own variable because it is not the plot line. VAR_PLOT_LINE_WIDTH and its siblings state how heavy a plot line is; this one states how heavy the edge over a fill is, and the two are chosen for different jobs. It used to be half the plot width, which meant a theme could not set a readable fill edge without also reweighting every line plot in the console.

      See Also:
    • VAR_PLOT_LINE_WIDTH_FILLED_WIDE

      public static final String VAR_PLOT_LINE_WIDTH_FILLED_WIDE
      Stroke width, in pixels, of the line over a filled plot on a frame past WIDE_WIDTH.

      The filled family needs its own wide variant for the same reason the plot family does: a longer series shows a thinner stroke's gaps more readily. Without it a wide filled graph was stuck on the ordinary filled weight, so raising --graph_plotLineWidthWide did nothing there - the two families read separate variables, so a theme could not widen one without widening the other.

      See Also:
    • VAR_PLOT_LINE_WIDTH_FILLED_CONDENSED

      public static final String VAR_PLOT_LINE_WIDTH_FILLED_CONDENSED
      Stroke width, in pixels, of the line over a filled plot on a narrow, condensed frame.

      The third member of the filled family, matching the plot family's plain, wide and condensed. Without it the filled edge had only one weight, so a narrow filled graph drew the same edge as a roomy one - which is the crowding the condensed slot exists to answer, just on the filled path where it had no slot to answer it in.

      See Also:
    • WIDE_WIDTH

      public static final int WIDE_WIDTH
      Frame width, in pixels, past which VAR_PLOT_LINE_WIDTH_WIDE replaces VAR_PLOT_LINE_WIDTH.

      A layout constant rather than a theme choice: a tile is drawn wider when the console has room for it, and a longer series shows a thinner stroke's gaps more readily, so the two are the same decision seen from either end.

      See Also:
    • CONDENSED_WIDTH

      public static final int CONDENSED_WIDTH
      Frame width, in pixels, at or below which a condensed plot takes VAR_PLOT_LINE_WIDTH_CONDENSED.

      A layout constant, like WIDE_WIDTH: the question is whether the points have room to separate, which is a property of the frame rather than of the theme.

      See Also:
    • VAR_PLOT_LINE_PREFIX

      static final String VAR_PLOT_LINE_PREFIX
      Prefix of the per-plot stroke variables; --graph_plotLine1, --graph_plotLine2.
      See Also:
    • VAR_PLOT_FILL_PREFIX

      static final String VAR_PLOT_FILL_PREFIX
      Prefix of the per-plot fill variables; --graph_plotFill1, --graph_plotFill2.
      See Also:
    • PLOTS

      public static final int PLOTS
      Plots per frame. Two by contract: see GraphGroups.MAX_SERIES.
      See Also:
    • maxCacheAgeMs

      static long maxCacheAgeMs
      How long a parse may be reused even when the timestamp looks unchanged, in ms.

      The timestamp check is what normally keeps this current, and it means an edit is visible on the very next page load. This interval is the fallback for a filesystem that does not maintain last-modified reliably - a network mount, some container overlays, or a coarse timestamp that hides two saves in the same second. Re-reading on a timer as well costs one small file read per interval, which is nothing next to rendering the graph itself.

      Not a static final so tests can shorten it instead of sleeping.

  • Method Details

    • lineColor

      public static Color lineColor(File themeDir, String theme, int plot)
      The stroke colour for a plot on a frame.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      plot - the plot ordinal, 0 for the first line and 1 for the second
      Returns:
      the colour, never null; falls back to the built-in value
    • lineValueShade

      public static Color[] lineValueShade(File themeDir, String theme, int plot)
      The stops that shade plot lines by their value, or null when lines are drawn flat.

      A plot line's declaration is read for this as well as for lineColor(File, String, int), so a theme opts in by naming two or more colours where it used to name one:

        --graph_plotLine1:#2ec23e40 #f0000008 #d0000008;
      

      The line is then drawn with a vertical gradient across the plot area, so the colour at a point is the colour for the value at that point - height is the value. The declared single colour still does its other jobs: it is the legend swatch, and it is what is drawn when the plot area is too short to span.

      Read per plot, so the two lines on one axis are shaded independently like every other plot colour. A theme can shade one line by value and leave the other flat.

      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      plot - 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
    • pathColor

      public static Color pathColor(File themeDir, String theme, int plot)
      The fill colour for a plot on a frame.

      A linear-gradient() declaration has no single colour, so its first stop is reported here: that is the ink the fill is made of. pathPaint(File, String, int, int) returns the whole wash.

      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      plot - the plot ordinal, 0 for the first path and 1 for the second
      Returns:
      the colour, never null; falls back to the built-in value
    • pathPaint

      public static Paint pathPaint(File themeDir, String theme, int plot, int frameHeight)
      The fill for a plot as something to paint with: a colour, or a vertical gradient.

      A gradient needs a length to span, and the area under a series is a vertical wash, so the frame's height is the caller's to supply. Only the CSS default direction - top to bottom, which is what the minigraph's own fill variables use - is painted; a stated direction this class cannot honour is treated as no opinion rather than a guess, and the fill comes out as its ink.

      Two stops are painted as a GradientPaint and three or more as a LinearGradientPaint, which is the only one of the two that holds an arbitrary number. Either way the stops are spread evenly down the span, so a third stop lands a third of the way down rather than wherever the declaration happened to say.

      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      plot - the plot ordinal, 0 for the first path and 1 for the second
      frameHeight - the height of the frame in pixels, which a gradient spans
      Returns:
      the fill paint, never null; falls back to the built-in colour
    • dashLength

      public static float dashLength(File themeDir, String theme)
      The dot ink length for the pattern that distinguishes the second plot from the first.

      --graph_plotDash takes either a bare length or a CSS dash pair:

        --graph_plotDash:1        a 1px dot, gap derived from the line width
        --graph_plotDash:1 3      a 1px dot followed by 3px of space
        --graph_plotDash:1,3      the same, for a comma-separated habit
        --graph_plotDash:0        no pattern at all: a solid line
        --graph_plotDash:0 3      the same; a gap needs a dot to follow it
      
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the dot length in pixels, or zero when the stylesheet asked for a solid line
    • dashGap

      public static float dashGap(File themeDir, String theme)
      The space after each dot, as stated by the theme, or zero when the renderer should derive it from the line width.

      A stated value is not a promise: RrdGraphConstants raises anything too tight to keep the dots apart, because with round caps each dot lays down dot + width of ink and a gap at or below the width merges them into a solid line. Reporting the raw value keeps this class a plain reader of the stylesheet.

      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the stated gap in pixels, or zero to derive one
    • textColor

      public static Color textColor(File themeDir, String theme)
      The text colour: axis labels, tick labels, the legend and the title.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • axisColor

      public static Color axisColor(File themeDir, String theme)
      The axis rule colour.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • gridMinorColor

      public static Color gridMinorColor(File themeDir, String theme)
      The minor gridline colour.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • gridMajorColor

      public static Color gridMajorColor(File themeDir, String theme)
      The major gridline colour.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • gridMinorDash

      public static float gridMinorDash(File themeDir, String theme)
      Dot length for the minor gridlines, or zero for solid ones.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the dot length in pixels
    • gridMinorDashGap

      public static float gridMinorDashGap(File themeDir, String theme)
      The space after each minor gridline dot, or zero to derive it from the stroke width.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the stated gap in pixels, or zero to derive one
    • gridMajorDash

      public static float gridMajorDash(File themeDir, String theme)
      Dot length for the major gridlines, or zero for solid ones.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the dot length in pixels
    • gridMajorDashGap

      public static float gridMajorDashGap(File themeDir, String theme)
      The space after each major gridline dot, or zero to derive it.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the stated gap in pixels, or zero to derive one
    • backgroundColor

      public static Color backgroundColor(File themeDir, String theme)
      The plot area's own background: the rectangle behind the gridlines.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • edgeShadeColor

      public static Color edgeShadeColor(File themeDir, String theme)
      The shading band along the bottom and left edges of the plot area.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null; fully transparent where a theme drops the band
    • restartMarkerColor

      public static Color restartMarkerColor(File themeDir, String theme)
      The vertical rule and legend entry marking a router restart.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • compactGridColor

      public static Color compactGridColor(File themeDir, String theme)
      The gridline a tile too small for a minor grid keeps in place of the minor grid.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the colour, never null
    • plotLineWidth

      public static float plotLineWidth(File themeDir, String theme)
      Stroke width of a plot line on a tile no wider than WIDE_WIDTH.

      A renderer decision outranks this one - see GraphRenderer for the dense-tile and sparkline widths - so a theme sets the weight of an ordinary plot, not every plot.

      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the width in pixels, never zero or negative
    • plotLineWidthWide

      public static float plotLineWidthWide(File themeDir, String theme)
      Stroke width of a plot line on a tile wider than WIDE_WIDTH.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the width in pixels, never zero or negative
      See Also:
    • plotLineWidthCondensed

      public static float plotLineWidthCondensed(File themeDir, String theme)
      Stroke width of a plot line on a tile no wider than CONDENSED_WIDTH that carries condensed data.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the width in pixels, never zero or negative
      See Also:
    • plotLineWidthFilled

      public static float plotLineWidthFilled(File themeDir, String theme)
      Stroke width of the line drawn over a filled plot.

      Independent of plotLineWidth(File, String) and its siblings: this is an edge on a fill, not a plot line, and the two are set for different reasons.

      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the width in pixels, never zero or negative
      See Also:
    • plotLineWidthFilledWide

      public static float plotLineWidthFilledWide(File themeDir, String theme)
      Stroke width of the line over a filled plot on a frame wider than WIDE_WIDTH.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the width in pixels, never zero or negative
      See Also:
    • plotLineWidthFilledCondensed

      public static float plotLineWidthFilledCondensed(File themeDir, String theme)
      Stroke width of the line over a filled plot on a narrow, condensed frame.
      Parameters:
      themeDir - the directory holding <theme>/console.css trees
      theme - the console theme name
      Returns:
      the width in pixels, never zero or negative
      See Also:
    • installedThemeDir

      public static File installedThemeDir()
      The directory the console is installed into, taken from the running context.
      Returns:
      the theme directory, or null when there is no context (unit tests, shutdown)
    • clearCache

      static void clearCache()
      Forget every parsed theme.

      Not needed in normal operation: both the timestamp and the interval already pick up edits. This exists so a caller that has just rewritten a stylesheet can force a re-read without waiting.