Search Apps Documentation Source Content File Folder Download Copy Actions Download

column_chart.gno

2.63 Kb ยท 105 lines
  1package charts
  2
  3import (
  4	"strings"
  5
  6	"gno.land/p/nt/ufmt"
  7)
  8
  9// GenerateColumnChart creates an ASCII column chart in markdown format
 10// values: slice of float values to chart
 11// maxColumns: maximum number of columns to display (will normalize if exceeded)
 12// title: chart title
 13// xAxisTitle: title for the x-axis
 14// yAxisTitle: title for the y-axis
 15// Returns a markdown string representing the chart
 16func GenerateColumnChart(values []float64, maxColumns int, title, xAxisTitle, yAxisTitle string) string {
 17	if len(values) == 0 {
 18		return "no data to display"
 19	}
 20
 21	if maxColumns <= 0 {
 22		return "maxColumns must be greater than 0"
 23	}
 24
 25	maxVal := findMaxValue(values)
 26
 27	displayValues := values
 28	if len(values) > maxColumns {
 29		displayValues = normalizeData(values, maxColumns)
 30	}
 31
 32	scale := height / maxVal
 33
 34	output := formatChartHeader(title)
 35	output += "\n```\n"
 36	output += formatYAxisTitle(yAxisTitle)
 37
 38	maxYValue := ufmt.Sprintf("%.2f", maxVal)
 39	yAxisWidth := len(maxYValue)
 40
 41	maxValStrLen := calculateMaxValueStringLength(displayValues)
 42	if maxValStrLen < 2 {
 43		maxValStrLen = 2
 44	}
 45	colWidth := maxValStrLen + 2
 46
 47	for row := height; row > 0; row-- {
 48		if row%3 == 0 {
 49			output += formatYAxisLabel(float64(row), scale, yAxisWidth)
 50		} else {
 51			output += formatYAxisSpace(yAxisWidth)
 52		}
 53
 54		for _, val := range displayValues {
 55			scaledHeight := int(val * scale)
 56			if scaledHeight >= row {
 57				barWidth := colWidth - 1
 58				output += strings.Repeat("|", barWidth) + " "
 59			} else {
 60				output += strings.Repeat(" ", colWidth)
 61			}
 62		}
 63		output += "\n"
 64	}
 65
 66	output += strings.Repeat(" ", yAxisWidth) + " +"
 67	output += strings.Repeat(strings.Repeat("-", colWidth), len(displayValues))
 68	output += "\n"
 69
 70	output += formatValueLabelsColumnChart(displayValues, colWidth, yAxisWidth)
 71
 72	if xAxisTitle != "" {
 73		totalWidth := len(displayValues) * colWidth
 74		output += formatXAxisTitle(xAxisTitle, totalWidth)
 75	}
 76
 77	output += "```\n"
 78	return output
 79}
 80
 81// formatValueLabelsColumnChart formats the value labels for the x-axis for column charts
 82func formatValueLabelsColumnChart(values []float64, colWidth int, yAxisWidth int) string {
 83	output := strings.Repeat(" ", yAxisWidth+2)
 84
 85	for i := 0; i < len(values); i++ {
 86		x := i * colWidth
 87		valStr := ufmt.Sprintf("%.2f", values[i])
 88		labelPos := x + colWidth/2 - len(valStr)/2
 89		if labelPos < 0 {
 90			labelPos = 0
 91		}
 92
 93		if i == 0 {
 94			output += strings.Repeat(" ", labelPos)
 95		} else {
 96			prevX := (i - 1) * colWidth
 97			prevValStr := ufmt.Sprintf("%.2f", values[i-1])
 98			prevLabelEnd := prevX + colWidth/2 - len(prevValStr)/2 + len(prevValStr)
 99			output += strings.Repeat(" ", labelPos-prevLabelEnd)
100		}
101		output += valStr
102	}
103
104	return output + "\n"
105}