mirror of
https://github.com/taigrr/gico.git
synced 2026-04-02 03:09:07 -07:00
rename gitgraph => graph
This commit is contained in:
4
graph/.gitignore
vendored
Normal file
4
graph/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
*.svg
|
||||
graph
|
||||
bin/cli/cli
|
||||
bin/server/svg-server
|
||||
75
graph/common/common.go
Normal file
75
graph/common/common.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image/color"
|
||||
"math"
|
||||
"sync"
|
||||
|
||||
sc "github.com/taigrr/simplecolorpalettes/simplecolor"
|
||||
)
|
||||
|
||||
var (
|
||||
colorsLoaded sync.Once
|
||||
colorScheme []sc.SimpleColor
|
||||
)
|
||||
|
||||
func CreateGraph() bytes.Buffer {
|
||||
var x bytes.Buffer
|
||||
return x
|
||||
}
|
||||
|
||||
func init() {
|
||||
colors := []string{"#767960", "#a7297f", "#e8ca89", "#f5efd6", "#158266"}
|
||||
colors = []string{"#000000", "#0e4429", "#006d32", "#26a641", "#39d353"}
|
||||
for _, c := range colors {
|
||||
color := sc.FromHexString(c)
|
||||
colorScheme = append(colorScheme, color)
|
||||
}
|
||||
}
|
||||
|
||||
func SetColorScheme(c []color.Color) {
|
||||
for _, c := range c {
|
||||
colorScheme = append(colorScheme, sc.FromRGBA(c.RGBA()))
|
||||
}
|
||||
}
|
||||
|
||||
func ColorForFrequency(freq, min, max int) sc.SimpleColor {
|
||||
if freq == 0 {
|
||||
return sc.SimpleColor(0)
|
||||
}
|
||||
spread := max - min
|
||||
if spread < len(colorScheme)-1 {
|
||||
return colorScheme[freq-min+1]
|
||||
}
|
||||
interval := float64(spread) / float64(len(colorScheme))
|
||||
colorIndex := 0
|
||||
for i := float64(min); i < float64(freq); i += float64(interval) {
|
||||
colorIndex++
|
||||
}
|
||||
if colorIndex > len(colorScheme)-1 {
|
||||
colorIndex = len(colorScheme) - 1
|
||||
}
|
||||
return colorScheme[colorIndex]
|
||||
}
|
||||
|
||||
func MinMax(f []int) (int, int) {
|
||||
min, max := math.MaxInt, math.MinInt
|
||||
for _, x := range f {
|
||||
if x == 0 {
|
||||
continue
|
||||
}
|
||||
if x < min {
|
||||
min = x
|
||||
} else if x > max {
|
||||
max = x
|
||||
}
|
||||
}
|
||||
if min == math.MaxInt {
|
||||
min = 0
|
||||
}
|
||||
if max == math.MinInt {
|
||||
max = 0
|
||||
}
|
||||
return min, max
|
||||
}
|
||||
103
graph/svg/svg.go
Normal file
103
graph/svg/svg.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package svg
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
svg "github.com/ajstarks/svgo"
|
||||
"github.com/srwiley/oksvg"
|
||||
"github.com/srwiley/rasterx"
|
||||
sc "github.com/taigrr/simplecolorpalettes/simplecolor"
|
||||
|
||||
"github.com/taigrr/gico/graph/common"
|
||||
)
|
||||
|
||||
var (
|
||||
colorsLoaded sync.Once
|
||||
colorScheme []sc.SimpleColor
|
||||
)
|
||||
|
||||
func GetWeekSVG(frequencies []int) bytes.Buffer {
|
||||
squareColors := []sc.SimpleColor{}
|
||||
min, max := common.MinMax(frequencies)
|
||||
for _, f := range frequencies {
|
||||
squareColors = append(squareColors, common.ColorForFrequency(f, min, max))
|
||||
}
|
||||
return drawWeekImage(squareColors, frequencies)
|
||||
}
|
||||
|
||||
func drawWeekImage(c []sc.SimpleColor, freq []int) bytes.Buffer {
|
||||
var sb bytes.Buffer
|
||||
sbw := bufio.NewWriter(&sb)
|
||||
squareLength := 10
|
||||
width := (len(c) + 1) * squareLength * 2
|
||||
height := squareLength * 2
|
||||
canvas := svg.New(sbw)
|
||||
canvas.Start(width, height)
|
||||
canvas.Rect(0, 0, width, height, "fill:black")
|
||||
for i, s := range c {
|
||||
canvas.Square(squareLength*2*(i+1), squareLength/2, squareLength, fmt.Sprintf("fill:%s; value:%d", s.ToHex(), freq[i]))
|
||||
}
|
||||
canvas.End()
|
||||
sbw.Flush()
|
||||
return sb
|
||||
}
|
||||
|
||||
func GetYearSVG(frequencies []int) bytes.Buffer {
|
||||
squareColors := []sc.SimpleColor{}
|
||||
min, max := common.MinMax(frequencies)
|
||||
for _, f := range frequencies {
|
||||
squareColors = append(squareColors, common.ColorForFrequency(f, min, max))
|
||||
}
|
||||
return drawYearImage(squareColors)
|
||||
}
|
||||
|
||||
func drawYearImage(c []sc.SimpleColor) bytes.Buffer {
|
||||
var sb bytes.Buffer
|
||||
sbw := bufio.NewWriter(&sb)
|
||||
squareLength := 10
|
||||
width := (len(c)/7+1)*squareLength*2 + squareLength*5
|
||||
height := squareLength*9 + squareLength*3
|
||||
canvas := svg.New(sbw)
|
||||
canvas.Start(width, height)
|
||||
for i, s := range c {
|
||||
canvas.Square(2*squareLength+width/(len(c)/7+1)*(i/7)+squareLength*2, squareLength/2+height/7*(i%7), squareLength, fmt.Sprintf("fill:%s", s.ToHex()))
|
||||
}
|
||||
// canvas.Text(2*squareLength, squareLength*3, "Mon", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength))
|
||||
// canvas.Text(2*squareLength, int(float64(squareLength)*6.5), "Wed", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength))
|
||||
// canvas.Text(2*squareLength, int(float64(squareLength))*10, "Fri", fmt.Sprintf("text-anchor:middle;font-size:%dpx;fill:black", squareLength))
|
||||
canvas.End()
|
||||
sbw.Flush()
|
||||
return sb
|
||||
}
|
||||
|
||||
func svgToPng() {
|
||||
w, h := 512, 512
|
||||
|
||||
in, err := os.Open("in.svg")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
icon, _ := oksvg.ReadIconStream(in)
|
||||
icon.SetTarget(0, 0, float64(w), float64(h))
|
||||
rgba := image.NewRGBA(image.Rect(0, 0, w, h))
|
||||
icon.Draw(rasterx.NewDasher(w, h, rasterx.NewScannerGV(w, h, rgba, rgba.Bounds())), 1)
|
||||
|
||||
out, err := os.Create("out.png")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
err = png.Encode(out, rgba)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
78
graph/term/term.go
Normal file
78
graph/term/term.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package term
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/muesli/termenv"
|
||||
sc "github.com/taigrr/simplecolorpalettes/simplecolor"
|
||||
|
||||
"github.com/taigrr/gico/graph/common"
|
||||
)
|
||||
|
||||
var (
|
||||
colorsLoaded sync.Once
|
||||
colorScheme []sc.SimpleColor
|
||||
)
|
||||
|
||||
func GetWeekUnicode(frequencies []int) string {
|
||||
squareColors := []sc.SimpleColor{}
|
||||
min, max := common.MinMax(frequencies)
|
||||
for _, f := range frequencies {
|
||||
squareColors = append(squareColors, common.ColorForFrequency(f, min, max))
|
||||
}
|
||||
return drawWeekUnicode(squareColors)
|
||||
}
|
||||
|
||||
func drawWeekUnicode(c []sc.SimpleColor) string {
|
||||
// o := termenv.NewOutput(os.Stdout)
|
||||
s := strings.Builder{}
|
||||
o := termenv.NewOutputWithProfile(os.Stdout, termenv.TrueColor)
|
||||
for w, color := range c {
|
||||
style := o.String(block).Foreground(termenv.TrueColor.Color(color.ToHex()))
|
||||
s.WriteString(style.String())
|
||||
// termenv.SetForegroundColor(termenv.ForegroundColor())
|
||||
if w == len(c)-1 {
|
||||
s.WriteString("\n")
|
||||
} else {
|
||||
s.WriteString(" ")
|
||||
}
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func GetYearUnicode(frequencies []int) string {
|
||||
squareColors := []sc.SimpleColor{}
|
||||
min, max := common.MinMax(frequencies)
|
||||
for _, f := range frequencies {
|
||||
squareColors = append(squareColors, common.ColorForFrequency(f, min, max))
|
||||
}
|
||||
return drawYearUnicode(squareColors)
|
||||
}
|
||||
|
||||
func drawYearUnicode(c []sc.SimpleColor) string {
|
||||
// o := termenv.NewOutput(os.Stdout)
|
||||
var s strings.Builder
|
||||
o := termenv.NewOutputWithProfile(os.Stdout, termenv.TrueColor)
|
||||
weeks := [7][]sc.SimpleColor{{}}
|
||||
for i := 0; i < 7; i++ {
|
||||
weeks[i] = []sc.SimpleColor{}
|
||||
}
|
||||
for i := range c {
|
||||
weeks[i%7] = append(weeks[i%7], c[i])
|
||||
}
|
||||
for _, row := range weeks {
|
||||
for w, d := range row {
|
||||
style := o.String(block).Foreground(termenv.TrueColor.Color(d.ToHex()))
|
||||
s.WriteString(style.String())
|
||||
if w == len(row)-1 {
|
||||
s.WriteString("\n")
|
||||
} else {
|
||||
s.WriteString(" ")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
3
graph/term/unicode.go
Normal file
3
graph/term/unicode.go
Normal file
@@ -0,0 +1,3 @@
|
||||
package term
|
||||
|
||||
const block = "▅"
|
||||
Reference in New Issue
Block a user