repomatic.metric_chart module¶
Draw an accumulated metric history as a standalone, themeable SVG.
Written by hand rather than through a plotting library: the output is committed, so a docs build never needs the dependency, and the file stays a few kilobytes of readable vector.
An SVG rather than a client-side canvas: GitHub strips <script> and
<canvas> from rendered Markdown, so a scripted chart is invisible to every
reader of the repository, while the third-party embeds these replace were
images that rendered there. Committing it also drops the pinned CDN artifact
and its subresource-integrity digest, which is the point of moving off a
service that died without notice.
- repomatic.metric_chart.CHART_MODES = ('absolute', 'relative')¶
Horizontal axes a chart can measure against.
absoluteshares one calendar across every curve, answering when a project gathered its following.relativestarts each curve at its own repository’s creation, which is the only origin they all share, so a project that took eight years to reach a figure another hit in two is read at a glance.Kept separate from
CHART_SCALES, which measures the vertical one: a comparison chart routinely wants both, and folding them into a single setting would make each pair of choices a new name.
- repomatic.metric_chart.CHART_SCALES = ('linear', 'logarithmic')¶
Vertical axes a chart can measure against.
linearreads a difference, and is right whenever the series are the same size.logarithmicreads a rate, and is what puts a project of 57 stars on one chart with a peer of 25,000 without flattening it onto the axis: equal slopes mean equal growth in percentage terms, whatever the counts.A count of zero has no logarithm, and every series carries one, since the day a repository was created is the only date its count is known exactly. So the bottom
LOG_ZERO_BANDof the plot is kept linear, spanning nothing but the step from zero to one. The curve then leaves the axis where the first star landed rather than beginning in mid-air or being silently dropped.
- repomatic.metric_chart.LABEL_CHAR_WIDTH = 7.6¶
Pixels a direct label’s average character occupies, for margin arithmetic.
Measured against the 13px semibold
system-uithe labels are drawn in. An SVG carries no text metrics and this generator loads no font, so the width of a label can only be estimated: erring high costs a few pixels of plot, erring low clips the name off the edge of the chart.
- repomatic.metric_chart.LOG_ZERO_BAND = 0.06¶
Fraction of a logarithmic plot’s height reserved for the zero-to-one step.
Small enough to read as a baseline rather than as a decade of its own, and large enough that a curve sitting at zero for years is visibly on the floor instead of indistinguishable from one at a count of one.
- repomatic.metric_chart.MIN_LABEL_MARGIN = 168¶
Floor on the right margin, in pixels, whatever the labels measure.
Holds the plot’s proportions steady across the charts a project draws: a single-series chart would otherwise stretch nearly to the edge and read as a different shape from the comparison beside it.
- repomatic.metric_chart.SERIES_PALETTE: tuple[tuple[str, str], ...] = (('#2a78d6', '#3987e5'), ('#eb6834', '#d95926'), ('#1baf7a', '#199e70'), ('#eda100', '#c98500'), ('#e87ba4', '#d55181'), ('#8250df', '#a371f7'), ('#0a7c8a', '#22b8cf'), ('#cf222e', '#ff7b72'), ('#5a7f10', '#8fc832'), ('#8a6240', '#c19a6b'), ('#57606a', '#9198a1'), ('#bf3989', '#e878b8'))¶
Light and dark hex pair per categorical slot, in fixed order.
Assigned positionally and never cycled: a chart declaring more series than there are slots raises rather than reusing a hue, since a repeated colour on a chart whose curves are told apart by colour is a defect the reader cannot see. Override any of them by name through
[tool.repomatic.metrics] colors.A few light-mode steps sit below 3:1 against a white surface. The direct label drawn at the end of every line is what answers that: identity is never colour alone.
- class repomatic.metric_chart.ChartSpec(output, metric='stars', mode='absolute', only=(), scale='linear', title='')[source]¶
Bases:
objectOne chart a repository asked for.
- metric: str = 'stars'¶
Which accruing metric to plot, from
METRICS.Defaults to the one that motivated the whole collector. Only a metric the store accrues can be charted: an attribute holds a single current value, which is a table cell rather than a curve.
- mode: str = 'absolute'¶
Which of
CHART_MODESmeasures the horizontal axis.
- scale: str = 'linear'¶
Which of
CHART_SCALESmeasures the vertical axis.
- classmethod from_mapping(entry)[source]¶
Build a spec from one
[[tool.repomatic.metrics.charts]]entry.- Parameters:
entry (
Mapping[str,object]) – The entry as configuration parsed it.- Return type:
- Returns:
The corresponding spec.
- Raises:
ValueError – When
outputis missing, the mode is unknown, or the named metric has no history to chart.
- class repomatic.metric_chart.ChartData(points=<factory>, colors=<factory>)[source]¶
Bases:
objectA chart’s plotted series, already grouped and ordered.
Holds what
render_chart()draws, so the renderer never touches the store and stays testable against synthetic points.
- repomatic.metric_chart.assign_colors(names, overrides=None)[source]¶
Give every series a light and dark hue.
Positional from
SERIES_PALETTEin names order, so a chart’s first curve is always the first slot, with overrides winning by name. A hue is a property of the series rather than of the chart, which is what keeps a repository plotted on two charts recognizable across both.- Parameters:
- Return type:
- Returns:
The light and dark pair of each name.
- Raises:
ValueError – When more series need a slot than the palette holds, or when an override is not a light and dark pair.
- repomatic.metric_chart.build_chart_data(grouped, spec, overrides=None)[source]¶
Select, order and colour the series one chart plots.
A forerunner rides along with the series it precedes rather than being selected on its own, and borrows that series’ hue instead of claiming a slot of its own.
- Parameters:
- Return type:
- Returns:
The chart’s points and colours.
- Raises:
ValueError – When the chart plots nothing, when two series fold onto one CSS class, or when the palette runs out.
- repomatic.metric_chart.render_chart(data, *, relative=False, logarithmic=False, title='', label='Stars', stamp=None)[source]¶
Draw the line chart as a standalone, themeable SVG.
- Parameters:
data (
ChartData) – The series to plot and their hues.relative (
bool) – Measure the horizontal axis from each repository’s own first point rather than from the calendar.logarithmic (
bool) – Measure the vertical axis by powers of ten, so series orders of magnitude apart stay legible on one chart. SeeCHART_SCALESfor how the zero every series carries is placed.title (
str) – Accessible name for the chart. Derived from the metric and the mode when empty.label (
str) – What the vertical axis counts, from the plotted metric’slabel.stamp (
str|None) – Sampling date shown in the caption, inYYYY-MM-DDform. Today (UTC) whenNone.
- Return type:
- Returns:
The complete SVG document.
- repomatic.metric_chart.write_chart(grouped, spec, overrides=None, stamp=None)[source]¶
Render one chart and write it, leaving an unchanged file alone.
- Parameters:
grouped (
Mapping[str,list[tuple[date,int]]]) – Every recorded series, asrepomatic.metrics.series()returns them.spec (
ChartSpec) – The chart to draw.overrides (
Mapping[str,Sequence[str]] |None) – Per-name[light, dark]pairs from configuration.stamp (
str|None) – Sampling date shown in the caption. Today (UTC) whenNone.
- Return type:
- Returns:
Truewhen the file content changed.- Raises:
ValueError – When the chart cannot be built (see
build_chart_data()).