graphics

package
v0.0.0-...-554f5f9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 9, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const (

	// PythonPlotFontFamily is the font Python labours renders with (matplotlib's
	// bundled default face).
	PythonPlotFontFamily = "DejaVu Sans"
	// PythonPlotMonoFontFamily is the monospace face used for code/path labels.
	PythonPlotMonoFontFamily = "DejaVu Sans Mono"

	// PythonPlotDefaultWidthInches / PythonPlotDefaultHeightInches are the
	// fallback figure size (matplotlib labours' 16x12 default) used when both a
	// mode and the --size flag leave the dimensions unspecified.
	PythonPlotDefaultWidthInches  = 16.0
	PythonPlotDefaultHeightInches = 12.0
)

Python labours render-style constants. These mirror matplotlib's savefig defaults as used by the reference `labours` tool and are the single source of truth for the matplotlib-go render path: every mode and bridge helper reads figure DPI, font family/size, and the fallback figure size from here rather than re-declaring the literals.

Variables

View Source
var (
	DefaultTheme       = newTheme("default", matplotlibPalette(), rgba(255, 255, 255, 255), grid(true, rgba(224, 224, 224, 255), 0.5), text("Arial", 10, rgba(0, 0, 0, 255), 14, 10), chart(1.0, 1.0, rgba(0, 0, 0, 255), 0.7, true, "right"), heat(rgba(31, 119, 180, 255), rgba(214, 39, 40, 255), rgba(148, 103, 189, 255), false))
	DarkTheme          = newTheme("dark", darkPalette(), rgba(35, 39, 42, 255), grid(true, rgba(68, 74, 79, 255), 0.5), text("Arial", 10, rgba(240, 240, 240, 255), 14, 10), chart(1.0, 1.0, rgba(200, 200, 200, 255), 0.8, true, "right"), heat(rgba(0, 100, 200, 255), rgba(255, 80, 80, 255), rgba(150, 50, 200, 255), false))
	MinimalTheme       = newTheme("minimal", minimalPalette(), rgba(255, 255, 255, 255), grid(false, rgba(240, 240, 240, 255), 0.25), text("Arial", 9, rgba(60, 60, 60, 255), 12, 8), chart(0.8, 0.5, rgba(120, 120, 120, 255), 0.9, false, "bottom"), heat(rgba(240, 240, 240, 255), rgba(60, 60, 60, 255), rgba(150, 150, 150, 255), true))
	VibranthColorTheme = newTheme("vibrant", vibrantPalette(), rgba(250, 250, 250, 255), grid(true, rgba(230, 230, 230, 255), 0.8), text("Arial", 11, rgba(40, 40, 40, 255), 16, 11), chart(1.5, 1.2, rgba(80, 80, 80, 255), 0.6, true, "right"), heat(rgba(0, 100, 255, 255), rgba(255, 50, 50, 255), rgba(255, 200, 0, 255), true))
	MatplotlibTheme    = newTheme("matplotlib", matplotlibPalette(), rgba(255, 255, 255, 255), grid(true, rgba(224, 224, 224, 255), 0.5), text("Arial", 10, rgba(0, 0, 0, 255), 14, 10), chart(1.0, 1.0, rgba(0, 0, 0, 255), 0.7, true, "right"), heat(rgba(31, 119, 180, 255), rgba(214, 39, 40, 255), rgba(148, 103, 189, 255), false))
)

Default themes.

View Source
var BuiltinThemes = map[string]Theme{
	"default":    DefaultTheme,
	"dark":       DarkTheme,
	"minimal":    MinimalTheme,
	"vibrant":    VibranthColorTheme,
	"matplotlib": MatplotlibTheme,
}

BuiltinThemes contains all built-in themes.

View Source
var ColorPalette = []color.Color{
	color.RGBA{R: 31, G: 119, B: 180, A: 255},
	color.RGBA{R: 255, G: 127, B: 14, A: 255},
	color.RGBA{R: 44, G: 160, B: 44, A: 255},
	color.RGBA{R: 214, G: 39, B: 40, A: 255},
	color.RGBA{R: 148, G: 103, B: 189, A: 255},
	color.RGBA{R: 140, G: 86, B: 75, A: 255},
	color.RGBA{R: 227, G: 119, B: 194, A: 255},
	color.RGBA{R: 127, G: 127, B: 127, A: 255},
	color.RGBA{R: 188, G: 189, B: 34, A: 255},
	color.RGBA{R: 23, G: 190, B: 207, A: 255},
}

ColorPalette is the legacy color palette for backwards compatibility It's updated automatically when themes are changed.

View Source
var CurrentTheme = DefaultTheme

CurrentTheme holds the active theme (defaults to DefaultTheme).

View Source
var GlobalThemeManager = NewThemeManager()

GlobalThemeManager is the process-wide theme manager instance.

Functions

func ConfigureLineCountYAxis

func ConfigureLineCountYAxis(axes *core.Axes, maxValue float64)

ConfigureLineCountYAxis fixes both the tick locations and their complete decimal labels. This keeps the magnitude attached to the axis instead of relying on a detachable scientific-notation offset such as "1e4".

func GetBurndownColors

func GetBurndownColors(numColors int) []color.Color

GetBurndownColors returns appropriate colors for burndown charts Uses matplotlib colors if matplotlib theme is active, otherwise uses theme colors.

func GetBurndownColorsForTheme

func GetBurndownColorsForTheme(theme Theme, numColors int) []color.Color

GetBurndownColorsForTheme returns burndown colors without consulting mutable package theme state.

func GetColor

func GetColor(index int) color.Color

GetColor returns a color from the current theme's palette by index.

func GetColorPalette

func GetColorPalette() []color.Color

GetColorPalette returns the current theme's color palette.

func GetMatplotlibBurndownColors

func GetMatplotlibBurndownColors(opacity uint8) []color.Color

GetMatplotlibBurndownColors returns the exact matplotlib colors for burndown charts Red (#d62728) for bottom/older layer, Blue (#1f77b4) for top/newer layer.

func GetPlotSizeInches

func GetPlotSizeInches(chartType ChartType) (width, height float64)

GetPlotSizeInches returns the plot size in inches based on the --size flag and chart type. matplotlib-go renderers take figure sizes in inches, so this is the single sizing entry point modes should use.

func GetPlotSizeInchesWithOptions

func GetPlotSizeInchesWithOptions(chartType ChartType, opts Options) (width, height float64)

GetPlotSizeInchesWithOptions resolves an instance-scoped figure size.

func HeatColor

func HeatColor(ratio float64) color.Color

HeatColor generates a color ranging from blue (cold, ratio=0) to red (hot, ratio=1) This is useful for heatmap-style visualizations where higher values should appear "hotter" This function now uses the current theme's heat color settings.

func InchesToPixels

func InchesToPixels(inches float64) int

InchesToPixels converts a figure dimension in inches to device pixels at the labours render DPI (matplotlib savefig dpi=100), clamped to at least 1px.

func LaboursPlotColors

func LaboursPlotColors(backgroundName string) (background, foreground render.Color)

LaboursPlotColors returns the (background, foreground) figure colors for the given --background flag value, matching Python labours' black-on-white default and white-on-black "black" theme.

func ListThemes

func ListThemes() []string

ListThemes lists all available themes.

func LoadUserThemes

func LoadUserThemes() error

LoadUserThemes loads themes from user directories.

func PlotBarChartMatplotlib

func PlotBarChartMatplotlib(labels []string, values []float64, opts MatplotlibBarOptions) error

func PlotBurndownMatplotlib

func PlotBurndownMatplotlib(data *burndown.ProcessedBurndown, output string, relative bool) error

PlotBurndownMatplotlib creates a burndown plot with matplotlib-go stackplot rendering.

func PlotBurndownMatplotlibWithOptions

func PlotBurndownMatplotlibWithOptions(
	data *burndown.ProcessedBurndown,
	output string,
	relative bool,
	opts Options,
) error

PlotBurndownMatplotlibWithOptions creates a burndown plot using opts.

func PlotDevsEffortsMatplotlib

func PlotDevsEffortsMatplotlib(
	dates []time.Time,
	cumLayers [][]float64,
	labels []string,
	opts MatplotlibDevsEffortsOptions,
) error

PlotDevsEffortsMatplotlib renders the "Efforts through time" chart as non-negative cumulative effort layers over a shared date x-axis. The last layer is the aggregated "others" series.

func PlotGroupedBarChartMatplotlib

func PlotGroupedBarChartMatplotlib(
	labels []string, series []MatplotlibGroupedBarSeries, opts MatplotlibGroupedBarOptions,
) error

func PlotHeatmapMatplotlib

func PlotHeatmapMatplotlib(matrix [][]float64, rowLabels, colLabels []string, opts MatplotlibHeatmapOptions) error

func PlotLineChartMatplotlib

func PlotLineChartMatplotlib(series []MatplotlibLineSeries, opts MatplotlibLineOptions) error

func PlotParallelCoordinatesMatplotlib

func PlotParallelCoordinatesMatplotlib(
	series []MatplotlibParallelCoordinatesSeries, opts MatplotlibParallelCoordinatesOptions,
) error

PlotParallelCoordinatesMatplotlib renders the Python labours devs-parallel chart: each developer is a cubic-spline curve flowing across the vertical axes, drawn as short segments tinted along the viridis colormap.

func PlotScatterMatplotlib

func PlotScatterMatplotlib(series []MatplotlibScatterSeries, opts MatplotlibScatterOptions) error

PlotScatterMatplotlib renders one or more scatter series via matplotlib-go, optionally annotating points with text labels and drawing a dashed y=0 reference line.

func PlotStackedBarChartMatplotlib

func PlotStackedBarChartMatplotlib(
	labels []string, series []MatplotlibGroupedBarSeries, opts MatplotlibGroupedBarOptions,
) error

PlotStackedBarChartMatplotlib renders categorical stacked bars (one stack per label) using per-bar baselines, mirroring gonum's BarChart.StackOn chains.

func PlotStackedBurndownMatplotlib

func PlotStackedBurndownMatplotlib(matrix [][]float64, dateRange []time.Time, output string, relative bool) error

PlotStackedBurndownMatplotlib renders a stacked burndown chart from a raw per-layer matrix and date range using the matplotlib-go backend. It backs the legacy/fallback burndown path that operates on already-interpolated matrices (the header-driven path uses PlotBurndownMatplotlib).

func PlotStackedBurndownMatplotlibWithOptions

func PlotStackedBurndownMatplotlibWithOptions(
	matrix [][]float64,
	dateRange []time.Time,
	output string,
	relative bool,
	opts Options,
) error

PlotStackedBurndownMatplotlibWithOptions renders using an explicit visual configuration.

func PlotTimeAreasMatplotlib

func PlotTimeAreasMatplotlib(
	dates []time.Time, series []MatplotlibTimeAreaSeries, opts MatplotlibTimeAreaOptions,
) error

func PythonLaboursColorPalette

func PythonLaboursColorPalette(n int) []color.Color

PythonLaboursColorPalette returns the color cycle Python labours actually produces. Python labours applies the requested matplotlib style and then overrides axes.prop_cycle with pyplot.cm.tab20.colors in plotting.import_pyplot. Matching this palette is what makes burndown layers, devs spikes and old-vs-new fills look right relative to the Python baseline.

When more series are needed than palette entries, callers cycle modulo length, which mirrors matplotlib's `axes.prop_cycle` wrap-around.

func PythonPlotFontSize

func PythonPlotFontSize() float64

PythonPlotFontSize resolves the configured font size (--font-size), falling back to the Python-parity default of 12pt.

func RegisterPythonLaboursHeatmapColormaps

func RegisterPythonLaboursHeatmapColormaps()

RegisterPythonLaboursHeatmapColormaps registers colormaps used by Python labours but not provided by matplotlib-go's default registry.

func SetTheme

func SetTheme(name string) error

SetTheme sets the current theme by name.

func SetTransparentPNGRGB

func SetTransparentPNGRGB(path string, background render.Color) error

SetTransparentPNGRGB rewrites fully transparent PNG pixels so their hidden RGB channels match the intended matte/background color.

func UseConciseDateAxis

func UseConciseDateAxis(ax *core.Axes)

UseConciseDateAxis replaces the default date formatter on the x axis.

AutoDateFormatter picks its layout from the axis *span* while the locator picks tick positions from its own spacing, and the two disagree: a history of two and a half years crosses the formatter's "two years" threshold into a year-only layout, but still gets roughly nine ticks - so the axis reads "2024 2024 2024 2025 2025 2025 2026". ConciseDateFormatter derives its level from the tick spacing instead, and adds the month where the year alone cannot tell two ticks apart.

func ValidateHeatMap

func ValidateHeatMap(matrix [][]float64, rows, cols []string) error

Types

type ChartStyle

type ChartStyle struct {
	LineWidth   float64  `json:"line_width"      yaml:"line_width"`
	BorderWidth float64  `json:"border_width"    yaml:"border_width"`
	BorderColor ColorRGB `json:"border_color"    yaml:"border_color"`
	FillOpacity float64  `json:"fill_opacity"    yaml:"fill_opacity"`
	LegendShow  bool     `json:"legend_show"     yaml:"legend_show"`
	LegendPos   string   `json:"legend_position" yaml:"legend_position"`
}

ChartStyle configures chart-specific styling.

type ChartType

type ChartType int

ChartType represents different types of charts with their default dimensions.

const (
	ChartTypeDefault ChartType = iota // Standard rectangular charts (burndown, devs, etc.)
	ChartTypeSquare                   // Square charts (heatmaps, coupling matrices)
	ChartTypeCompact                  // Compact charts (ownership, simple plots)
	ChartTypeWide                     // Wide charts (timeline-heavy charts)
)

type ColorRGB

type ColorRGB struct {
	R uint8 `json:"r" yaml:"r"`
	G uint8 `json:"g" yaml:"g"`
	B uint8 `json:"b" yaml:"b"`
	A uint8 `json:"a" yaml:"a"`
}

ColorRGB represents an RGB color that can be serialized.

func (ColorRGB) ToColor

func (c ColorRGB) ToColor() color.Color

ToColor converts ColorRGB to color.Color.

type GridStyle

type GridStyle struct {
	Show  bool     `json:"show"  yaml:"show"`
	Color ColorRGB `json:"color" yaml:"color"`
	Width float64  `json:"width" yaml:"width"`
}

GridStyle configures grid appearance.

type HeatStyle

type HeatStyle struct {
	ColdColor   ColorRGB `json:"cold_color"    yaml:"cold_color"`
	HotColor    ColorRGB `json:"hot_color"     yaml:"hot_color"`
	MidColor    ColorRGB `json:"mid_color"     yaml:"mid_color"`
	UseMidPoint bool     `json:"use_mid_point" yaml:"use_mid_point"`
}

HeatStyle configures heatmap-specific styling.

type MatplotlibBarOptions

type MatplotlibBarOptions struct {
	Title        string
	XLabel       string
	YLabel       string
	Output       string
	WidthInches  float64
	HeightInches float64
	RotateX      bool
	Color        color.Color
	DisableGrid  bool
	Opaque       bool
	DefaultStyle bool
	ManualXLim   bool
	XMin         float64
	XMax         float64
	YMax         float64
	// BarLabels, when set (len == values), draws a rotated text annotation above
	// each bar with a non-empty label. Mirrors gonum's per-bar XYLabels.
	BarLabels     []string
	BarLabelAngle float64
	FontSize      float64
}

type MatplotlibDevsEffortsOptions

type MatplotlibDevsEffortsOptions struct {
	Title        string
	Output       string
	WidthInches  float64
	HeightInches float64
	FontSize     float64
}

type MatplotlibGroupedBarOptions

type MatplotlibGroupedBarOptions struct {
	Title        string
	Subtitle     string
	XLabel       string
	YLabel       string
	Output       string
	WidthInches  float64
	HeightInches float64
	RotateX      bool
	FontSize     float64
}

type MatplotlibGroupedBarSeries

type MatplotlibGroupedBarSeries struct {
	Name   string
	Values []float64
	Color  color.Color
}

type MatplotlibHeatmapOptions

type MatplotlibHeatmapOptions struct {
	Title        string
	Output       string
	Colormap     string
	WidthInches  float64
	HeightInches float64
	XLabelLimit  int
	YLabelLimit  int
	FontSize     float64
}

type MatplotlibLineOptions

type MatplotlibLineOptions struct {
	Title        string
	XLabel       string
	YLabel       string
	Output       string
	WidthInches  float64
	HeightInches float64
	ShowGrid     bool
	Legend       bool
	FontSize     float64
}

type MatplotlibLineSeries

type MatplotlibLineSeries struct {
	Name string
	X    []float64
	// Dates supersedes X when set. matplotlib-go's Plot/Scatter/FillBetween take
	// their x values as any and switch the axis to date units for a []time.Time,
	// so a date axis needs no separate plotting path - only this field.
	Dates  []time.Time
	Y      []float64
	Color  color.Color
	Marker bool
	// Dashes sets a dash pattern (e.g. {5, 5}); nil draws a solid line.
	Dashes []float64
	// Fill shades the area between the series and y=0.
	Fill bool
}

type MatplotlibParallelCoordinatesOptions

type MatplotlibParallelCoordinatesOptions struct {
	Title        string
	Output       string
	WidthInches  float64
	HeightInches float64
	FontSize     float64
	// Axes is the number of vertical axes (Python uses 5).
	Axes int
}

type MatplotlibParallelCoordinatesSeries

type MatplotlibParallelCoordinatesSeries struct {
	// Values holds the normalized y position (0..1) of one developer at each
	// vertical axis, ordered left to right.
	Values []float64
}

type MatplotlibScatterOptions

type MatplotlibScatterOptions struct {
	Title          string
	Subtitle       string
	XLabel         string
	YLabel         string
	Output         string
	WidthInches    float64
	HeightInches   float64
	ShowGrid       bool
	Legend         bool
	ZeroLine       bool
	AnnotateLabels bool
	// XTickLabels, when set, replaces the numeric x-axis with categorical tick
	// labels (one per index 0..len-1), mirroring gonum's NominalX.
	XTickLabels []string
	RotateX     bool
	FontSize    float64
}

type MatplotlibScatterPoint

type MatplotlibScatterPoint struct {
	X     float64
	Y     float64
	Label string
}

type MatplotlibScatterSeries

type MatplotlibScatterSeries struct {
	Name   string
	Points []MatplotlibScatterPoint
	Color  color.Color
	Size   float64
}

type MatplotlibTextLabel

type MatplotlibTextLabel struct {
	X        float64
	Y        float64
	Text     string
	HAlign   core.TextAlign
	FontSize float64
	// BackgroundColor draws a filled rectangle behind the label, mirroring
	// matplotlib's `text(..., backgroundcolor=...)`. Leave nil for no fill.
	BackgroundColor color.Color
}

type MatplotlibTimeAreaOptions

type MatplotlibTimeAreaOptions struct {
	Title        string
	Subtitle     string
	XLabel       string
	YLabel       string
	Output       string
	WidthInches  float64
	HeightInches float64
	Stacked      bool
	HideY        bool
	ShowGrid     bool
	Legend       bool
	LegendLeft   bool
	LegendTop    bool
	HideFrame    bool
	AutoXMargin  bool
	// FullNumberYTicks disables scientific/offset notation and renders the
	// complete magnitude in every y-axis tick label.
	FullNumberYTicks bool
	LegendFace       color.Color
	Alpha            float64
	YMin             float64
	YMax             float64
	Baselines        [][]float64
	TextLabels       []MatplotlibTextLabel
	FontSize         float64
}

type MatplotlibTimeAreaSeries

type MatplotlibTimeAreaSeries struct {
	Label  string
	Values []float64
	Color  color.Color
}

type Options

type Options struct {
	Theme      Theme
	FontSize   int
	Background string
	Size       string
	HideTitle  bool
}

Options contains immutable visual settings for one renderer instance.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns Python-compatible visual defaults.

func (Options) Palette

func (opts Options) Palette() []color.Color

Palette returns a fresh copy of the configured theme palette.

func (Options) PlotFontSize

func (opts Options) PlotFontSize() float64

PlotFontSize returns the configured font size.

type TextStyle

type TextStyle struct {
	Font      string   `json:"font"       yaml:"font"`
	Size      float64  `json:"size"       yaml:"size"`
	Color     ColorRGB `json:"color"      yaml:"color"`
	TitleSize float64  `json:"title_size" yaml:"title_size"`
	LabelSize float64  `json:"label_size" yaml:"label_size"`
}

TextStyle configures text appearance.

type Theme

type Theme struct {
	Name         string     `json:"name"       yaml:"name"`
	ColorPalette []ColorRGB `json:"colors"     yaml:"colors"`
	Background   ColorRGB   `json:"background" yaml:"background"`
	Grid         GridStyle  `json:"grid"       yaml:"grid"`
	Text         TextStyle  `json:"text"       yaml:"text"`
	Chart        ChartStyle `json:"chart"      yaml:"chart"`
	HeatMap      HeatStyle  `json:"heatmap"    yaml:"heatmap"`
}

Theme represents a complete visual theme configuration.

func GetTheme

func GetTheme(name string) (*Theme, error)

GetTheme gets a theme by name.

func (*Theme) GetColorPalette

func (t *Theme) GetColorPalette() []color.Color

GetColorPalette returns the color palette as color.Color slice.

func (*Theme) GetHeatColor

func (t *Theme) GetHeatColor(ratio float64) color.Color

GetHeatColor generates a heat map color based on ratio and theme settings.

func (*Theme) Validate

func (t *Theme) Validate() error

Validate checks if theme configuration is valid.

type ThemeManager

type ThemeManager struct {
	// contains filtered or unexported fields
}

ThemeManager handles theme loading and management.

func NewThemeManager

func NewThemeManager() *ThemeManager

NewThemeManager creates a new theme manager with built-in themes.

func (*ThemeManager) CreateCustomTheme

func (tm *ThemeManager) CreateCustomTheme(baseName string, customizations map[string]any) (*Theme, error)

CreateCustomTheme creates a custom theme based on an existing theme with modifications.

func (*ThemeManager) ExportTheme

func (tm *ThemeManager) ExportTheme(themeName, outputPath string) error

ExportTheme exports a built-in theme to a file for customization.

func (*ThemeManager) GetTheme

func (tm *ThemeManager) GetTheme(name string) (*Theme, error)

GetTheme retrieves a theme by name.

func (*ThemeManager) ListThemes

func (tm *ThemeManager) ListThemes() []string

ListThemes returns a list of available theme names.

func (*ThemeManager) LoadThemeFromFile

func (tm *ThemeManager) LoadThemeFromFile(filepath string) error

LoadThemeFromFile loads a theme from a YAML file.

func (*ThemeManager) LoadThemesFromDirectory

func (tm *ThemeManager) LoadThemesFromDirectory(dirPath string) error

LoadThemesFromDirectory loads all theme files from a directory.

func (*ThemeManager) RegisterTheme

func (tm *ThemeManager) RegisterTheme(theme Theme) error

RegisterTheme registers a new theme.

func (*ThemeManager) SaveThemeToFile

func (tm *ThemeManager) SaveThemeToFile(theme *Theme, filepath string) error

SaveThemeToFile saves a theme to a YAML file.

func (*ThemeManager) SetCurrentTheme

func (tm *ThemeManager) SetCurrentTheme(name string) error

SetCurrentTheme sets the global current theme.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL