Compare commits
26 commits
Author | SHA1 | Date | |
---|---|---|---|
63f0be79dd | |||
1f6d76e8b5 | |||
cc8d36edd9 | |||
bd2b44aa38 | |||
|
b46667ea80 | ||
|
218e744a87 | ||
|
a334e8e43a | ||
|
c9c9042154 | ||
|
2f3402adfb | ||
|
dd823617d9 | ||
|
7281bbdfa8 | ||
|
b3fc6cba9f | ||
|
0d3588f719 | ||
|
d9bba03c8f | ||
|
c6416e0757 | ||
|
f6d9d1edca | ||
|
2c2fb0651b | ||
|
2ff54048b8 | ||
|
e781e0cd22 | ||
|
54fc699377 | ||
|
1ccfbb0172 | ||
|
c1468e8ae4 | ||
|
962b9abdec | ||
|
3a7bc55431 | ||
|
60baf17927 | ||
|
45fad0cfb8 |
|
@ -1,17 +0,0 @@
|
||||||
version: 2
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
working_directory: /go/src/github.com/wcharczuk/go-chart
|
|
||||||
docker:
|
|
||||||
- image: circleci/golang:1.11
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- run:
|
|
||||||
name: new-install
|
|
||||||
command: make new-install
|
|
||||||
- run:
|
|
||||||
name: ci
|
|
||||||
command: make ci
|
|
||||||
- store_artifacts:
|
|
||||||
path: coverage.html
|
|
||||||
destination: coverage.html
|
|
33
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
name: "Continuous Integration"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
paths: [ "*.go" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
paths: [ "*.go" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
name: "Tests"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
env:
|
||||||
|
GOOS: "linux"
|
||||||
|
GOARCH: "amd64"
|
||||||
|
GO111MODULE: "on"
|
||||||
|
CGO_ENABLED: "0"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.21
|
||||||
|
|
||||||
|
- name: Check out go-incr
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Run all tests
|
||||||
|
run: go test ./...
|
1
.gitignore
vendored
|
@ -17,3 +17,4 @@
|
||||||
.vscode
|
.vscode
|
||||||
.DS_Store
|
.DS_Store
|
||||||
coverage.html
|
coverage.html
|
||||||
|
.idea
|
||||||
|
|
2
COVERAGE
|
@ -1 +1 @@
|
||||||
70.89
|
29.02
|
1
LICENSE
|
@ -1,6 +1,7 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2016 William Charczuk.
|
Copyright (c) 2016 William Charczuk.
|
||||||
|
Copyright (c) 2024 Zeni Kim.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
16
Makefile
|
@ -1,18 +1,10 @@
|
||||||
all: test
|
all: new-install test
|
||||||
|
|
||||||
ci: profanity coverage
|
|
||||||
|
|
||||||
new-install:
|
new-install:
|
||||||
@go get -v -u ./...
|
@go get -v -u ./...
|
||||||
@go get -v -u github.com/blend/go-sdk/cmd/coverage
|
|
||||||
@go get -v -u github.com/blend/go-sdk/cmd/profanity
|
generate:
|
||||||
|
@go generate ./...
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@go test ./...
|
@go test ./...
|
||||||
|
|
||||||
.PHONY: profanity
|
|
||||||
profanity:
|
|
||||||
@profanity
|
|
||||||
|
|
||||||
coverage:
|
|
||||||
@coverage
|
|
35
README.md
|
@ -1,20 +1,18 @@
|
||||||
go-chart
|
go-chart
|
||||||
========
|
========
|
||||||
[![CircleCI](https://circleci.com/gh/wcharczuk/go-chart.svg?style=svg)](https://circleci.com/gh/wcharczuk/go-chart) [![Go Report Card](https://goreportcard.com/badge/github.com/wcharczuk/go-chart)](https://goreportcard.com/report/github.com/wcharczuk/go-chart)
|
|
||||||
|
|
||||||
Package `chart` is a very simple golang native charting library that supports timeseries and continuous
|
This project starts from a full copy from [https://git.smarteching.com/zeni/go-chart](https://git.smarteching.com/zeni/go-chart). 28 Oct 2024.
|
||||||
line charts.
|
|
||||||
|
|
||||||
The v1.0 release has been tagged so things should be more or less stable, if something changes please log an issue.
|
-
|
||||||
|
|
||||||
Master should now be on the v2.x codebase, which brings a couple new features and better handling of basics like axes labeling etc. Per usual, see `_examples` for more information.
|
Master should now be on the v3.x codebase, which overhauls the api significantly. Per usual, see `examples` for more information.
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
To install `chart` run the following:
|
To install `chart` run the following:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> go get -u github.com/wcharczuk/go-chart
|
> go get git.smarteching.com/zeni/go-chart/v2@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Most of the components are interchangeable so feel free to crib whatever you want.
|
Most of the components are interchangeable so feel free to crib whatever you want.
|
||||||
|
@ -23,33 +21,35 @@ Most of the components are interchangeable so feel free to crib whatever you wan
|
||||||
|
|
||||||
Spark Lines:
|
Spark Lines:
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/wcharczuk/go-chart/master/_images/tvix_ltm.png)
|
![](https://git.smarteching.com/zeni/go-chart/raw/branch/main/_images/tvix_ltm.png)
|
||||||
|
|
||||||
Single axis:
|
Single axis:
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/wcharczuk/go-chart/master/_images/goog_ltm.png)
|
![](https://git.smarteching.com/zeni/go-chart/raw/branch/main/_images/goog_ltm.png)
|
||||||
|
|
||||||
Two axis:
|
Two axis:
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/wcharczuk/go-chart/master/_images/two_axis.png)
|
![](https://git.smarteching.com/zeni/go-chart/raw/branch/main/_images/two_axis.png)
|
||||||
|
|
||||||
# Other Chart Types
|
# Other Chart Types
|
||||||
|
|
||||||
Pie Chart:
|
Pie Chart:
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/wcharczuk/go-chart/master/_images/pie_chart.png)
|
![](https://git.smarteching.com/zeni/go-chart/raw/branch/main/_images/pie_chart.png)
|
||||||
|
|
||||||
The code for this chart can be found in `_examples/pie_chart/main.go`.
|
The code for this chart can be found in `examples/pie_chart/main.go`.
|
||||||
|
|
||||||
Stacked Bar:
|
Stacked Bar:
|
||||||
|
|
||||||
![](https://raw.githubusercontent.com/wcharczuk/go-chart/master/_images/stacked_bar.png)
|
![](https://git.smarteching.com/zeni/go-chart/raw/branch/main/_images/stacked_bar.png)
|
||||||
|
|
||||||
The code for this chart can be found in `_examples/stacked_bar/main.go`.
|
The code for this chart can be found in `examples/stacked_bar/main.go`.
|
||||||
|
|
||||||
# Code Examples
|
# Code Examples
|
||||||
|
|
||||||
Actual chart configurations and examples can be found in the `./_examples/` directory. They are web servers, so start them with `go run main.go` then access `http://localhost:8080` to see the output.
|
Actual chart configurations and examples can be found in the `./examples/` directory. They are simple CLI programs that write to `output.png` (they are also updated with `go generate`.
|
||||||
|
|
||||||
|
If folder ends in "web", has web servers, so start them with `go run main.go` then access `http://localhost:8080` to see the output.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ import (
|
||||||
...
|
...
|
||||||
"bytes"
|
"bytes"
|
||||||
...
|
...
|
||||||
"github.com/wcharczuk/go-chart" //exposes "chart"
|
"git.smarteching.com/zeni/go-chart/v2" //exposes "chart"
|
||||||
)
|
)
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
|
@ -83,8 +83,7 @@ Here, we have a single series with x range values as float64s, rendered to a PNG
|
||||||
|
|
||||||
# API Overview
|
# API Overview
|
||||||
|
|
||||||
Everything on the `chart.Chart` object has defaults that can be overriden. Whenever a developer sets a property on the chart object, it is to be assumed that value will be used instead of the default. One complication here
|
Everything on the `chart.Chart` object has defaults that can be overriden. Whenever a developer sets a property on the chart object, it is to be assumed that value will be used instead of the default.
|
||||||
is any object's root `chart.Style` object (i.e named `Style`) and the `Show` property specifically, if any other property is set and the `Show` property is unset, it is assumed to be it's default value of `False`.
|
|
||||||
|
|
||||||
The best way to see the api in action is to look at the examples in the `./_examples/` directory.
|
The best way to see the api in action is to look at the examples in the `./_examples/` directory.
|
||||||
|
|
||||||
|
@ -96,4 +95,4 @@ The goal with the API itself is to have the "zero value be useful", and to requi
|
||||||
|
|
||||||
# Contributions
|
# Contributions
|
||||||
|
|
||||||
This library is super early but contributions are welcome.
|
Contributions are welcome though this library is in a holding pattern for the forseable future.
|
||||||
|
|
147
_colors/colors_extended.txt
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
aliceblue #f0f8ff 240,248,255
|
||||||
|
antiquewhite #faebd7 250,235,215
|
||||||
|
aqua #00ffff 0,255,255
|
||||||
|
aquamarine #7fffd4 127,255,212
|
||||||
|
azure #f0ffff 240,255,255
|
||||||
|
beige #f5f5dc 245,245,220
|
||||||
|
bisque #ffe4c4 255,228,196
|
||||||
|
black #000000 0,0,0
|
||||||
|
blanchedalmond #ffebcd 255,235,205
|
||||||
|
blue #0000ff 0,0,255
|
||||||
|
blueviolet #8a2be2 138,43,226
|
||||||
|
brown #a52a2a 165,42,42
|
||||||
|
burlywood #deb887 222,184,135
|
||||||
|
cadetblue #5f9ea0 95,158,160
|
||||||
|
chartreuse #7fff00 127,255,0
|
||||||
|
chocolate #d2691e 210,105,30
|
||||||
|
coral #ff7f50 255,127,80
|
||||||
|
cornflowerblue #6495ed 100,149,237
|
||||||
|
cornsilk #fff8dc 255,248,220
|
||||||
|
crimson #dc143c 220,20,60
|
||||||
|
cyan #00ffff 0,255,255
|
||||||
|
darkblue #00008b 0,0,139
|
||||||
|
darkcyan #008b8b 0,139,139
|
||||||
|
darkgoldenrod #b8860b 184,134,11
|
||||||
|
darkgray #a9a9a9 169,169,169
|
||||||
|
darkgreen #006400 0,100,0
|
||||||
|
darkgrey #a9a9a9 169,169,169
|
||||||
|
darkkhaki #bdb76b 189,183,107
|
||||||
|
darkmagenta #8b008b 139,0,139
|
||||||
|
darkolivegreen #556b2f 85,107,47
|
||||||
|
darkorange #ff8c00 255,140,0
|
||||||
|
darkorchid #9932cc 153,50,204
|
||||||
|
darkred #8b0000 139,0,0
|
||||||
|
darksalmon #e9967a 233,150,122
|
||||||
|
darkseagreen #8fbc8f 143,188,143
|
||||||
|
darkslateblue #483d8b 72,61,139
|
||||||
|
darkslategray #2f4f4f 47,79,79
|
||||||
|
darkslategrey #2f4f4f 47,79,79
|
||||||
|
darkturquoise #00ced1 0,206,209
|
||||||
|
darkviolet #9400d3 148,0,211
|
||||||
|
deeppink #ff1493 255,20,147
|
||||||
|
deepskyblue #00bfff 0,191,255
|
||||||
|
dimgray #696969 105,105,105
|
||||||
|
dimgrey #696969 105,105,105
|
||||||
|
dodgerblue #1e90ff 30,144,255
|
||||||
|
firebrick #b22222 178,34,34
|
||||||
|
floralwhite #fffaf0 255,250,240
|
||||||
|
forestgreen #228b22 34,139,34
|
||||||
|
fuchsia #ff00ff 255,0,255
|
||||||
|
gainsboro #dcdcdc 220,220,220
|
||||||
|
ghostwhite #f8f8ff 248,248,255
|
||||||
|
gold #ffd700 255,215,0
|
||||||
|
goldenrod #daa520 218,165,32
|
||||||
|
gray #808080 128,128,128
|
||||||
|
green #008000 0,128,0
|
||||||
|
greenyellow #adff2f 173,255,47
|
||||||
|
grey #808080 128,128,128
|
||||||
|
honeydew #f0fff0 240,255,240
|
||||||
|
hotpink #ff69b4 255,105,180
|
||||||
|
indianred #cd5c5c 205,92,92
|
||||||
|
indigo #4b0082 75,0,130
|
||||||
|
ivory #fffff0 255,255,240
|
||||||
|
khaki #f0e68c 240,230,140
|
||||||
|
lavender #e6e6fa 230,230,250
|
||||||
|
lavenderblush #fff0f5 255,240,245
|
||||||
|
lawngreen #7cfc00 124,252,0
|
||||||
|
lemonchiffon #fffacd 255,250,205
|
||||||
|
lightblue #add8e6 173,216,230
|
||||||
|
lightcoral #f08080 240,128,128
|
||||||
|
lightcyan #e0ffff 224,255,255
|
||||||
|
lightgoldenrodyellow #fafad2 250,250,210
|
||||||
|
lightgray #d3d3d3 211,211,211
|
||||||
|
lightgreen #90ee90 144,238,144
|
||||||
|
lightgrey #d3d3d3 211,211,211
|
||||||
|
lightpink #ffb6c1 255,182,193
|
||||||
|
lightsalmon #ffa07a 255,160,122
|
||||||
|
lightseagreen #20b2aa 32,178,170
|
||||||
|
lightskyblue #87cefa 135,206,250
|
||||||
|
lightslategray #778899 119,136,153
|
||||||
|
lightslategrey #778899 119,136,153
|
||||||
|
lightsteelblue #b0c4de 176,196,222
|
||||||
|
lightyellow #ffffe0 255,255,224
|
||||||
|
lime #00ff00 0,255,0
|
||||||
|
limegreen #32cd32 50,205,50
|
||||||
|
linen #faf0e6 250,240,230
|
||||||
|
magenta #ff00ff 255,0,255
|
||||||
|
maroon #800000 128,0,0
|
||||||
|
mediumaquamarine #66cdaa 102,205,170
|
||||||
|
mediumblue #0000cd 0,0,205
|
||||||
|
mediumorchid #ba55d3 186,85,211
|
||||||
|
mediumpurple #9370db 147,112,219
|
||||||
|
mediumseagreen #3cb371 60,179,113
|
||||||
|
mediumslateblue #7b68ee 123,104,238
|
||||||
|
mediumspringgreen #00fa9a 0,250,154
|
||||||
|
mediumturquoise #48d1cc 72,209,204
|
||||||
|
mediumvioletred #c71585 199,21,133
|
||||||
|
midnightblue #191970 25,25,112
|
||||||
|
mintcream #f5fffa 245,255,250
|
||||||
|
mistyrose #ffe4e1 255,228,225
|
||||||
|
moccasin #ffe4b5 255,228,181
|
||||||
|
navajowhite #ffdead 255,222,173
|
||||||
|
navy #000080 0,0,128
|
||||||
|
oldlace #fdf5e6 253,245,230
|
||||||
|
olive #808000 128,128,0
|
||||||
|
olivedrab #6b8e23 107,142,35
|
||||||
|
orange #ffa500 255,165,0
|
||||||
|
orangered #ff4500 255,69,0
|
||||||
|
orchid #da70d6 218,112,214
|
||||||
|
palegoldenrod #eee8aa 238,232,170
|
||||||
|
palegreen #98fb98 152,251,152
|
||||||
|
paleturquoise #afeeee 175,238,238
|
||||||
|
palevioletred #db7093 219,112,147
|
||||||
|
papayawhip #ffefd5 255,239,213
|
||||||
|
peachpuff #ffdab9 255,218,185
|
||||||
|
peru #cd853f 205,133,63
|
||||||
|
pink #ffc0cb 255,192,203
|
||||||
|
plum #dda0dd 221,160,221
|
||||||
|
powderblue #b0e0e6 176,224,230
|
||||||
|
purple #800080 128,0,128
|
||||||
|
red #ff0000 255,0,0
|
||||||
|
rosybrown #bc8f8f 188,143,143
|
||||||
|
royalblue #4169e1 65,105,225
|
||||||
|
saddlebrown #8b4513 139,69,19
|
||||||
|
salmon #fa8072 250,128,114
|
||||||
|
sandybrown #f4a460 244,164,96
|
||||||
|
seagreen #2e8b57 46,139,87
|
||||||
|
seashell #fff5ee 255,245,238
|
||||||
|
sienna #a0522d 160,82,45
|
||||||
|
silver #c0c0c0 192,192,192
|
||||||
|
skyblue #87ceeb 135,206,235
|
||||||
|
slateblue #6a5acd 106,90,205
|
||||||
|
slategray #708090 112,128,144
|
||||||
|
slategrey #708090 112,128,144
|
||||||
|
snow #fffafa 255,250,250
|
||||||
|
springgreen #00ff7f 0,255,127
|
||||||
|
steelblue #4682b4 70,130,180
|
||||||
|
tan #d2b48c 210,180,140
|
||||||
|
teal #008080 0,128,128
|
||||||
|
thistle #d8bfd8 216,191,216
|
||||||
|
tomato #ff6347 255,99,71
|
||||||
|
turquoise #40e0d0 64,224,208
|
||||||
|
violet #ee82ee 238,130,238
|
||||||
|
wheat #f5deb3 245,222,179
|
||||||
|
white #ffffff 255,255,255
|
||||||
|
whitesmoke #f5f5f5 245,245,245
|
||||||
|
yellow #ffff00 255,255,0
|
||||||
|
yellowgreen #9acd32 154,205,50
|
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 19 KiB |
|
@ -1,43 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
|
||||||
)
|
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
|
||||||
graph := chart.Chart{
|
|
||||||
Series: []chart.Series{
|
|
||||||
chart.ContinuousSeries{
|
|
||||||
XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0},
|
|
||||||
YValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
|
||||||
graph.Render(chart.PNG, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawChartWide(res http.ResponseWriter, req *http.Request) {
|
|
||||||
graph := chart.Chart{
|
|
||||||
Width: 1920, //this overrides the default.
|
|
||||||
Series: []chart.Series{
|
|
||||||
chart.ContinuousSeries{
|
|
||||||
XValues: []float64{1.0, 2.0, 3.0, 4.0},
|
|
||||||
YValues: []float64{1.0, 2.0, 3.0, 4.0},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
|
||||||
graph.Render(chart.PNG, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.HandleFunc("/wide", drawChartWide)
|
|
||||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
|
||||||
}
|
|
Before Width: | Height: | Size: 11 KiB |
|
@ -1,79 +0,0 @@
|
||||||
// Usage: http://localhost:8080?series=100&values=1000
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
|
||||||
)
|
|
||||||
|
|
||||||
func random(min, max float64) float64 {
|
|
||||||
return rand.Float64()*(max-min) + min
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawLargeChart(res http.ResponseWriter, r *http.Request) {
|
|
||||||
numSeriesInt64, err := strconv.ParseInt(r.FormValue("series"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
numSeriesInt64 = int64(1)
|
|
||||||
}
|
|
||||||
if numSeriesInt64 == 0 {
|
|
||||||
numSeriesInt64 = 1
|
|
||||||
}
|
|
||||||
numSeries := int(numSeriesInt64)
|
|
||||||
|
|
||||||
numValuesInt64, err := strconv.ParseInt(r.FormValue("values"), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
numValuesInt64 = int64(100)
|
|
||||||
}
|
|
||||||
if numValuesInt64 == 0 {
|
|
||||||
numValuesInt64 = int64(100)
|
|
||||||
}
|
|
||||||
numValues := int(numValuesInt64)
|
|
||||||
|
|
||||||
series := make([]chart.Series, numSeries)
|
|
||||||
|
|
||||||
for i := 0; i < numSeries; i++ {
|
|
||||||
xValues := make([]time.Time, numValues)
|
|
||||||
yValues := make([]float64, numValues)
|
|
||||||
|
|
||||||
for j := 0; j < numValues; j++ {
|
|
||||||
xValues[j] = time.Now().AddDate(0, 0, (numValues-j)*-1)
|
|
||||||
yValues[j] = random(float64(-500), float64(500))
|
|
||||||
}
|
|
||||||
|
|
||||||
series[i] = chart.TimeSeries{
|
|
||||||
Name: fmt.Sprintf("aaa.bbb.hostname-%v.ccc.ddd.eee.fff.ggg.hhh.iii.jjj.kkk.lll.mmm.nnn.value", i),
|
|
||||||
XValues: xValues,
|
|
||||||
YValues: yValues,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
graph := chart.Chart{
|
|
||||||
XAxis: chart.XAxis{
|
|
||||||
Name: "Time",
|
|
||||||
NameStyle: chart.StyleShow(),
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Name: "Value",
|
|
||||||
NameStyle: chart.StyleShow(),
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Series: series,
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
|
||||||
graph.Render(chart.PNG, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawLargeChart)
|
|
||||||
http.HandleFunc("/favico.ico", func(res http.ResponseWriter, req *http.Request) {
|
|
||||||
res.Write([]byte{})
|
|
||||||
})
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 27 KiB |
|
@ -1,67 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
|
||||||
"github.com/wcharczuk/go-chart/drawing"
|
|
||||||
"github.com/wcharczuk/go-chart/seq"
|
|
||||||
)
|
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
|
||||||
graph := chart.Chart{
|
|
||||||
Background: chart.Style{
|
|
||||||
Padding: chart.Box{
|
|
||||||
Top: 50,
|
|
||||||
Left: 25,
|
|
||||||
Right: 25,
|
|
||||||
Bottom: 10,
|
|
||||||
},
|
|
||||||
FillColor: drawing.ColorFromHex("efefef"),
|
|
||||||
},
|
|
||||||
XAxis: chart.XAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Series: []chart.Series{
|
|
||||||
chart.ContinuousSeries{
|
|
||||||
XValues: SeqRange(1.0, 100.0),
|
|
||||||
YValues: seq.RandomValuesWithMax(100, 512),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
|
||||||
graph.Render(chart.PNG, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawChartDefault(res http.ResponseWriter, req *http.Request) {
|
|
||||||
graph := chart.Chart{
|
|
||||||
Background: chart.Style{
|
|
||||||
FillColor: drawing.ColorFromHex("efefef"),
|
|
||||||
},
|
|
||||||
XAxis: chart.XAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Series: []chart.Series{
|
|
||||||
chart.ContinuousSeries{
|
|
||||||
XValues: SeqRange(1.0, 100.0),
|
|
||||||
YValues: seq.RandomValuesWithMax(100, 512),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
|
||||||
graph.Render(chart.PNG, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.HandleFunc("/default", drawChartDefault)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
|
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 19 KiB |
|
@ -1,54 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/wcharczuk/go-chart"
|
|
||||||
)
|
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
|
||||||
pie := chart.DonutChart{
|
|
||||||
Width: 512,
|
|
||||||
Height: 512,
|
|
||||||
Values: []chart.Value{
|
|
||||||
{Value: 5, Label: "Blue"},
|
|
||||||
{Value: 5, Label: "Green"},
|
|
||||||
{Value: 4, Label: "Gray"},
|
|
||||||
{Value: 4, Label: "Orange"},
|
|
||||||
{Value: 3, Label: "Deep Blue"},
|
|
||||||
{Value: 3, Label: "test"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
|
||||||
err := pie.Render(chart.PNG, res)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error rendering pie chart: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func drawChartRegression(res http.ResponseWriter, req *http.Request) {
|
|
||||||
pie := chart.DonutChart{
|
|
||||||
Width: 512,
|
|
||||||
Height: 512,
|
|
||||||
Values: []chart.Value{
|
|
||||||
{Value: 5, Label: "Blue"},
|
|
||||||
{Value: 2, Label: "Two"},
|
|
||||||
{Value: 1, Label: "One"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Header().Set("Content-Type", chart.ContentTypeSVG)
|
|
||||||
err := pie.Render(chart.SVG, res)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error rendering pie chart: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.HandleFunc("/reg", drawChartRegression)
|
|
||||||
log.Fatal(http.ListenAndServe(":8080", nil))
|
|
||||||
}
|
|
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 170 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 40 KiB |
|
@ -4,13 +4,12 @@ import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
"github.com/wcharczuk/go-chart/drawing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAnnotationSeriesMeasure(t *testing.T) {
|
func TestAnnotationSeriesMeasure(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
as := AnnotationSeries{
|
as := AnnotationSeries{
|
||||||
Annotations: []Value2{
|
Annotations: []Value2{
|
||||||
|
@ -22,10 +21,10 @@ func TestAnnotationSeriesMeasure(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := PNG(110, 110)
|
r, err := PNG(110, 110)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
f, err := GetDefaultFont()
|
f, err := GetDefaultFont()
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
xrange := &ContinuousRange{
|
xrange := &ContinuousRange{
|
||||||
Min: 1.0,
|
Min: 1.0,
|
||||||
|
@ -50,15 +49,15 @@ func TestAnnotationSeriesMeasure(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
box := as.Measure(r, cb, xrange, yrange, sd)
|
box := as.Measure(r, cb, xrange, yrange, sd)
|
||||||
assert.False(box.IsZero())
|
testutil.AssertFalse(t, box.IsZero())
|
||||||
assert.Equal(-5.0, box.Top)
|
testutil.AssertEqual(t, -5.0, box.Top)
|
||||||
assert.Equal(5.0, box.Left)
|
testutil.AssertEqual(t, 5.0, box.Left)
|
||||||
assert.Equal(146.0, box.Right) //the top,left annotation sticks up 5px and out ~44px.
|
testutil.AssertEqual(t, 146.0, box.Right) //the top,left annotation sticks up 5px and out ~44px.
|
||||||
assert.Equal(115.0, box.Bottom)
|
testutil.AssertEqual(t, 115.0, box.Bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAnnotationSeriesRender(t *testing.T) {
|
func TestAnnotationSeriesRender(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
as := AnnotationSeries{
|
as := AnnotationSeries{
|
||||||
Style: Style{
|
Style: Style{
|
||||||
|
@ -74,10 +73,10 @@ func TestAnnotationSeriesRender(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := PNG(110, 110)
|
r, err := PNG(110, 110)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
f, err := GetDefaultFont()
|
f, err := GetDefaultFont()
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
xrange := &ContinuousRange{
|
xrange := &ContinuousRange{
|
||||||
Min: 1.0,
|
Min: 1.0,
|
||||||
|
@ -104,13 +103,13 @@ func TestAnnotationSeriesRender(t *testing.T) {
|
||||||
as.Render(r, cb, xrange, yrange, sd)
|
as.Render(r, cb, xrange, yrange, sd)
|
||||||
|
|
||||||
rr, isRaster := r.(*rasterRenderer)
|
rr, isRaster := r.(*rasterRenderer)
|
||||||
assert.True(isRaster)
|
testutil.AssertTrue(t, isRaster)
|
||||||
assert.NotNil(rr)
|
testutil.AssertNotNil(t, rr)
|
||||||
|
|
||||||
c := rr.i.At(38, 70)
|
c := rr.i.At(38, 70)
|
||||||
converted, isRGBA := color.RGBAModel.Convert(c).(color.RGBA)
|
converted, isRGBA := color.RGBAModel.Convert(c).(color.RGBA)
|
||||||
assert.True(isRGBA)
|
testutil.AssertTrue(t, isRGBA)
|
||||||
assert.Equal(0, converted.R)
|
testutil.AssertEqual(t, 0, converted.R)
|
||||||
assert.Equal(0, converted.G)
|
testutil.AssertEqual(t, 0, converted.G)
|
||||||
assert.Equal(0, converted.B)
|
testutil.AssertEqual(t, 0, converted.B)
|
||||||
}
|
}
|
||||||
|
|
27
bar_chart.go
|
@ -264,32 +264,7 @@ func (bc BarChart) drawXAxis(r Renderer, canvasBox Box) {
|
||||||
|
|
||||||
func (bc BarChart) drawYAxis(r Renderer, canvasBox Box, yr Range, ticks []Tick) {
|
func (bc BarChart) drawYAxis(r Renderer, canvasBox Box, yr Range, ticks []Tick) {
|
||||||
if !bc.YAxis.Style.Hidden {
|
if !bc.YAxis.Style.Hidden {
|
||||||
axisStyle := bc.YAxis.Style.InheritFrom(bc.styleDefaultsAxes())
|
bc.YAxis.Render(r, canvasBox, yr, bc.styleDefaultsAxes(), ticks)
|
||||||
axisStyle.WriteToRenderer(r)
|
|
||||||
|
|
||||||
r.MoveTo(canvasBox.Right, canvasBox.Top)
|
|
||||||
r.LineTo(canvasBox.Right, canvasBox.Bottom)
|
|
||||||
r.Stroke()
|
|
||||||
|
|
||||||
r.MoveTo(canvasBox.Right, canvasBox.Bottom)
|
|
||||||
r.LineTo(canvasBox.Right+DefaultHorizontalTickWidth, canvasBox.Bottom)
|
|
||||||
r.Stroke()
|
|
||||||
|
|
||||||
var ty int
|
|
||||||
var tb Box
|
|
||||||
for _, t := range ticks {
|
|
||||||
ty = canvasBox.Bottom - yr.Translate(t.Value)
|
|
||||||
|
|
||||||
axisStyle.GetStrokeOptions().WriteToRenderer(r)
|
|
||||||
r.MoveTo(canvasBox.Right, ty)
|
|
||||||
r.LineTo(canvasBox.Right+DefaultHorizontalTickWidth, ty)
|
|
||||||
r.Stroke()
|
|
||||||
|
|
||||||
axisStyle.GetTextOptions().WriteToRenderer(r)
|
|
||||||
tb = r.MeasureText(t.Label)
|
|
||||||
Draw.Text(r, t.Label, canvasBox.Right+DefaultYAxisMargin+5, ty+(tb.Height()>>1), axisStyle)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
assert "github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBarChartRender(t *testing.T) {
|
func TestBarChartRender(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
Width: 1024,
|
Width: 1024,
|
||||||
|
@ -25,12 +25,12 @@ func TestBarChartRender(t *testing.T) {
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
err := bc.Render(PNG, buf)
|
err := bc.Render(PNG, buf)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
assert.NotZero(buf.Len())
|
testutil.AssertNotZero(t, buf.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartRenderZero(t *testing.T) {
|
func TestBarChartRenderZero(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
Width: 1024,
|
Width: 1024,
|
||||||
|
@ -43,64 +43,64 @@ func TestBarChartRenderZero(t *testing.T) {
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
err := bc.Render(PNG, buf)
|
err := bc.Render(PNG, buf)
|
||||||
assert.NotNil(err)
|
testutil.AssertNotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartProps(t *testing.T) {
|
func TestBarChartProps(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
|
|
||||||
assert.Equal(DefaultDPI, bc.GetDPI())
|
testutil.AssertEqual(t, DefaultDPI, bc.GetDPI())
|
||||||
bc.DPI = 100
|
bc.DPI = 100
|
||||||
assert.Equal(100, bc.GetDPI())
|
testutil.AssertEqual(t, 100, bc.GetDPI())
|
||||||
|
|
||||||
assert.Nil(bc.GetFont())
|
testutil.AssertNil(t, bc.GetFont())
|
||||||
f, err := GetDefaultFont()
|
f, err := GetDefaultFont()
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
bc.Font = f
|
bc.Font = f
|
||||||
assert.NotNil(bc.GetFont())
|
testutil.AssertNotNil(t, bc.GetFont())
|
||||||
|
|
||||||
assert.Equal(DefaultChartWidth, bc.GetWidth())
|
testutil.AssertEqual(t, DefaultChartWidth, bc.GetWidth())
|
||||||
bc.Width = DefaultChartWidth - 1
|
bc.Width = DefaultChartWidth - 1
|
||||||
assert.Equal(DefaultChartWidth-1, bc.GetWidth())
|
testutil.AssertEqual(t, DefaultChartWidth-1, bc.GetWidth())
|
||||||
|
|
||||||
assert.Equal(DefaultChartHeight, bc.GetHeight())
|
testutil.AssertEqual(t, DefaultChartHeight, bc.GetHeight())
|
||||||
bc.Height = DefaultChartHeight - 1
|
bc.Height = DefaultChartHeight - 1
|
||||||
assert.Equal(DefaultChartHeight-1, bc.GetHeight())
|
testutil.AssertEqual(t, DefaultChartHeight-1, bc.GetHeight())
|
||||||
|
|
||||||
assert.Equal(DefaultBarSpacing, bc.GetBarSpacing())
|
testutil.AssertEqual(t, DefaultBarSpacing, bc.GetBarSpacing())
|
||||||
bc.BarSpacing = 150
|
bc.BarSpacing = 150
|
||||||
assert.Equal(150, bc.GetBarSpacing())
|
testutil.AssertEqual(t, 150, bc.GetBarSpacing())
|
||||||
|
|
||||||
assert.Equal(DefaultBarWidth, bc.GetBarWidth())
|
testutil.AssertEqual(t, DefaultBarWidth, bc.GetBarWidth())
|
||||||
bc.BarWidth = 75
|
bc.BarWidth = 75
|
||||||
assert.Equal(75, bc.GetBarWidth())
|
testutil.AssertEqual(t, 75, bc.GetBarWidth())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartRenderNoBars(t *testing.T) {
|
func TestBarChartRenderNoBars(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
err := bc.Render(PNG, bytes.NewBuffer([]byte{}))
|
err := bc.Render(PNG, bytes.NewBuffer([]byte{}))
|
||||||
assert.NotNil(err)
|
testutil.AssertNotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetRanges(t *testing.T) {
|
func TestBarChartGetRanges(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
|
|
||||||
yr := bc.getRanges()
|
yr := bc.getRanges()
|
||||||
assert.NotNil(yr)
|
testutil.AssertNotNil(t, yr)
|
||||||
assert.False(yr.IsZero())
|
testutil.AssertFalse(t, yr.IsZero())
|
||||||
|
|
||||||
assert.Equal(-math.MaxFloat64, yr.GetMax())
|
testutil.AssertEqual(t, -math.MaxFloat64, yr.GetMax())
|
||||||
assert.Equal(math.MaxFloat64, yr.GetMin())
|
testutil.AssertEqual(t, math.MaxFloat64, yr.GetMin())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetRangesBarsMinMax(t *testing.T) {
|
func TestBarChartGetRangesBarsMinMax(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
Bars: []Value{
|
Bars: []Value{
|
||||||
|
@ -110,15 +110,15 @@ func TestBarChartGetRangesBarsMinMax(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
yr := bc.getRanges()
|
yr := bc.getRanges()
|
||||||
assert.NotNil(yr)
|
testutil.AssertNotNil(t, yr)
|
||||||
assert.False(yr.IsZero())
|
testutil.AssertFalse(t, yr.IsZero())
|
||||||
|
|
||||||
assert.Equal(10, yr.GetMax())
|
testutil.AssertEqual(t, 10, yr.GetMax())
|
||||||
assert.Equal(1, yr.GetMin())
|
testutil.AssertEqual(t, 1, yr.GetMin())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetRangesMinMax(t *testing.T) {
|
func TestBarChartGetRangesMinMax(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
YAxis: YAxis{
|
YAxis: YAxis{
|
||||||
|
@ -138,15 +138,15 @@ func TestBarChartGetRangesMinMax(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
yr := bc.getRanges()
|
yr := bc.getRanges()
|
||||||
assert.NotNil(yr)
|
testutil.AssertNotNil(t, yr)
|
||||||
assert.False(yr.IsZero())
|
testutil.AssertFalse(t, yr.IsZero())
|
||||||
|
|
||||||
assert.Equal(15, yr.GetMax())
|
testutil.AssertEqual(t, 15, yr.GetMax())
|
||||||
assert.Equal(5, yr.GetMin())
|
testutil.AssertEqual(t, 5, yr.GetMin())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetRangesTicksMinMax(t *testing.T) {
|
func TestBarChartGetRangesTicksMinMax(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
YAxis: YAxis{
|
YAxis: YAxis{
|
||||||
|
@ -162,56 +162,56 @@ func TestBarChartGetRangesTicksMinMax(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
yr := bc.getRanges()
|
yr := bc.getRanges()
|
||||||
assert.NotNil(yr)
|
testutil.AssertNotNil(t, yr)
|
||||||
assert.False(yr.IsZero())
|
testutil.AssertFalse(t, yr.IsZero())
|
||||||
|
|
||||||
assert.Equal(11, yr.GetMax())
|
testutil.AssertEqual(t, 11, yr.GetMax())
|
||||||
assert.Equal(7, yr.GetMin())
|
testutil.AssertEqual(t, 7, yr.GetMin())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartHasAxes(t *testing.T) {
|
func TestBarChartHasAxes(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
assert.True(bc.hasAxes())
|
testutil.AssertTrue(t, bc.hasAxes())
|
||||||
bc.YAxis = YAxis{
|
bc.YAxis = YAxis{
|
||||||
Style: Hidden(),
|
Style: Hidden(),
|
||||||
}
|
}
|
||||||
assert.False(bc.hasAxes())
|
testutil.AssertFalse(t, bc.hasAxes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetDefaultCanvasBox(t *testing.T) {
|
func TestBarChartGetDefaultCanvasBox(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
b := bc.getDefaultCanvasBox()
|
b := bc.getDefaultCanvasBox()
|
||||||
assert.False(b.IsZero())
|
testutil.AssertFalse(t, b.IsZero())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartSetRangeDomains(t *testing.T) {
|
func TestBarChartSetRangeDomains(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
cb := bc.box()
|
cb := bc.box()
|
||||||
yr := bc.getRanges()
|
yr := bc.getRanges()
|
||||||
yr2 := bc.setRangeDomains(cb, yr)
|
yr2 := bc.setRangeDomains(cb, yr)
|
||||||
assert.NotZero(yr2.GetDomain())
|
testutil.AssertNotZero(t, yr2.GetDomain())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetValueFormatters(t *testing.T) {
|
func TestBarChartGetValueFormatters(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{}
|
bc := BarChart{}
|
||||||
vf := bc.getValueFormatters()
|
vf := bc.getValueFormatters()
|
||||||
assert.NotNil(vf)
|
testutil.AssertNotNil(t, vf)
|
||||||
assert.Equal("1234.00", vf(1234.0))
|
testutil.AssertEqual(t, "1234.00", vf(1234.0))
|
||||||
|
|
||||||
bc.YAxis.ValueFormatter = func(_ interface{}) string { return "test" }
|
bc.YAxis.ValueFormatter = func(_ interface{}) string { return "test" }
|
||||||
assert.Equal("test", bc.getValueFormatters()(1234))
|
testutil.AssertEqual(t, "test", bc.getValueFormatters()(1234))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartGetAxesTicks(t *testing.T) {
|
func TestBarChartGetAxesTicks(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
Bars: []Value{
|
Bars: []Value{
|
||||||
|
@ -222,21 +222,21 @@ func TestBarChartGetAxesTicks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := PNG(128, 128)
|
r, err := PNG(128, 128)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
yr := bc.getRanges()
|
yr := bc.getRanges()
|
||||||
yf := bc.getValueFormatters()
|
yf := bc.getValueFormatters()
|
||||||
|
|
||||||
bc.YAxis.Style.Hidden = true
|
bc.YAxis.Style.Hidden = true
|
||||||
ticks := bc.getAxesTicks(r, yr, yf)
|
ticks := bc.getAxesTicks(r, yr, yf)
|
||||||
assert.Empty(ticks)
|
testutil.AssertEmpty(t, ticks)
|
||||||
|
|
||||||
bc.YAxis.Style.Hidden = false
|
bc.YAxis.Style.Hidden = false
|
||||||
ticks = bc.getAxesTicks(r, yr, yf)
|
ticks = bc.getAxesTicks(r, yr, yf)
|
||||||
assert.Len(ticks, 2)
|
testutil.AssertLen(t, ticks, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartCalculateEffectiveBarSpacing(t *testing.T) {
|
func TestBarChartCalculateEffectiveBarSpacing(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
Width: 1024,
|
Width: 1024,
|
||||||
|
@ -251,15 +251,15 @@ func TestBarChartCalculateEffectiveBarSpacing(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
spacing := bc.calculateEffectiveBarSpacing(bc.box())
|
spacing := bc.calculateEffectiveBarSpacing(bc.box())
|
||||||
assert.NotZero(spacing)
|
testutil.AssertNotZero(t, spacing)
|
||||||
|
|
||||||
bc.BarWidth = 250
|
bc.BarWidth = 250
|
||||||
spacing = bc.calculateEffectiveBarSpacing(bc.box())
|
spacing = bc.calculateEffectiveBarSpacing(bc.box())
|
||||||
assert.Zero(spacing)
|
testutil.AssertZero(t, spacing)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChartCalculateEffectiveBarWidth(t *testing.T) {
|
func TestBarChartCalculateEffectiveBarWidth(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BarChart{
|
bc := BarChart{
|
||||||
Width: 1024,
|
Width: 1024,
|
||||||
|
@ -276,35 +276,35 @@ func TestBarChartCalculateEffectiveBarWidth(t *testing.T) {
|
||||||
cb := bc.box()
|
cb := bc.box()
|
||||||
|
|
||||||
spacing := bc.calculateEffectiveBarSpacing(bc.box())
|
spacing := bc.calculateEffectiveBarSpacing(bc.box())
|
||||||
assert.NotZero(spacing)
|
testutil.AssertNotZero(t, spacing)
|
||||||
|
|
||||||
barWidth := bc.calculateEffectiveBarWidth(bc.box(), spacing)
|
barWidth := bc.calculateEffectiveBarWidth(bc.box(), spacing)
|
||||||
assert.Equal(10, barWidth)
|
testutil.AssertEqual(t, 10, barWidth)
|
||||||
|
|
||||||
bc.BarWidth = 250
|
bc.BarWidth = 250
|
||||||
spacing = bc.calculateEffectiveBarSpacing(bc.box())
|
spacing = bc.calculateEffectiveBarSpacing(bc.box())
|
||||||
assert.Zero(spacing)
|
testutil.AssertZero(t, spacing)
|
||||||
barWidth = bc.calculateEffectiveBarWidth(bc.box(), spacing)
|
barWidth = bc.calculateEffectiveBarWidth(bc.box(), spacing)
|
||||||
assert.Equal(199, barWidth)
|
testutil.AssertEqual(t, 199, barWidth)
|
||||||
|
|
||||||
assert.Equal(cb.Width()+1, bc.calculateTotalBarWidth(barWidth, spacing))
|
testutil.AssertEqual(t, cb.Width()+1, bc.calculateTotalBarWidth(barWidth, spacing))
|
||||||
|
|
||||||
bw, bs, total := bc.calculateScaledTotalWidth(cb)
|
bw, bs, total := bc.calculateScaledTotalWidth(cb)
|
||||||
assert.Equal(spacing, bs)
|
testutil.AssertEqual(t, spacing, bs)
|
||||||
assert.Equal(barWidth, bw)
|
testutil.AssertEqual(t, barWidth, bw)
|
||||||
assert.Equal(cb.Width()+1, total)
|
testutil.AssertEqual(t, cb.Width()+1, total)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBarChatGetTitleFontSize(t *testing.T) {
|
func TestBarChatGetTitleFontSize(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
size := BarChart{Width: 2049, Height: 2049}.getTitleFontSize()
|
size := BarChart{Width: 2049, Height: 2049}.getTitleFontSize()
|
||||||
assert.Equal(48, size)
|
testutil.AssertEqual(t, 48, size)
|
||||||
size = BarChart{Width: 1025, Height: 1025}.getTitleFontSize()
|
size = BarChart{Width: 1025, Height: 1025}.getTitleFontSize()
|
||||||
assert.Equal(24, size)
|
testutil.AssertEqual(t, 24, size)
|
||||||
size = BarChart{Width: 513, Height: 513}.getTitleFontSize()
|
size = BarChart{Width: 513, Height: 513}.getTitleFontSize()
|
||||||
assert.Equal(18, size)
|
testutil.AssertEqual(t, 18, size)
|
||||||
size = BarChart{Width: 257, Height: 257}.getTitleFontSize()
|
size = BarChart{Width: 257, Height: 257}.getTitleFontSize()
|
||||||
assert.Equal(12, size)
|
testutil.AssertEqual(t, 12, size)
|
||||||
size = BarChart{Width: 128, Height: 128}.getTitleFontSize()
|
size = BarChart{Width: 128, Height: 128}.getTitleFontSize()
|
||||||
assert.Equal(10, size)
|
testutil.AssertEqual(t, 10, size)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBollingerBandSeries(t *testing.T) {
|
func TestBollingerBandSeries(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
s1 := mockValuesProvider{
|
s1 := mockValuesProvider{
|
||||||
X: LinearRange(1.0, 100.0),
|
X: LinearRange(1.0, 100.0),
|
||||||
|
@ -29,12 +29,12 @@ func TestBollingerBandSeries(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for x := bbs.GetPeriod(); x < 100; x++ {
|
for x := bbs.GetPeriod(); x < 100; x++ {
|
||||||
assert.True(y1values[x] > y2values[x], fmt.Sprintf("%v vs. %v", y1values[x], y2values[x]))
|
testutil.AssertTrue(t, y1values[x] > y2values[x], fmt.Sprintf("%v vs. %v", y1values[x], y2values[x]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBollingerBandLastValue(t *testing.T) {
|
func TestBollingerBandLastValue(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
s1 := mockValuesProvider{
|
s1 := mockValuesProvider{
|
||||||
X: LinearRange(1.0, 100.0),
|
X: LinearRange(1.0, 100.0),
|
||||||
|
@ -46,7 +46,7 @@ func TestBollingerBandLastValue(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
x, y1, y2 := bbs.GetBoundedLastValues()
|
x, y1, y2 := bbs.GetBoundedLastValues()
|
||||||
assert.Equal(100.0, x)
|
testutil.AssertEqual(t, 100.0, x)
|
||||||
assert.Equal(101, math.Floor(y1))
|
testutil.AssertEqual(t, 101, math.Floor(y1))
|
||||||
assert.Equal(83, math.Floor(y2))
|
testutil.AssertEqual(t, 83, math.Floor(y2))
|
||||||
}
|
}
|
||||||
|
|
16
box.go
|
@ -254,6 +254,22 @@ func (b Box) OuterConstrain(bounds, other Box) Box {
|
||||||
return newBox
|
return newBox
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b Box) Validate() error {
|
||||||
|
if b.Left < 0 {
|
||||||
|
return fmt.Errorf("invalid left; must be >= 0")
|
||||||
|
}
|
||||||
|
if b.Right < 0 {
|
||||||
|
return fmt.Errorf("invalid right; must be > 0")
|
||||||
|
}
|
||||||
|
if b.Top < 0 {
|
||||||
|
return fmt.Errorf("invalid top; must be > 0")
|
||||||
|
}
|
||||||
|
if b.Bottom < 0 {
|
||||||
|
return fmt.Errorf("invalid bottom; must be > 0")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// BoxCorners is a box with independent corners.
|
// BoxCorners is a box with independent corners.
|
||||||
type BoxCorners struct {
|
type BoxCorners struct {
|
||||||
TopLeft, TopRight, BottomRight, BottomLeft Point
|
TopLeft, TopRight, BottomRight, BottomLeft Point
|
||||||
|
|
134
box_test.go
|
@ -4,131 +4,131 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBoxClone(t *testing.T) {
|
func TestBoxClone(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
a := Box{Top: 5, Left: 5, Right: 15, Bottom: 15}
|
a := Box{Top: 5, Left: 5, Right: 15, Bottom: 15}
|
||||||
b := a.Clone()
|
b := a.Clone()
|
||||||
assert.True(a.Equals(b))
|
testutil.AssertTrue(t, a.Equals(b))
|
||||||
assert.True(b.Equals(a))
|
testutil.AssertTrue(t, b.Equals(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxEquals(t *testing.T) {
|
func TestBoxEquals(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
a := Box{Top: 5, Left: 5, Right: 15, Bottom: 15}
|
a := Box{Top: 5, Left: 5, Right: 15, Bottom: 15}
|
||||||
b := Box{Top: 10, Left: 10, Right: 30, Bottom: 30}
|
b := Box{Top: 10, Left: 10, Right: 30, Bottom: 30}
|
||||||
c := Box{Top: 5, Left: 5, Right: 15, Bottom: 15}
|
c := Box{Top: 5, Left: 5, Right: 15, Bottom: 15}
|
||||||
assert.True(a.Equals(a))
|
testutil.AssertTrue(t, a.Equals(a))
|
||||||
assert.True(a.Equals(c))
|
testutil.AssertTrue(t, a.Equals(c))
|
||||||
assert.True(c.Equals(a))
|
testutil.AssertTrue(t, c.Equals(a))
|
||||||
assert.False(a.Equals(b))
|
testutil.AssertFalse(t, a.Equals(b))
|
||||||
assert.False(c.Equals(b))
|
testutil.AssertFalse(t, c.Equals(b))
|
||||||
assert.False(b.Equals(a))
|
testutil.AssertFalse(t, b.Equals(a))
|
||||||
assert.False(b.Equals(c))
|
testutil.AssertFalse(t, b.Equals(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxIsBiggerThan(t *testing.T) {
|
func TestBoxIsBiggerThan(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
a := Box{Top: 5, Left: 5, Right: 25, Bottom: 25}
|
a := Box{Top: 5, Left: 5, Right: 25, Bottom: 25}
|
||||||
b := Box{Top: 10, Left: 10, Right: 20, Bottom: 20} // only half bigger
|
b := Box{Top: 10, Left: 10, Right: 20, Bottom: 20} // only half bigger
|
||||||
c := Box{Top: 1, Left: 1, Right: 30, Bottom: 30} //bigger
|
c := Box{Top: 1, Left: 1, Right: 30, Bottom: 30} //bigger
|
||||||
assert.True(a.IsBiggerThan(b))
|
testutil.AssertTrue(t, a.IsBiggerThan(b))
|
||||||
assert.False(a.IsBiggerThan(c))
|
testutil.AssertFalse(t, a.IsBiggerThan(c))
|
||||||
assert.True(c.IsBiggerThan(a))
|
testutil.AssertTrue(t, c.IsBiggerThan(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxIsSmallerThan(t *testing.T) {
|
func TestBoxIsSmallerThan(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
a := Box{Top: 5, Left: 5, Right: 25, Bottom: 25}
|
a := Box{Top: 5, Left: 5, Right: 25, Bottom: 25}
|
||||||
b := Box{Top: 10, Left: 10, Right: 20, Bottom: 20} // only half bigger
|
b := Box{Top: 10, Left: 10, Right: 20, Bottom: 20} // only half bigger
|
||||||
c := Box{Top: 1, Left: 1, Right: 30, Bottom: 30} //bigger
|
c := Box{Top: 1, Left: 1, Right: 30, Bottom: 30} //bigger
|
||||||
assert.False(a.IsSmallerThan(b))
|
testutil.AssertFalse(t, a.IsSmallerThan(b))
|
||||||
assert.True(a.IsSmallerThan(c))
|
testutil.AssertTrue(t, a.IsSmallerThan(c))
|
||||||
assert.False(c.IsSmallerThan(a))
|
testutil.AssertFalse(t, c.IsSmallerThan(a))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxGrow(t *testing.T) {
|
func TestBoxGrow(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
a := Box{Top: 1, Left: 2, Right: 15, Bottom: 15}
|
a := Box{Top: 1, Left: 2, Right: 15, Bottom: 15}
|
||||||
b := Box{Top: 4, Left: 5, Right: 30, Bottom: 35}
|
b := Box{Top: 4, Left: 5, Right: 30, Bottom: 35}
|
||||||
c := a.Grow(b)
|
c := a.Grow(b)
|
||||||
assert.False(c.Equals(b))
|
testutil.AssertFalse(t, c.Equals(b))
|
||||||
assert.False(c.Equals(a))
|
testutil.AssertFalse(t, c.Equals(a))
|
||||||
assert.Equal(1, c.Top)
|
testutil.AssertEqual(t, 1, c.Top)
|
||||||
assert.Equal(2, c.Left)
|
testutil.AssertEqual(t, 2, c.Left)
|
||||||
assert.Equal(30, c.Right)
|
testutil.AssertEqual(t, 30, c.Right)
|
||||||
assert.Equal(35, c.Bottom)
|
testutil.AssertEqual(t, 35, c.Bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxFit(t *testing.T) {
|
func TestBoxFit(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
a := Box{Top: 64, Left: 64, Right: 192, Bottom: 192}
|
a := Box{Top: 64, Left: 64, Right: 192, Bottom: 192}
|
||||||
b := Box{Top: 16, Left: 16, Right: 256, Bottom: 170}
|
b := Box{Top: 16, Left: 16, Right: 256, Bottom: 170}
|
||||||
c := Box{Top: 16, Left: 16, Right: 170, Bottom: 256}
|
c := Box{Top: 16, Left: 16, Right: 170, Bottom: 256}
|
||||||
|
|
||||||
fab := a.Fit(b)
|
fab := a.Fit(b)
|
||||||
assert.Equal(a.Left, fab.Left)
|
testutil.AssertEqual(t, a.Left, fab.Left)
|
||||||
assert.Equal(a.Right, fab.Right)
|
testutil.AssertEqual(t, a.Right, fab.Right)
|
||||||
assert.True(fab.Top < fab.Bottom)
|
testutil.AssertTrue(t, fab.Top < fab.Bottom)
|
||||||
assert.True(fab.Left < fab.Right)
|
testutil.AssertTrue(t, fab.Left < fab.Right)
|
||||||
assert.True(math.Abs(b.Aspect()-fab.Aspect()) < 0.02)
|
testutil.AssertTrue(t, math.Abs(b.Aspect()-fab.Aspect()) < 0.02)
|
||||||
|
|
||||||
fac := a.Fit(c)
|
fac := a.Fit(c)
|
||||||
assert.Equal(a.Top, fac.Top)
|
testutil.AssertEqual(t, a.Top, fac.Top)
|
||||||
assert.Equal(a.Bottom, fac.Bottom)
|
testutil.AssertEqual(t, a.Bottom, fac.Bottom)
|
||||||
assert.True(math.Abs(c.Aspect()-fac.Aspect()) < 0.02)
|
testutil.AssertTrue(t, math.Abs(c.Aspect()-fac.Aspect()) < 0.02)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxConstrain(t *testing.T) {
|
func TestBoxConstrain(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
a := Box{Top: 64, Left: 64, Right: 192, Bottom: 192}
|
a := Box{Top: 64, Left: 64, Right: 192, Bottom: 192}
|
||||||
b := Box{Top: 16, Left: 16, Right: 256, Bottom: 170}
|
b := Box{Top: 16, Left: 16, Right: 256, Bottom: 170}
|
||||||
c := Box{Top: 16, Left: 16, Right: 170, Bottom: 256}
|
c := Box{Top: 16, Left: 16, Right: 170, Bottom: 256}
|
||||||
|
|
||||||
cab := a.Constrain(b)
|
cab := a.Constrain(b)
|
||||||
assert.Equal(64, cab.Top)
|
testutil.AssertEqual(t, 64, cab.Top)
|
||||||
assert.Equal(64, cab.Left)
|
testutil.AssertEqual(t, 64, cab.Left)
|
||||||
assert.Equal(192, cab.Right)
|
testutil.AssertEqual(t, 192, cab.Right)
|
||||||
assert.Equal(170, cab.Bottom)
|
testutil.AssertEqual(t, 170, cab.Bottom)
|
||||||
|
|
||||||
cac := a.Constrain(c)
|
cac := a.Constrain(c)
|
||||||
assert.Equal(64, cac.Top)
|
testutil.AssertEqual(t, 64, cac.Top)
|
||||||
assert.Equal(64, cac.Left)
|
testutil.AssertEqual(t, 64, cac.Left)
|
||||||
assert.Equal(170, cac.Right)
|
testutil.AssertEqual(t, 170, cac.Right)
|
||||||
assert.Equal(192, cac.Bottom)
|
testutil.AssertEqual(t, 192, cac.Bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxOuterConstrain(t *testing.T) {
|
func TestBoxOuterConstrain(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
box := NewBox(0, 0, 100, 100)
|
box := NewBox(0, 0, 100, 100)
|
||||||
canvas := NewBox(5, 5, 95, 95)
|
canvas := NewBox(5, 5, 95, 95)
|
||||||
taller := NewBox(-10, 5, 50, 50)
|
taller := NewBox(-10, 5, 50, 50)
|
||||||
|
|
||||||
c := canvas.OuterConstrain(box, taller)
|
c := canvas.OuterConstrain(box, taller)
|
||||||
assert.Equal(15, c.Top, c.String())
|
testutil.AssertEqual(t, 15, c.Top, c.String())
|
||||||
assert.Equal(5, c.Left, c.String())
|
testutil.AssertEqual(t, 5, c.Left, c.String())
|
||||||
assert.Equal(95, c.Right, c.String())
|
testutil.AssertEqual(t, 95, c.Right, c.String())
|
||||||
assert.Equal(95, c.Bottom, c.String())
|
testutil.AssertEqual(t, 95, c.Bottom, c.String())
|
||||||
|
|
||||||
wider := NewBox(5, 5, 110, 50)
|
wider := NewBox(5, 5, 110, 50)
|
||||||
d := canvas.OuterConstrain(box, wider)
|
d := canvas.OuterConstrain(box, wider)
|
||||||
assert.Equal(5, d.Top, d.String())
|
testutil.AssertEqual(t, 5, d.Top, d.String())
|
||||||
assert.Equal(5, d.Left, d.String())
|
testutil.AssertEqual(t, 5, d.Left, d.String())
|
||||||
assert.Equal(85, d.Right, d.String())
|
testutil.AssertEqual(t, 85, d.Right, d.String())
|
||||||
assert.Equal(95, d.Bottom, d.String())
|
testutil.AssertEqual(t, 95, d.Bottom, d.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxShift(t *testing.T) {
|
func TestBoxShift(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
b := Box{
|
b := Box{
|
||||||
Top: 5,
|
Top: 5,
|
||||||
|
@ -138,14 +138,14 @@ func TestBoxShift(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
shifted := b.Shift(1, 2)
|
shifted := b.Shift(1, 2)
|
||||||
assert.Equal(7, shifted.Top)
|
testutil.AssertEqual(t, 7, shifted.Top)
|
||||||
assert.Equal(6, shifted.Left)
|
testutil.AssertEqual(t, 6, shifted.Left)
|
||||||
assert.Equal(11, shifted.Right)
|
testutil.AssertEqual(t, 11, shifted.Right)
|
||||||
assert.Equal(12, shifted.Bottom)
|
testutil.AssertEqual(t, 12, shifted.Bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxCenter(t *testing.T) {
|
func TestBoxCenter(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
b := Box{
|
b := Box{
|
||||||
Top: 10,
|
Top: 10,
|
||||||
|
@ -154,12 +154,12 @@ func TestBoxCenter(t *testing.T) {
|
||||||
Bottom: 30,
|
Bottom: 30,
|
||||||
}
|
}
|
||||||
cx, cy := b.Center()
|
cx, cy := b.Center()
|
||||||
assert.Equal(15, cx)
|
testutil.AssertEqual(t, 15, cx)
|
||||||
assert.Equal(20, cy)
|
testutil.AssertEqual(t, 20, cy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxCornersCenter(t *testing.T) {
|
func TestBoxCornersCenter(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BoxCorners{
|
bc := BoxCorners{
|
||||||
TopLeft: Point{5, 5},
|
TopLeft: Point{5, 5},
|
||||||
|
@ -169,12 +169,12 @@ func TestBoxCornersCenter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cx, cy := bc.Center()
|
cx, cy := bc.Center()
|
||||||
assert.Equal(10, cx)
|
testutil.AssertEqual(t, 10, cx)
|
||||||
assert.Equal(10, cy)
|
testutil.AssertEqual(t, 10, cy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBoxCornersRotate(t *testing.T) {
|
func TestBoxCornersRotate(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
bc := BoxCorners{
|
bc := BoxCorners{
|
||||||
TopLeft: Point{5, 5},
|
TopLeft: Point{5, 5},
|
||||||
|
@ -184,5 +184,5 @@ func TestBoxCornersRotate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
rotated := bc.Rotate(45)
|
rotated := bc.Rotate(45)
|
||||||
assert.True(rotated.TopLeft.Equals(Point{10, 3}), rotated.String())
|
testutil.AssertTrue(t, rotated.TopLeft.Equals(Point{10, 3}), rotated.String())
|
||||||
}
|
}
|
||||||
|
|
224
chart_test.go
|
@ -8,58 +8,57 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
"github.com/wcharczuk/go-chart/drawing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestChartGetDPI(t *testing.T) {
|
func TestChartGetDPI(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
unset := Chart{}
|
unset := Chart{}
|
||||||
assert.Equal(DefaultDPI, unset.GetDPI())
|
testutil.AssertEqual(t, DefaultDPI, unset.GetDPI())
|
||||||
assert.Equal(192, unset.GetDPI(192))
|
testutil.AssertEqual(t, 192, unset.GetDPI(192))
|
||||||
|
|
||||||
set := Chart{DPI: 128}
|
set := Chart{DPI: 128}
|
||||||
assert.Equal(128, set.GetDPI())
|
testutil.AssertEqual(t, 128, set.GetDPI())
|
||||||
assert.Equal(128, set.GetDPI(192))
|
testutil.AssertEqual(t, 128, set.GetDPI(192))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetFont(t *testing.T) {
|
func TestChartGetFont(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
f, err := GetDefaultFont()
|
f, err := GetDefaultFont()
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
unset := Chart{}
|
unset := Chart{}
|
||||||
assert.Nil(unset.GetFont())
|
testutil.AssertNil(t, unset.GetFont())
|
||||||
|
|
||||||
set := Chart{Font: f}
|
set := Chart{Font: f}
|
||||||
assert.NotNil(set.GetFont())
|
testutil.AssertNotNil(t, set.GetFont())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetWidth(t *testing.T) {
|
func TestChartGetWidth(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
unset := Chart{}
|
unset := Chart{}
|
||||||
assert.Equal(DefaultChartWidth, unset.GetWidth())
|
testutil.AssertEqual(t, DefaultChartWidth, unset.GetWidth())
|
||||||
|
|
||||||
set := Chart{Width: DefaultChartWidth + 10}
|
set := Chart{Width: DefaultChartWidth + 10}
|
||||||
assert.Equal(DefaultChartWidth+10, set.GetWidth())
|
testutil.AssertEqual(t, DefaultChartWidth+10, set.GetWidth())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetHeight(t *testing.T) {
|
func TestChartGetHeight(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
unset := Chart{}
|
unset := Chart{}
|
||||||
assert.Equal(DefaultChartHeight, unset.GetHeight())
|
testutil.AssertEqual(t, DefaultChartHeight, unset.GetHeight())
|
||||||
|
|
||||||
set := Chart{Height: DefaultChartHeight + 10}
|
set := Chart{Height: DefaultChartHeight + 10}
|
||||||
assert.Equal(DefaultChartHeight+10, set.GetHeight())
|
testutil.AssertEqual(t, DefaultChartHeight+10, set.GetHeight())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetRanges(t *testing.T) {
|
func TestChartGetRanges(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Series: []Series{
|
Series: []Series{
|
||||||
|
@ -80,14 +79,14 @@ func TestChartGetRanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xrange, yrange, yrangeAlt := c.getRanges()
|
xrange, yrange, yrangeAlt := c.getRanges()
|
||||||
assert.Equal(-2.0, xrange.GetMin())
|
testutil.AssertEqual(t, -2.0, xrange.GetMin())
|
||||||
assert.Equal(5.0, xrange.GetMax())
|
testutil.AssertEqual(t, 5.0, xrange.GetMax())
|
||||||
|
|
||||||
assert.Equal(-2.1, yrange.GetMin())
|
testutil.AssertEqual(t, -2.1, yrange.GetMin())
|
||||||
assert.Equal(4.5, yrange.GetMax())
|
testutil.AssertEqual(t, 4.5, yrange.GetMax())
|
||||||
|
|
||||||
assert.Equal(10.0, yrangeAlt.GetMin())
|
testutil.AssertEqual(t, 10.0, yrangeAlt.GetMin())
|
||||||
assert.Equal(14.0, yrangeAlt.GetMax())
|
testutil.AssertEqual(t, 14.0, yrangeAlt.GetMax())
|
||||||
|
|
||||||
cSet := Chart{
|
cSet := Chart{
|
||||||
XAxis: XAxis{
|
XAxis: XAxis{
|
||||||
|
@ -117,18 +116,18 @@ func TestChartGetRanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xr2, yr2, yra2 := cSet.getRanges()
|
xr2, yr2, yra2 := cSet.getRanges()
|
||||||
assert.Equal(9.8, xr2.GetMin())
|
testutil.AssertEqual(t, 9.8, xr2.GetMin())
|
||||||
assert.Equal(19.8, xr2.GetMax())
|
testutil.AssertEqual(t, 19.8, xr2.GetMax())
|
||||||
|
|
||||||
assert.Equal(9.9, yr2.GetMin())
|
testutil.AssertEqual(t, 9.9, yr2.GetMin())
|
||||||
assert.Equal(19.9, yr2.GetMax())
|
testutil.AssertEqual(t, 19.9, yr2.GetMax())
|
||||||
|
|
||||||
assert.Equal(9.7, yra2.GetMin())
|
testutil.AssertEqual(t, 9.7, yra2.GetMin())
|
||||||
assert.Equal(19.7, yra2.GetMax())
|
testutil.AssertEqual(t, 19.7, yra2.GetMax())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetRangesUseTicks(t *testing.T) {
|
func TestChartGetRangesUseTicks(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
// this test asserts that ticks should supercede manual ranges when generating the overall ranges.
|
// this test asserts that ticks should supercede manual ranges when generating the overall ranges.
|
||||||
|
|
||||||
|
@ -156,15 +155,15 @@ func TestChartGetRangesUseTicks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xr, yr, yar := c.getRanges()
|
xr, yr, yar := c.getRanges()
|
||||||
assert.Equal(-2.0, xr.GetMin())
|
testutil.AssertEqual(t, -2.0, xr.GetMin())
|
||||||
assert.Equal(2.0, xr.GetMax())
|
testutil.AssertEqual(t, 2.0, xr.GetMax())
|
||||||
assert.Equal(0.0, yr.GetMin())
|
testutil.AssertEqual(t, 0.0, yr.GetMin())
|
||||||
assert.Equal(5.0, yr.GetMax())
|
testutil.AssertEqual(t, 5.0, yr.GetMax())
|
||||||
assert.True(yar.IsZero(), yar.String())
|
testutil.AssertTrue(t, yar.IsZero(), yar.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetRangesUseUserRanges(t *testing.T) {
|
func TestChartGetRangesUseUserRanges(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
YAxis: YAxis{
|
YAxis: YAxis{
|
||||||
|
@ -182,15 +181,15 @@ func TestChartGetRangesUseUserRanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xr, yr, yar := c.getRanges()
|
xr, yr, yar := c.getRanges()
|
||||||
assert.Equal(-2.0, xr.GetMin())
|
testutil.AssertEqual(t, -2.0, xr.GetMin())
|
||||||
assert.Equal(2.0, xr.GetMax())
|
testutil.AssertEqual(t, 2.0, xr.GetMax())
|
||||||
assert.Equal(-5.0, yr.GetMin())
|
testutil.AssertEqual(t, -5.0, yr.GetMin())
|
||||||
assert.Equal(5.0, yr.GetMax())
|
testutil.AssertEqual(t, 5.0, yr.GetMax())
|
||||||
assert.True(yar.IsZero(), yar.String())
|
testutil.AssertTrue(t, yar.IsZero(), yar.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetBackgroundStyle(t *testing.T) {
|
func TestChartGetBackgroundStyle(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Background: Style{
|
Background: Style{
|
||||||
|
@ -199,11 +198,11 @@ func TestChartGetBackgroundStyle(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := c.getBackgroundStyle()
|
bs := c.getBackgroundStyle()
|
||||||
assert.Equal(bs.FillColor.String(), drawing.ColorBlack.String())
|
testutil.AssertEqual(t, bs.FillColor.String(), drawing.ColorBlack.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetCanvasStyle(t *testing.T) {
|
func TestChartGetCanvasStyle(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Canvas: Style{
|
Canvas: Style{
|
||||||
|
@ -212,19 +211,19 @@ func TestChartGetCanvasStyle(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bs := c.getCanvasStyle()
|
bs := c.getCanvasStyle()
|
||||||
assert.Equal(bs.FillColor.String(), drawing.ColorBlack.String())
|
testutil.AssertEqual(t, bs.FillColor.String(), drawing.ColorBlack.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetDefaultCanvasBox(t *testing.T) {
|
func TestChartGetDefaultCanvasBox(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{}
|
c := Chart{}
|
||||||
canvasBoxDefault := c.getDefaultCanvasBox()
|
canvasBoxDefault := c.getDefaultCanvasBox()
|
||||||
assert.False(canvasBoxDefault.IsZero())
|
testutil.AssertFalse(t, canvasBoxDefault.IsZero())
|
||||||
assert.Equal(DefaultBackgroundPadding.Top, canvasBoxDefault.Top)
|
testutil.AssertEqual(t, DefaultBackgroundPadding.Top, canvasBoxDefault.Top)
|
||||||
assert.Equal(DefaultBackgroundPadding.Left, canvasBoxDefault.Left)
|
testutil.AssertEqual(t, DefaultBackgroundPadding.Left, canvasBoxDefault.Left)
|
||||||
assert.Equal(c.GetWidth()-DefaultBackgroundPadding.Right, canvasBoxDefault.Right)
|
testutil.AssertEqual(t, c.GetWidth()-DefaultBackgroundPadding.Right, canvasBoxDefault.Right)
|
||||||
assert.Equal(c.GetHeight()-DefaultBackgroundPadding.Bottom, canvasBoxDefault.Bottom)
|
testutil.AssertEqual(t, c.GetHeight()-DefaultBackgroundPadding.Bottom, canvasBoxDefault.Bottom)
|
||||||
|
|
||||||
custom := Chart{
|
custom := Chart{
|
||||||
Background: Style{
|
Background: Style{
|
||||||
|
@ -237,15 +236,15 @@ func TestChartGetDefaultCanvasBox(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
canvasBoxCustom := custom.getDefaultCanvasBox()
|
canvasBoxCustom := custom.getDefaultCanvasBox()
|
||||||
assert.False(canvasBoxCustom.IsZero())
|
testutil.AssertFalse(t, canvasBoxCustom.IsZero())
|
||||||
assert.Equal(DefaultBackgroundPadding.Top+1, canvasBoxCustom.Top)
|
testutil.AssertEqual(t, DefaultBackgroundPadding.Top+1, canvasBoxCustom.Top)
|
||||||
assert.Equal(DefaultBackgroundPadding.Left+1, canvasBoxCustom.Left)
|
testutil.AssertEqual(t, DefaultBackgroundPadding.Left+1, canvasBoxCustom.Left)
|
||||||
assert.Equal(c.GetWidth()-(DefaultBackgroundPadding.Right+1), canvasBoxCustom.Right)
|
testutil.AssertEqual(t, c.GetWidth()-(DefaultBackgroundPadding.Right+1), canvasBoxCustom.Right)
|
||||||
assert.Equal(c.GetHeight()-(DefaultBackgroundPadding.Bottom+1), canvasBoxCustom.Bottom)
|
testutil.AssertEqual(t, c.GetHeight()-(DefaultBackgroundPadding.Bottom+1), canvasBoxCustom.Bottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetValueFormatters(t *testing.T) {
|
func TestChartGetValueFormatters(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Series: []Series{
|
Series: []Series{
|
||||||
|
@ -266,16 +265,16 @@ func TestChartGetValueFormatters(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dxf, dyf, dyaf := c.getValueFormatters()
|
dxf, dyf, dyaf := c.getValueFormatters()
|
||||||
assert.NotNil(dxf)
|
testutil.AssertNotNil(t, dxf)
|
||||||
assert.NotNil(dyf)
|
testutil.AssertNotNil(t, dyf)
|
||||||
assert.NotNil(dyaf)
|
testutil.AssertNotNil(t, dyaf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartHasAxes(t *testing.T) {
|
func TestChartHasAxes(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
assert.True(Chart{}.hasAxes())
|
testutil.AssertTrue(t, Chart{}.hasAxes())
|
||||||
assert.False(Chart{XAxis: XAxis{Style: Hidden()}, YAxis: YAxis{Style: Hidden()}, YAxisSecondary: YAxis{Style: Hidden()}}.hasAxes())
|
testutil.AssertFalse(t, Chart{XAxis: XAxis{Style: Hidden()}, YAxis: YAxis{Style: Hidden()}, YAxisSecondary: YAxis{Style: Hidden()}}.hasAxes())
|
||||||
|
|
||||||
x := Chart{
|
x := Chart{
|
||||||
XAxis: XAxis{
|
XAxis: XAxis{
|
||||||
|
@ -288,7 +287,7 @@ func TestChartHasAxes(t *testing.T) {
|
||||||
Style: Hidden(),
|
Style: Hidden(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.True(x.hasAxes())
|
testutil.AssertTrue(t, x.hasAxes())
|
||||||
|
|
||||||
y := Chart{
|
y := Chart{
|
||||||
XAxis: XAxis{
|
XAxis: XAxis{
|
||||||
|
@ -301,7 +300,7 @@ func TestChartHasAxes(t *testing.T) {
|
||||||
Style: Hidden(),
|
Style: Hidden(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.True(y.hasAxes())
|
testutil.AssertTrue(t, y.hasAxes())
|
||||||
|
|
||||||
ya := Chart{
|
ya := Chart{
|
||||||
XAxis: XAxis{
|
XAxis: XAxis{
|
||||||
|
@ -314,14 +313,14 @@ func TestChartHasAxes(t *testing.T) {
|
||||||
Style: Shown(),
|
Style: Shown(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.True(ya.hasAxes())
|
testutil.AssertTrue(t, ya.hasAxes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartGetAxesTicks(t *testing.T) {
|
func TestChartGetAxesTicks(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
r, err := PNG(1024, 1024)
|
r, err := PNG(1024, 1024)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
XAxis: XAxis{
|
XAxis: XAxis{
|
||||||
|
@ -337,13 +336,13 @@ func TestChartGetAxesTicks(t *testing.T) {
|
||||||
xr, yr, yar := c.getRanges()
|
xr, yr, yar := c.getRanges()
|
||||||
|
|
||||||
xt, yt, yat := c.getAxesTicks(r, xr, yr, yar, FloatValueFormatter, FloatValueFormatter, FloatValueFormatter)
|
xt, yt, yat := c.getAxesTicks(r, xr, yr, yar, FloatValueFormatter, FloatValueFormatter, FloatValueFormatter)
|
||||||
assert.NotEmpty(xt)
|
testutil.AssertNotEmpty(t, xt)
|
||||||
assert.NotEmpty(yt)
|
testutil.AssertNotEmpty(t, yt)
|
||||||
assert.NotEmpty(yat)
|
testutil.AssertNotEmpty(t, yat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartSingleSeries(t *testing.T) {
|
func TestChartSingleSeries(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Title: "Hello!",
|
Title: "Hello!",
|
||||||
|
@ -366,11 +365,11 @@ func TestChartSingleSeries(t *testing.T) {
|
||||||
|
|
||||||
buffer := bytes.NewBuffer([]byte{})
|
buffer := bytes.NewBuffer([]byte{})
|
||||||
c.Render(PNG, buffer)
|
c.Render(PNG, buffer)
|
||||||
assert.NotEmpty(buffer.Bytes())
|
testutil.AssertNotEmpty(t, buffer.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartRegressionBadRanges(t *testing.T) {
|
func TestChartRegressionBadRanges(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Series: []Series{
|
Series: []Series{
|
||||||
|
@ -382,11 +381,11 @@ func TestChartRegressionBadRanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
buffer := bytes.NewBuffer([]byte{})
|
buffer := bytes.NewBuffer([]byte{})
|
||||||
c.Render(PNG, buffer)
|
c.Render(PNG, buffer)
|
||||||
assert.True(true, "Render needs to finish.")
|
testutil.AssertTrue(t, true, "Render needs to finish.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartRegressionBadRangesByUser(t *testing.T) {
|
func TestChartRegressionBadRangesByUser(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
YAxis: YAxis{
|
YAxis: YAxis{
|
||||||
|
@ -404,11 +403,11 @@ func TestChartRegressionBadRangesByUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
buffer := bytes.NewBuffer([]byte{})
|
buffer := bytes.NewBuffer([]byte{})
|
||||||
c.Render(PNG, buffer)
|
c.Render(PNG, buffer)
|
||||||
assert.True(true, "Render needs to finish.")
|
testutil.AssertTrue(t, true, "Render needs to finish.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartValidatesSeries(t *testing.T) {
|
func TestChartValidatesSeries(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Series: []Series{
|
Series: []Series{
|
||||||
|
@ -419,7 +418,7 @@ func TestChartValidatesSeries(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Nil(c.validateSeries())
|
testutil.AssertNil(t, c.validateSeries())
|
||||||
|
|
||||||
c = Chart{
|
c = Chart{
|
||||||
Series: []Series{
|
Series: []Series{
|
||||||
|
@ -429,11 +428,11 @@ func TestChartValidatesSeries(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NotNil(c.validateSeries())
|
testutil.AssertNotNil(t, c.validateSeries())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartCheckRanges(t *testing.T) {
|
func TestChartCheckRanges(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Series: []Series{
|
Series: []Series{
|
||||||
|
@ -445,11 +444,11 @@ func TestChartCheckRanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xr, yr, yra := c.getRanges()
|
xr, yr, yra := c.getRanges()
|
||||||
assert.Nil(c.checkRanges(xr, yr, yra))
|
testutil.AssertNil(t, c.checkRanges(xr, yr, yra))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartCheckRangesWithRanges(t *testing.T) {
|
func TestChartCheckRangesWithRanges(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
XAxis: XAxis{
|
XAxis: XAxis{
|
||||||
|
@ -473,7 +472,7 @@ func TestChartCheckRangesWithRanges(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xr, yr, yra := c.getRanges()
|
xr, yr, yra := c.getRanges()
|
||||||
assert.Nil(c.checkRanges(xr, yr, yra))
|
testutil.AssertNil(t, c.checkRanges(xr, yr, yra))
|
||||||
}
|
}
|
||||||
|
|
||||||
func at(i image.Image, x, y int) drawing.Color {
|
func at(i image.Image, x, y int) drawing.Color {
|
||||||
|
@ -481,7 +480,7 @@ func at(i image.Image, x, y int) drawing.Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartE2ELine(t *testing.T) {
|
func TestChartE2ELine(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
c := Chart{
|
c := Chart{
|
||||||
Height: 50,
|
Height: 50,
|
||||||
|
@ -506,26 +505,26 @@ func TestChartE2ELine(t *testing.T) {
|
||||||
|
|
||||||
var buffer = &bytes.Buffer{}
|
var buffer = &bytes.Buffer{}
|
||||||
err := c.Render(PNG, buffer)
|
err := c.Render(PNG, buffer)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
// do color tests ...
|
// do color tests ...
|
||||||
|
|
||||||
i, err := png.Decode(buffer)
|
i, err := png.Decode(buffer)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
// test the bottom and top of the line
|
// test the bottom and top of the line
|
||||||
assert.Equal(drawing.ColorWhite, at(i, 0, 0))
|
testutil.AssertEqual(t, drawing.ColorWhite, at(i, 0, 0))
|
||||||
assert.Equal(drawing.ColorWhite, at(i, 49, 49))
|
testutil.AssertEqual(t, drawing.ColorWhite, at(i, 49, 49))
|
||||||
|
|
||||||
// test a line mid point
|
// test a line mid point
|
||||||
defaultSeriesColor := GetDefaultColor(0)
|
defaultSeriesColor := GetDefaultColor(0)
|
||||||
assert.Equal(defaultSeriesColor, at(i, 0, 49))
|
testutil.AssertEqual(t, defaultSeriesColor, at(i, 0, 49))
|
||||||
assert.Equal(defaultSeriesColor, at(i, 49, 0))
|
testutil.AssertEqual(t, defaultSeriesColor, at(i, 49, 0))
|
||||||
assert.Equal(drawing.ColorFromHex("bddbf6"), at(i, 24, 24))
|
testutil.AssertEqual(t, drawing.ColorFromHex("bddbf6"), at(i, 24, 24))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestChartE2ELineWithFill(t *testing.T) {
|
func TestChartE2ELineWithFill(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
logBuffer := new(bytes.Buffer)
|
logBuffer := new(bytes.Buffer)
|
||||||
|
|
||||||
|
@ -555,22 +554,41 @@ func TestChartE2ELineWithFill(t *testing.T) {
|
||||||
Log: NewLogger(OptLoggerStdout(logBuffer), OptLoggerStderr(logBuffer)),
|
Log: NewLogger(OptLoggerStdout(logBuffer), OptLoggerStderr(logBuffer)),
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(5, len(c.Series[0].(ContinuousSeries).XValues))
|
testutil.AssertEqual(t, 5, len(c.Series[0].(ContinuousSeries).XValues))
|
||||||
assert.Equal(5, len(c.Series[0].(ContinuousSeries).YValues))
|
testutil.AssertEqual(t, 5, len(c.Series[0].(ContinuousSeries).YValues))
|
||||||
|
|
||||||
var buffer = &bytes.Buffer{}
|
var buffer = &bytes.Buffer{}
|
||||||
err := c.Render(PNG, buffer)
|
err := c.Render(PNG, buffer)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
i, err := png.Decode(buffer)
|
i, err := png.Decode(buffer)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
|
|
||||||
// test the bottom and top of the line
|
// test the bottom and top of the line
|
||||||
assert.Equal(drawing.ColorWhite, at(i, 0, 0))
|
testutil.AssertEqual(t, drawing.ColorWhite, at(i, 0, 0))
|
||||||
assert.Equal(drawing.ColorRed, at(i, 49, 49))
|
testutil.AssertEqual(t, drawing.ColorRed, at(i, 49, 49))
|
||||||
|
|
||||||
// test a line mid point
|
// test a line mid point
|
||||||
defaultSeriesColor := drawing.ColorBlue
|
defaultSeriesColor := drawing.ColorBlue
|
||||||
assert.Equal(defaultSeriesColor, at(i, 0, 49))
|
testutil.AssertEqual(t, defaultSeriesColor, at(i, 0, 49))
|
||||||
assert.Equal(defaultSeriesColor, at(i, 49, 0))
|
testutil.AssertEqual(t, defaultSeriesColor, at(i, 49, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_Chart_cve(t *testing.T) {
|
||||||
|
poc := StackedBarChart{
|
||||||
|
Title: "poc",
|
||||||
|
Bars: []StackedBar{
|
||||||
|
{
|
||||||
|
Name: "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||||
|
Values: []Value{
|
||||||
|
{Value: 1, Label: "infinite"},
|
||||||
|
{Value: 1, Label: "loop"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var imgContent bytes.Buffer
|
||||||
|
err := poc.Render(PNG, &imgContent)
|
||||||
|
testutil.AssertNotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package chart
|
package chart
|
||||||
|
|
||||||
import "github.com/wcharczuk/go-chart/drawing"
|
import "git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ColorWhite is white.
|
// ColorWhite is white.
|
||||||
|
|
|
@ -3,11 +3,11 @@ package chart
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
assert "github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConcatSeries(t *testing.T) {
|
func TestConcatSeries(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
s1 := ContinuousSeries{
|
s1 := ContinuousSeries{
|
||||||
XValues: LinearRange(1.0, 10.0),
|
XValues: LinearRange(1.0, 10.0),
|
||||||
|
@ -25,17 +25,17 @@ func TestConcatSeries(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := ConcatSeries([]Series{s1, s2, s3})
|
cs := ConcatSeries([]Series{s1, s2, s3})
|
||||||
assert.Equal(30, cs.Len())
|
testutil.AssertEqual(t, 30, cs.Len())
|
||||||
|
|
||||||
x0, y0 := cs.GetValue(0)
|
x0, y0 := cs.GetValue(0)
|
||||||
assert.Equal(1.0, x0)
|
testutil.AssertEqual(t, 1.0, x0)
|
||||||
assert.Equal(1.0, y0)
|
testutil.AssertEqual(t, 1.0, y0)
|
||||||
|
|
||||||
xm, ym := cs.GetValue(19)
|
xm, ym := cs.GetValue(19)
|
||||||
assert.Equal(20.0, xm)
|
testutil.AssertEqual(t, 20.0, xm)
|
||||||
assert.Equal(1.0, ym)
|
testutil.AssertEqual(t, 1.0, ym)
|
||||||
|
|
||||||
xn, yn := cs.GetValue(29)
|
xn, yn := cs.GetValue(29)
|
||||||
assert.Equal(30.0, xn)
|
testutil.AssertEqual(t, 30.0, xn)
|
||||||
assert.Equal(10.0, yn)
|
testutil.AssertEqual(t, 10.0, yn)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,11 @@ package chart
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRangeTranslate(t *testing.T) {
|
func TestRangeTranslate(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
values := []float64{1.0, 2.0, 2.5, 2.7, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}
|
values := []float64{1.0, 2.0, 2.5, 2.7, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}
|
||||||
r := ContinuousRange{Domain: 1000}
|
r := ContinuousRange{Domain: 1000}
|
||||||
r.Min, r.Max = MinMax(values...)
|
r.Min, r.Max = MinMax(values...)
|
||||||
|
@ -16,7 +16,7 @@ func TestRangeTranslate(t *testing.T) {
|
||||||
// value = ~5.0
|
// value = ~5.0
|
||||||
// domain = ~1000
|
// domain = ~1000
|
||||||
// 5/8 * 1000 ~=
|
// 5/8 * 1000 ~=
|
||||||
assert.Equal(0, r.Translate(1.0))
|
testutil.AssertEqual(t, 0, r.Translate(1.0))
|
||||||
assert.Equal(1000, r.Translate(8.0))
|
testutil.AssertEqual(t, 1000, r.Translate(8.0))
|
||||||
assert.Equal(572, r.Translate(5.0))
|
testutil.AssertEqual(t, 572, r.Translate(5.0))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
assert "github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContinuousSeries(t *testing.T) {
|
func TestContinuousSeries(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
cs := ContinuousSeries{
|
cs := ContinuousSeries{
|
||||||
Name: "Test Series",
|
Name: "Test Series",
|
||||||
|
@ -16,23 +16,23 @@ func TestContinuousSeries(t *testing.T) {
|
||||||
YValues: LinearRange(1.0, 10.0),
|
YValues: LinearRange(1.0, 10.0),
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal("Test Series", cs.GetName())
|
testutil.AssertEqual(t, "Test Series", cs.GetName())
|
||||||
assert.Equal(10, cs.Len())
|
testutil.AssertEqual(t, 10, cs.Len())
|
||||||
x0, y0 := cs.GetValues(0)
|
x0, y0 := cs.GetValues(0)
|
||||||
assert.Equal(1.0, x0)
|
testutil.AssertEqual(t, 1.0, x0)
|
||||||
assert.Equal(1.0, y0)
|
testutil.AssertEqual(t, 1.0, y0)
|
||||||
|
|
||||||
xn, yn := cs.GetValues(9)
|
xn, yn := cs.GetValues(9)
|
||||||
assert.Equal(10.0, xn)
|
testutil.AssertEqual(t, 10.0, xn)
|
||||||
assert.Equal(10.0, yn)
|
testutil.AssertEqual(t, 10.0, yn)
|
||||||
|
|
||||||
xn, yn = cs.GetLastValues()
|
xn, yn = cs.GetLastValues()
|
||||||
assert.Equal(10.0, xn)
|
testutil.AssertEqual(t, 10.0, xn)
|
||||||
assert.Equal(10.0, yn)
|
testutil.AssertEqual(t, 10.0, yn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContinuousSeriesValueFormatter(t *testing.T) {
|
func TestContinuousSeriesValueFormatter(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
cs := ContinuousSeries{
|
cs := ContinuousSeries{
|
||||||
XValueFormatter: func(v interface{}) string {
|
XValueFormatter: func(v interface{}) string {
|
||||||
|
@ -44,29 +44,29 @@ func TestContinuousSeriesValueFormatter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xf, yf := cs.GetValueFormatters()
|
xf, yf := cs.GetValueFormatters()
|
||||||
assert.Equal("0.100000 foo", xf(0.1))
|
testutil.AssertEqual(t, "0.100000 foo", xf(0.1))
|
||||||
assert.Equal("0.100000 bar", yf(0.1))
|
testutil.AssertEqual(t, "0.100000 bar", yf(0.1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContinuousSeriesValidate(t *testing.T) {
|
func TestContinuousSeriesValidate(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
cs := ContinuousSeries{
|
cs := ContinuousSeries{
|
||||||
Name: "Test Series",
|
Name: "Test Series",
|
||||||
XValues: LinearRange(1.0, 10.0),
|
XValues: LinearRange(1.0, 10.0),
|
||||||
YValues: LinearRange(1.0, 10.0),
|
YValues: LinearRange(1.0, 10.0),
|
||||||
}
|
}
|
||||||
assert.Nil(cs.Validate())
|
testutil.AssertNil(t, cs.Validate())
|
||||||
|
|
||||||
cs = ContinuousSeries{
|
cs = ContinuousSeries{
|
||||||
Name: "Test Series",
|
Name: "Test Series",
|
||||||
XValues: LinearRange(1.0, 10.0),
|
XValues: LinearRange(1.0, 10.0),
|
||||||
}
|
}
|
||||||
assert.NotNil(cs.Validate())
|
testutil.AssertNotNil(t, cs.Validate())
|
||||||
|
|
||||||
cs = ContinuousSeries{
|
cs = ContinuousSeries{
|
||||||
Name: "Test Series",
|
Name: "Test Series",
|
||||||
YValues: LinearRange(1.0, 10.0),
|
YValues: LinearRange(1.0, 10.0),
|
||||||
}
|
}
|
||||||
assert.NotNil(cs.Validate())
|
testutil.AssertNotNil(t, cs.Validate())
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDonutChart(t *testing.T) {
|
func TestDonutChart(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
pie := DonutChart{
|
pie := DonutChart{
|
||||||
Canvas: Style{
|
Canvas: Style{
|
||||||
|
@ -27,11 +27,11 @@ func TestDonutChart(t *testing.T) {
|
||||||
|
|
||||||
b := bytes.NewBuffer([]byte{})
|
b := bytes.NewBuffer([]byte{})
|
||||||
pie.Render(PNG, b)
|
pie.Render(PNG, b)
|
||||||
assert.NotZero(b.Len())
|
testutil.AssertNotZero(t, b.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDonutChartDropsZeroValues(t *testing.T) {
|
func TestDonutChartDropsZeroValues(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
pie := DonutChart{
|
pie := DonutChart{
|
||||||
Canvas: Style{
|
Canvas: Style{
|
||||||
|
@ -46,11 +46,11 @@ func TestDonutChartDropsZeroValues(t *testing.T) {
|
||||||
|
|
||||||
b := bytes.NewBuffer([]byte{})
|
b := bytes.NewBuffer([]byte{})
|
||||||
err := pie.Render(PNG, b)
|
err := pie.Render(PNG, b)
|
||||||
assert.Nil(err)
|
testutil.AssertNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDonutChartAllZeroValues(t *testing.T) {
|
func TestDonutChartAllZeroValues(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
pie := DonutChart{
|
pie := DonutChart{
|
||||||
Canvas: Style{
|
Canvas: Style{
|
||||||
|
@ -65,5 +65,5 @@ func TestDonutChartAllZeroValues(t *testing.T) {
|
||||||
|
|
||||||
b := bytes.NewBuffer([]byte{})
|
b := bytes.NewBuffer([]byte{})
|
||||||
err := pie.Render(PNG, b)
|
err := pie.Render(PNG, b)
|
||||||
assert.NotNil(err)
|
testutil.AssertNotNil(t, err)
|
||||||
}
|
}
|
||||||
|
|
6
draw.go
|
@ -296,8 +296,10 @@ func (d draw) TextWithin(r Renderer, text string, box Box, style Style) {
|
||||||
switch style.GetTextVerticalAlign() {
|
switch style.GetTextVerticalAlign() {
|
||||||
case TextVerticalAlignBottom, TextVerticalAlignBaseline: // i have to build better baseline handling into measure text
|
case TextVerticalAlignBottom, TextVerticalAlignBaseline: // i have to build better baseline handling into measure text
|
||||||
y = y - linesBox.Height()
|
y = y - linesBox.Height()
|
||||||
case TextVerticalAlignMiddle, TextVerticalAlignMiddleBaseline:
|
case TextVerticalAlignMiddle:
|
||||||
y = (y - linesBox.Height()) >> 1
|
y = y + (box.Height() >> 1) - (linesBox.Height() >> 1)
|
||||||
|
case TextVerticalAlignMiddleBaseline:
|
||||||
|
y = y + (box.Height() >> 1) - linesBox.Height()
|
||||||
}
|
}
|
||||||
|
|
||||||
var tx, ty int
|
var tx, ty int
|
||||||
|
|
162
drawing/color.go
|
@ -2,27 +2,46 @@ package drawing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Basic Colors from:
|
||||||
|
// https://www.w3.org/wiki/CSS/Properties/color/keywords
|
||||||
var (
|
var (
|
||||||
// ColorTransparent is a fully transparent color.
|
// ColorTransparent is a fully transparent color.
|
||||||
ColorTransparent = Color{}
|
ColorTransparent = Color{R: 255, G: 255, B: 255, A: 0}
|
||||||
|
|
||||||
// ColorWhite is white.
|
// ColorWhite is white.
|
||||||
ColorWhite = Color{R: 255, G: 255, B: 255, A: 255}
|
ColorWhite = Color{R: 255, G: 255, B: 255, A: 255}
|
||||||
|
|
||||||
// ColorBlack is black.
|
// ColorBlack is black.
|
||||||
ColorBlack = Color{R: 0, G: 0, B: 0, A: 255}
|
ColorBlack = Color{R: 0, G: 0, B: 0, A: 255}
|
||||||
|
|
||||||
// ColorRed is red.
|
// ColorRed is red.
|
||||||
ColorRed = Color{R: 255, G: 0, B: 0, A: 255}
|
ColorRed = Color{R: 255, G: 0, B: 0, A: 255}
|
||||||
|
|
||||||
// ColorGreen is green.
|
// ColorGreen is green.
|
||||||
ColorGreen = Color{R: 0, G: 255, B: 0, A: 255}
|
ColorGreen = Color{R: 0, G: 128, B: 0, A: 255}
|
||||||
|
|
||||||
// ColorBlue is blue.
|
// ColorBlue is blue.
|
||||||
ColorBlue = Color{R: 0, G: 0, B: 255, A: 255}
|
ColorBlue = Color{R: 0, G: 0, B: 255, A: 255}
|
||||||
|
// ColorSilver is a known color.
|
||||||
|
ColorSilver = Color{R: 192, G: 192, B: 192, A: 255}
|
||||||
|
// ColorMaroon is a known color.
|
||||||
|
ColorMaroon = Color{R: 128, G: 0, B: 0, A: 255}
|
||||||
|
// ColorPurple is a known color.
|
||||||
|
ColorPurple = Color{R: 128, G: 0, B: 128, A: 255}
|
||||||
|
// ColorFuchsia is a known color.
|
||||||
|
ColorFuchsia = Color{R: 255, G: 0, B: 255, A: 255}
|
||||||
|
// ColorLime is a known color.
|
||||||
|
ColorLime = Color{R: 0, G: 255, B: 0, A: 255}
|
||||||
|
// ColorOlive is a known color.
|
||||||
|
ColorOlive = Color{R: 128, G: 128, B: 0, A: 255}
|
||||||
|
// ColorYellow is a known color.
|
||||||
|
ColorYellow = Color{R: 255, G: 255, B: 0, A: 255}
|
||||||
|
// ColorNavy is a known color.
|
||||||
|
ColorNavy = Color{R: 0, G: 0, B: 128, A: 255}
|
||||||
|
// ColorTeal is a known color.
|
||||||
|
ColorTeal = Color{R: 0, G: 128, B: 128, A: 255}
|
||||||
|
// ColorAqua is a known color.
|
||||||
|
ColorAqua = Color{R: 0, G: 255, B: 255, A: 255}
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseHex(hex string) uint8 {
|
func parseHex(hex string) uint8 {
|
||||||
|
@ -30,8 +49,97 @@ func parseHex(hex string) uint8 {
|
||||||
return uint8(v)
|
return uint8(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ParseColor parses a color from a string.
|
||||||
|
func ParseColor(rawColor string) Color {
|
||||||
|
if strings.HasPrefix(rawColor, "rgba") {
|
||||||
|
return ColorFromRGBA(rawColor)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(rawColor, "rgb") {
|
||||||
|
return ColorFromRGB(rawColor)
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(rawColor, "#") {
|
||||||
|
return ColorFromHex(rawColor)
|
||||||
|
}
|
||||||
|
return ColorFromKnown(rawColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
var rgbaexpr = regexp.MustCompile(`rgba\((?P<R>.+),(?P<G>.+),(?P<B>.+),(?P<A>.+)\)`)
|
||||||
|
|
||||||
|
// ColorFromRGBA returns a color from an `rgba()` css function.
|
||||||
|
func ColorFromRGBA(rgba string) (output Color) {
|
||||||
|
values := rgbaexpr.FindStringSubmatch(rgba)
|
||||||
|
for i, name := range rgbaexpr.SubexpNames() {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i >= len(values) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch name {
|
||||||
|
case "R":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseInt(value, 10, 16)
|
||||||
|
output.R = uint8(parsed)
|
||||||
|
case "G":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseInt(value, 10, 16)
|
||||||
|
output.G = uint8(parsed)
|
||||||
|
case "B":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseInt(value, 10, 16)
|
||||||
|
output.B = uint8(parsed)
|
||||||
|
case "A":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseFloat(value, 32)
|
||||||
|
if parsed > 1 {
|
||||||
|
parsed = 1
|
||||||
|
} else if parsed < 0 {
|
||||||
|
parsed = 0
|
||||||
|
}
|
||||||
|
output.A = uint8(parsed * 255)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var rgbexpr = regexp.MustCompile(`rgb\((?P<R>.+),(?P<G>.+),(?P<B>.+)\)`)
|
||||||
|
|
||||||
|
// ColorFromRGB returns a color from an `rgb()` css function.
|
||||||
|
func ColorFromRGB(rgb string) (output Color) {
|
||||||
|
output.A = 255
|
||||||
|
values := rgbexpr.FindStringSubmatch(rgb)
|
||||||
|
for i, name := range rgbaexpr.SubexpNames() {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i >= len(values) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch name {
|
||||||
|
case "R":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseInt(value, 10, 16)
|
||||||
|
output.R = uint8(parsed)
|
||||||
|
case "G":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseInt(value, 10, 16)
|
||||||
|
output.G = uint8(parsed)
|
||||||
|
case "B":
|
||||||
|
value := strings.TrimSpace(values[i])
|
||||||
|
parsed, _ := strconv.ParseInt(value, 10, 16)
|
||||||
|
output.B = uint8(parsed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// ColorFromHex returns a color from a css hex code.
|
// ColorFromHex returns a color from a css hex code.
|
||||||
|
//
|
||||||
|
// NOTE: it will trim a leading '#' character if present.
|
||||||
func ColorFromHex(hex string) Color {
|
func ColorFromHex(hex string) Color {
|
||||||
|
if strings.HasPrefix(hex, "#") {
|
||||||
|
hex = strings.TrimPrefix(hex, "#")
|
||||||
|
}
|
||||||
var c Color
|
var c Color
|
||||||
if len(hex) == 3 {
|
if len(hex) == 3 {
|
||||||
c.R = parseHex(string(hex[0])) * 0x11
|
c.R = parseHex(string(hex[0])) * 0x11
|
||||||
|
@ -46,6 +154,46 @@ func ColorFromHex(hex string) Color {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ColorFromKnown returns an internal color from a known (basic) color name.
|
||||||
|
func ColorFromKnown(known string) Color {
|
||||||
|
switch strings.ToLower(known) {
|
||||||
|
case "transparent":
|
||||||
|
return ColorTransparent
|
||||||
|
case "white":
|
||||||
|
return ColorWhite
|
||||||
|
case "black":
|
||||||
|
return ColorBlack
|
||||||
|
case "red":
|
||||||
|
return ColorRed
|
||||||
|
case "blue":
|
||||||
|
return ColorBlue
|
||||||
|
case "green":
|
||||||
|
return ColorGreen
|
||||||
|
case "silver":
|
||||||
|
return ColorSilver
|
||||||
|
case "maroon":
|
||||||
|
return ColorMaroon
|
||||||
|
case "purple":
|
||||||
|
return ColorPurple
|
||||||
|
case "fuchsia":
|
||||||
|
return ColorFuchsia
|
||||||
|
case "lime":
|
||||||
|
return ColorLime
|
||||||
|
case "olive":
|
||||||
|
return ColorOlive
|
||||||
|
case "yellow":
|
||||||
|
return ColorYellow
|
||||||
|
case "navy":
|
||||||
|
return ColorNavy
|
||||||
|
case "teal":
|
||||||
|
return ColorTeal
|
||||||
|
case "aqua":
|
||||||
|
return ColorAqua
|
||||||
|
default:
|
||||||
|
return Color{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ColorFromAlphaMixedRGBA returns the system alpha mixed rgba values.
|
// ColorFromAlphaMixedRGBA returns the system alpha mixed rgba values.
|
||||||
func ColorFromAlphaMixedRGBA(r, g, b, a uint32) Color {
|
func ColorFromAlphaMixedRGBA(r, g, b, a uint32) Color {
|
||||||
fa := float64(a) / 255.0
|
fa := float64(a) / 255.0
|
||||||
|
|
|
@ -1,53 +1,114 @@
|
||||||
package drawing
|
package drawing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestColorFromHex(t *testing.T) {
|
func TestColorFromHex(t *testing.T) {
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
white := ColorFromHex("FFFFFF")
|
white := ColorFromHex("FFFFFF")
|
||||||
assert.Equal(ColorWhite, white)
|
testutil.AssertEqual(t, ColorWhite, white)
|
||||||
|
|
||||||
shortWhite := ColorFromHex("FFF")
|
shortWhite := ColorFromHex("FFF")
|
||||||
assert.Equal(ColorWhite, shortWhite)
|
testutil.AssertEqual(t, ColorWhite, shortWhite)
|
||||||
|
|
||||||
black := ColorFromHex("000000")
|
black := ColorFromHex("000000")
|
||||||
assert.Equal(ColorBlack, black)
|
testutil.AssertEqual(t, ColorBlack, black)
|
||||||
|
|
||||||
shortBlack := ColorFromHex("000")
|
shortBlack := ColorFromHex("000")
|
||||||
assert.Equal(ColorBlack, shortBlack)
|
testutil.AssertEqual(t, ColorBlack, shortBlack)
|
||||||
|
|
||||||
red := ColorFromHex("FF0000")
|
red := ColorFromHex("FF0000")
|
||||||
assert.Equal(ColorRed, red)
|
testutil.AssertEqual(t, ColorRed, red)
|
||||||
|
|
||||||
shortRed := ColorFromHex("F00")
|
shortRed := ColorFromHex("F00")
|
||||||
assert.Equal(ColorRed, shortRed)
|
testutil.AssertEqual(t, ColorRed, shortRed)
|
||||||
|
|
||||||
green := ColorFromHex("00FF00")
|
green := ColorFromHex("008000")
|
||||||
assert.Equal(ColorGreen, green)
|
testutil.AssertEqual(t, ColorGreen, green)
|
||||||
|
|
||||||
shortGreen := ColorFromHex("0F0")
|
// shortGreen := ColorFromHex("0F0")
|
||||||
assert.Equal(ColorGreen, shortGreen)
|
// testutil.AssertEqual(t, ColorGreen, shortGreen)
|
||||||
|
|
||||||
blue := ColorFromHex("0000FF")
|
blue := ColorFromHex("0000FF")
|
||||||
assert.Equal(ColorBlue, blue)
|
testutil.AssertEqual(t, ColorBlue, blue)
|
||||||
|
|
||||||
shortBlue := ColorFromHex("00F")
|
shortBlue := ColorFromHex("00F")
|
||||||
assert.Equal(ColorBlue, shortBlue)
|
testutil.AssertEqual(t, ColorBlue, shortBlue)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestColorFromHex_handlesHash(t *testing.T) {
|
||||||
|
withHash := ColorFromHex("#FF0000")
|
||||||
|
testutil.AssertEqual(t, ColorRed, withHash)
|
||||||
|
|
||||||
|
withoutHash := ColorFromHex("#FF0000")
|
||||||
|
testutil.AssertEqual(t, ColorRed, withoutHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestColorFromAlphaMixedRGBA(t *testing.T) {
|
func TestColorFromAlphaMixedRGBA(t *testing.T) {
|
||||||
assert := assert.New(t)
|
|
||||||
|
|
||||||
black := ColorFromAlphaMixedRGBA(color.Black.RGBA())
|
black := ColorFromAlphaMixedRGBA(color.Black.RGBA())
|
||||||
assert.True(black.Equals(ColorBlack), black.String())
|
testutil.AssertTrue(t, black.Equals(ColorBlack), black.String())
|
||||||
|
|
||||||
white := ColorFromAlphaMixedRGBA(color.White.RGBA())
|
white := ColorFromAlphaMixedRGBA(color.White.RGBA())
|
||||||
assert.True(white.Equals(ColorWhite), white.String())
|
testutil.AssertTrue(t, white.Equals(ColorWhite), white.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_ColorFromRGBA(t *testing.T) {
|
||||||
|
value := "rgba(192, 192, 192, 1.0)"
|
||||||
|
parsed := ColorFromRGBA(value)
|
||||||
|
testutil.AssertEqual(t, ColorSilver, parsed)
|
||||||
|
|
||||||
|
value = "rgba(192,192,192,1.0)"
|
||||||
|
parsed = ColorFromRGBA(value)
|
||||||
|
testutil.AssertEqual(t, ColorSilver, parsed)
|
||||||
|
|
||||||
|
value = "rgba(192,192,192,1.5)"
|
||||||
|
parsed = ColorFromRGBA(value)
|
||||||
|
testutil.AssertEqual(t, ColorSilver, parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseColor(t *testing.T) {
|
||||||
|
testCases := [...]struct {
|
||||||
|
Input string
|
||||||
|
Expected Color
|
||||||
|
}{
|
||||||
|
{"", Color{}},
|
||||||
|
{"white", ColorWhite},
|
||||||
|
{"WHITE", ColorWhite}, // caps!
|
||||||
|
{"black", ColorBlack},
|
||||||
|
{"red", ColorRed},
|
||||||
|
{"green", ColorGreen},
|
||||||
|
{"blue", ColorBlue},
|
||||||
|
{"silver", ColorSilver},
|
||||||
|
{"maroon", ColorMaroon},
|
||||||
|
{"purple", ColorPurple},
|
||||||
|
{"fuchsia", ColorFuchsia},
|
||||||
|
{"lime", ColorLime},
|
||||||
|
{"olive", ColorOlive},
|
||||||
|
{"yellow", ColorYellow},
|
||||||
|
{"navy", ColorNavy},
|
||||||
|
{"teal", ColorTeal},
|
||||||
|
{"aqua", ColorAqua},
|
||||||
|
|
||||||
|
{"rgba(192, 192, 192, 1.0)", ColorSilver},
|
||||||
|
{"rgba(192,192,192,1.0)", ColorSilver},
|
||||||
|
{"rgb(192, 192, 192)", ColorSilver},
|
||||||
|
{"rgb(192,192,192)", ColorSilver},
|
||||||
|
|
||||||
|
{"#FF0000", ColorRed},
|
||||||
|
{"#008000", ColorGreen},
|
||||||
|
{"#0000FF", ColorBlue},
|
||||||
|
{"#F00", ColorRed},
|
||||||
|
{"#080", Color{0, 136, 0, 255}},
|
||||||
|
{"#00F", ColorBlue},
|
||||||
|
}
|
||||||
|
|
||||||
|
for index, tc := range testCases {
|
||||||
|
actual := ParseColor(tc.Input)
|
||||||
|
testutil.AssertEqual(t, tc.Expected, actual, fmt.Sprintf("test case: %d -> %s", index, tc.Input))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package drawing
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
assert "github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type point struct {
|
type point struct {
|
||||||
|
@ -23,7 +23,7 @@ func (ml mockLine) Len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTraceQuad(t *testing.T) {
|
func TestTraceQuad(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
// Quad
|
// Quad
|
||||||
// x1, y1, cpx1, cpy2, x2, y2 float64
|
// x1, y1, cpx1, cpy2, x2, y2 float64
|
||||||
|
@ -31,5 +31,5 @@ func TestTraceQuad(t *testing.T) {
|
||||||
quad := []float64{10, 20, 20, 20, 20, 10}
|
quad := []float64{10, 20, 20, 20, 20, 10}
|
||||||
liner := &mockLine{}
|
liner := &mockLine{}
|
||||||
TraceQuad(liner, quad, 0.5)
|
TraceQuad(liner, quad, 0.5)
|
||||||
assert.NotZero(liner.Len())
|
testutil.AssertNotZero(t, liner.Len())
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package chart
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/blend/go-sdk/assert"
|
"git.smarteching.com/zeni/go-chart/v2/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -73,13 +73,13 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEMASeries(t *testing.T) {
|
func TestEMASeries(t *testing.T) {
|
||||||
assert := assert.New(t)
|
// replaced new assertions helper
|
||||||
|
|
||||||
mockSeries := mockValuesProvider{
|
mockSeries := mockValuesProvider{
|
||||||
emaXValues,
|
emaXValues,
|
||||||
emaYValues,
|
emaYValues,
|
||||||
}
|
}
|
||||||
assert.Equal(50, mockSeries.Len())
|
testutil.AssertEqual(t, 50, mockSeries.Len())
|
||||||
|
|
||||||
ema := &EMASeries{
|
ema := &EMASeries{
|
||||||
InnerSeries: mockSeries,
|
InnerSeries: mockSeries,
|
||||||
|
@ -87,7 +87,7 @@ func TestEMASeries(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sig := ema.GetSigma()
|
sig := ema.GetSigma()
|
||||||
assert.Equal(2.0/(26.0+1), sig)
|
testutil.AssertEqual(t, 2.0/(26.0+1), sig)
|
||||||
|
|
||||||
var yvalues []float64
|
var yvalues []float64
|
||||||
for x := 0; x < ema.Len(); x++ {
|
for x := 0; x < ema.Len(); x++ {
|
||||||
|
@ -96,10 +96,10 @@ func TestEMASeries(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for index, yv := range yvalues {
|
for index, yv := range yvalues {
|
||||||
assert.InDelta(yv, emaExpected[index], emaDelta)
|
testutil.AssertInDelta(t, yv, emaExpected[index], emaDelta)
|
||||||
}
|
}
|
||||||
|
|
||||||
lvx, lvy := ema.GetLastValues()
|
lvx, lvy := ema.GetLastValues()
|
||||||
assert.Equal(50.0, lvx)
|
testutil.AssertEqual(t, 50.0, lvx)
|
||||||
assert.InDelta(lvy, emaExpected[49], emaDelta)
|
testutil.AssertInDelta(t, lvy, emaExpected[49], emaDelta)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In this example we add an `Annotation` series, which is a special type of series that
|
In this example we add an `Annotation` series, which is a special type of series that
|
||||||
draws annotation labels at given X and Y values (as translated by their respective ranges).
|
draws annotation labels at given X and Y values (as translated by their respective ranges).
|
||||||
|
@ -37,11 +38,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/annotations/output.png
Normal file
After Width: | Height: | Size: 26 KiB |
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
chart "git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The below will draw the same chart as the `basic` example, except with both the x and y axes turned on.
|
The below will draw the same chart as the `basic` example, except with both the x and y axes turned on.
|
||||||
|
@ -14,20 +16,9 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
XAxis: chart.XAxis{
|
|
||||||
Name: "The XAxis",
|
|
||||||
NameStyle: chart.StyleShow(),
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Name: "The YAxis",
|
|
||||||
NameStyle: chart.StyleShow(),
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Series: []chart.Series{
|
Series: []chart.Series{
|
||||||
chart.ContinuousSeries{
|
chart.ContinuousSeries{
|
||||||
Style: chart.Style{
|
Style: chart.Style{
|
||||||
Show: true,
|
|
||||||
StrokeColor: chart.GetDefaultColor(0).WithAlpha(64),
|
StrokeColor: chart.GetDefaultColor(0).WithAlpha(64),
|
||||||
FillColor: chart.GetDefaultColor(0).WithAlpha(64),
|
FillColor: chart.GetDefaultColor(0).WithAlpha(64),
|
||||||
},
|
},
|
||||||
|
@ -37,11 +28,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/axes/output.png
Normal file
After Width: | Height: | Size: 22 KiB |
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
chart "git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The below will draw the same chart as the `basic` example, except with both the x and y axes turned on.
|
The below will draw the same chart as the `basic` example, except with both the x and y axes turned on.
|
||||||
|
@ -15,15 +17,14 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
XAxis: chart.XAxis{
|
XAxis: chart.XAxis{
|
||||||
Style: chart.StyleShow(), //enables / displays the x-axis
|
Name: "The XAxis",
|
||||||
},
|
},
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Style: chart.StyleShow(), //enables / displays the y-axis
|
Name: "The YAxis",
|
||||||
},
|
},
|
||||||
Series: []chart.Series{
|
Series: []chart.Series{
|
||||||
chart.ContinuousSeries{
|
chart.ContinuousSeries{
|
||||||
Style: chart.Style{
|
Style: chart.Style{
|
||||||
Show: true,
|
|
||||||
StrokeColor: chart.GetDefaultColor(0).WithAlpha(64),
|
StrokeColor: chart.GetDefaultColor(0).WithAlpha(64),
|
||||||
FillColor: chart.GetDefaultColor(0).WithAlpha(64),
|
FillColor: chart.GetDefaultColor(0).WithAlpha(64),
|
||||||
},
|
},
|
||||||
|
@ -33,11 +34,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/axes_labels/output.png
Normal file
After Width: | Height: | Size: 24 KiB |
35
examples/bar_chart/main.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
graph := chart.BarChart{
|
||||||
|
Title: "Test Bar Chart",
|
||||||
|
Background: chart.Style{
|
||||||
|
Padding: chart.Box{
|
||||||
|
Top: 40,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Height: 512,
|
||||||
|
BarWidth: 60,
|
||||||
|
Bars: []chart.Value{
|
||||||
|
{Value: 5.25, Label: "Blue"},
|
||||||
|
{Value: 4.88, Label: "Green"},
|
||||||
|
{Value: 4.74, Label: "Gray"},
|
||||||
|
{Value: 3.22, Label: "Orange"},
|
||||||
|
{Value: 3, Label: "Test"},
|
||||||
|
{Value: 2.27, Label: "??"},
|
||||||
|
{Value: 1, Label: "!!"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
graph.Render(chart.PNG, f)
|
||||||
|
}
|
BIN
examples/bar_chart/output.png
Normal file
After Width: | Height: | Size: 19 KiB |
|
@ -1,33 +1,29 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
"github.com/wcharczuk/go-chart/drawing"
|
"git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
profitStyle := chart.Style{
|
profitStyle := chart.Style{
|
||||||
Show: true,
|
|
||||||
FillColor: drawing.ColorFromHex("13c158"),
|
FillColor: drawing.ColorFromHex("13c158"),
|
||||||
StrokeColor: drawing.ColorFromHex("13c158"),
|
StrokeColor: drawing.ColorFromHex("13c158"),
|
||||||
StrokeWidth: 0,
|
StrokeWidth: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
lossStyle := chart.Style{
|
lossStyle := chart.Style{
|
||||||
Show: true,
|
|
||||||
FillColor: drawing.ColorFromHex("c11313"),
|
FillColor: drawing.ColorFromHex("c11313"),
|
||||||
StrokeColor: drawing.ColorFromHex("c11313"),
|
StrokeColor: drawing.ColorFromHex("c11313"),
|
||||||
StrokeWidth: 0,
|
StrokeWidth: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
sbc := chart.BarChart{
|
sbc := chart.BarChart{
|
||||||
Title: "Bar Chart Using BaseValue",
|
Title: "Bar Chart Using BaseValue",
|
||||||
TitleStyle: chart.StyleShow(),
|
|
||||||
Background: chart.Style{
|
Background: chart.Style{
|
||||||
Padding: chart.Box{
|
Padding: chart.Box{
|
||||||
Top: 40,
|
Top: 40,
|
||||||
|
@ -35,13 +31,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
Height: 512,
|
Height: 512,
|
||||||
BarWidth: 60,
|
BarWidth: 60,
|
||||||
XAxis: chart.Style{
|
|
||||||
Show: true,
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Style: chart.Style{
|
|
||||||
Show: true,
|
|
||||||
},
|
|
||||||
Ticks: []chart.Tick{
|
Ticks: []chart.Tick{
|
||||||
{Value: -4.0, Label: "-4"},
|
{Value: -4.0, Label: "-4"},
|
||||||
{Value: -2.0, Label: "-2"},
|
{Value: -2.0, Label: "-2"},
|
||||||
|
@ -66,23 +56,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
err := sbc.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
if err != nil {
|
sbc.Render(chart.PNG, f)
|
||||||
fmt.Printf("Error rendering chart: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func port() string {
|
|
||||||
if len(os.Getenv("PORT")) > 0 {
|
|
||||||
return os.Getenv("PORT")
|
|
||||||
}
|
|
||||||
return "8080"
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
listenPort := fmt.Sprintf(":%s", port())
|
|
||||||
fmt.Printf("Listening on %s\n", listenPort)
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
log.Fatal(http.ListenAndServe(listenPort, nil))
|
|
||||||
}
|
}
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
@ -1,18 +1,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
sbc := chart.BarChart{
|
graph := chart.BarChart{
|
||||||
Title: "Test Bar Chart",
|
Title: "Test Bar Chart",
|
||||||
TitleStyle: chart.StyleShow(),
|
|
||||||
Background: chart.Style{
|
Background: chart.Style{
|
||||||
Padding: chart.Box{
|
Padding: chart.Box{
|
||||||
Top: 40,
|
Top: 40,
|
||||||
|
@ -20,10 +21,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
Height: 512,
|
Height: 512,
|
||||||
BarWidth: 60,
|
BarWidth: 60,
|
||||||
XAxis: chart.StyleShow(),
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Bars: []chart.Value{
|
Bars: []chart.Value{
|
||||||
{Value: 5.25, Label: "Blue"},
|
{Value: 5.25, Label: "Blue"},
|
||||||
{Value: 4.88, Label: "Green"},
|
{Value: 4.88, Label: "Green"},
|
||||||
|
@ -36,10 +33,11 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
res.Header().Set("Content-Type", "image/png")
|
||||||
err := sbc.Render(chart.PNG, res)
|
err := graph.Render(chart.PNG, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error rendering chart: %v\n", err)
|
fmt.Printf("Error rendering chart: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func port() string {
|
func port() string {
|
23
examples/basic/main.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
graph := chart.Chart{
|
||||||
|
Series: []chart.Series{
|
||||||
|
chart.ContinuousSeries{
|
||||||
|
XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0},
|
||||||
|
YValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
graph.Render(chart.PNG, f)
|
||||||
|
}
|
BIN
examples/basic/output.png
Normal file
After Width: | Height: | Size: 24 KiB |
52
examples/benchmark_line_charts/main.go
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func random(min, max float64) float64 {
|
||||||
|
return rand.Float64()*(max-min) + min
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
numValues := 1024
|
||||||
|
numSeries := 100
|
||||||
|
series := make([]chart.Series, numSeries)
|
||||||
|
|
||||||
|
for i := 0; i < numSeries; i++ {
|
||||||
|
xValues := make([]time.Time, numValues)
|
||||||
|
yValues := make([]float64, numValues)
|
||||||
|
|
||||||
|
for j := 0; j < numValues; j++ {
|
||||||
|
xValues[j] = time.Now().AddDate(0, 0, (numValues-j)*-1)
|
||||||
|
yValues[j] = random(float64(-500), float64(500))
|
||||||
|
}
|
||||||
|
|
||||||
|
series[i] = chart.TimeSeries{
|
||||||
|
Name: fmt.Sprintf("aaa.bbb.hostname-%v.ccc.ddd.eee.fff.ggg.hhh.iii.jjj.kkk.lll.mmm.nnn.value", i),
|
||||||
|
XValues: xValues,
|
||||||
|
YValues: yValues,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graph := chart.Chart{
|
||||||
|
XAxis: chart.XAxis{
|
||||||
|
Name: "Time",
|
||||||
|
},
|
||||||
|
YAxis: chart.YAxis{
|
||||||
|
Name: "Value",
|
||||||
|
},
|
||||||
|
Series: series,
|
||||||
|
}
|
||||||
|
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
graph.Render(chart.PNG, f)
|
||||||
|
}
|
BIN
examples/benchmark_line_charts/output.png
Normal file
After Width: | Height: | Size: 314 KiB |
|
@ -5,7 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Note: Additional examples on how to add Stylesheets are in the custom_stylesheets example
|
// Note: Additional examples on how to add Stylesheets are in the custom_stylesheets example
|
|
@ -1,13 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"os"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
/*
|
/*
|
||||||
In this example we use a custom `ValueFormatter` for the y axis, letting us specify how to format text of the y-axis ticks.
|
In this example we use a custom `ValueFormatter` for the y axis, letting us specify how to format text of the y-axis ticks.
|
||||||
You can also do this for the x-axis, or the secondary y-axis.
|
You can also do this for the x-axis, or the secondary y-axis.
|
||||||
|
@ -16,7 +18,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Style: chart.StyleShow(),
|
|
||||||
ValueFormatter: func(v interface{}) string {
|
ValueFormatter: func(v interface{}) string {
|
||||||
if vf, isFloat := v.(float64); isFloat {
|
if vf, isFloat := v.(float64); isFloat {
|
||||||
return fmt.Sprintf("%0.6f", vf)
|
return fmt.Sprintf("%0.6f", vf)
|
||||||
|
@ -31,12 +32,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
res.Header().Set("Content-Type", "image/png")
|
defer f.Close()
|
||||||
graph.Render(chart.PNG, res)
|
graph.Render(chart.PNG, f)
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/custom_formatters/output.png
Normal file
After Width: | Height: | Size: 29 KiB |
34
examples/custom_padding/main.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
graph := chart.Chart{
|
||||||
|
Background: chart.Style{
|
||||||
|
Padding: chart.Box{
|
||||||
|
Top: 50,
|
||||||
|
Left: 25,
|
||||||
|
Right: 25,
|
||||||
|
Bottom: 10,
|
||||||
|
},
|
||||||
|
FillColor: drawing.ColorFromHex("efefef"),
|
||||||
|
},
|
||||||
|
Series: []chart.Series{
|
||||||
|
chart.ContinuousSeries{
|
||||||
|
XValues: chart.Seq{Sequence: chart.NewLinearSequence().WithStart(1.0).WithEnd(100.0)}.Values(),
|
||||||
|
YValues: chart.Seq{Sequence: chart.NewRandomSequence().WithLen(100).WithMin(100).WithMax(512)}.Values(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
graph.Render(chart.PNG, f)
|
||||||
|
}
|
BIN
examples/custom_padding/output.png
Normal file
After Width: | Height: | Size: 65 KiB |
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
/*
|
/*
|
||||||
In this example we set a custom range for the y-axis, overriding the automatic range generation.
|
In this example we set a custom range for the y-axis, overriding the automatic range generation.
|
||||||
Note: the chart will still generate the ticks automatically based on the custom range, so the intervals may be a bit weird.
|
Note: the chart will still generate the ticks automatically based on the custom range, so the intervals may be a bit weird.
|
||||||
|
@ -14,7 +16,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Style: chart.StyleShow(),
|
|
||||||
Range: &chart.ContinuousRange{
|
Range: &chart.ContinuousRange{
|
||||||
Min: 0.0,
|
Min: 0.0,
|
||||||
Max: 10.0,
|
Max: 10.0,
|
||||||
|
@ -27,12 +28,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
res.Header().Set("Content-Type", "image/png")
|
defer f.Close()
|
||||||
graph.Render(chart.PNG, res)
|
graph.Render(chart.PNG, f)
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/custom_ranges/output.png
Normal file
After Width: | Height: | Size: 20 KiB |
|
@ -1,13 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
"github.com/wcharczuk/go-chart/drawing"
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
/*
|
/*
|
||||||
In this example we set some custom colors for the series and the chart background and canvas.
|
In this example we set some custom colors for the series and the chart background and canvas.
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +23,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
Series: []chart.Series{
|
Series: []chart.Series{
|
||||||
chart.ContinuousSeries{
|
chart.ContinuousSeries{
|
||||||
Style: chart.Style{
|
Style: chart.Style{
|
||||||
Show: true, //note; if we set ANY other properties, we must set this to true.
|
|
||||||
StrokeColor: drawing.ColorRed, // will supercede defaults
|
StrokeColor: drawing.ColorRed, // will supercede defaults
|
||||||
FillColor: drawing.ColorRed.WithAlpha(64), // will supercede defaults
|
FillColor: drawing.ColorRed.WithAlpha(64), // will supercede defaults
|
||||||
},
|
},
|
||||||
|
@ -31,11 +32,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/custom_styles/output.png
Normal file
After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 987 B After Width: | Height: | Size: 987 B |
|
@ -5,7 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const style = "svg .background { fill: white; }" +
|
const style = "svg .background { fill: white; }" +
|
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
/*
|
/*
|
||||||
In this example we set a custom set of ticks to use for the y-axis. It can be (almost) whatever you want, including some custom labels for ticks.
|
In this example we set a custom set of ticks to use for the y-axis. It can be (almost) whatever you want, including some custom labels for ticks.
|
||||||
Custom ticks will supercede a custom range, which will supercede automatic generation based on series values.
|
Custom ticks will supercede a custom range, which will supercede automatic generation based on series values.
|
||||||
|
@ -14,7 +16,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Style: chart.StyleShow(),
|
|
||||||
Range: &chart.ContinuousRange{
|
Range: &chart.ContinuousRange{
|
||||||
Min: 0.0,
|
Min: 0.0,
|
||||||
Max: 4.0,
|
Max: 4.0,
|
||||||
|
@ -35,12 +36,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
res.Header().Set("Content-Type", "image/png")
|
defer f.Close()
|
||||||
graph.Render(chart.PNG, res)
|
graph.Render(chart.PNG, f)
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/custom_ticks/output.png
Normal file
After Width: | Height: | Size: 17 KiB |
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The below will draw the same chart as the `basic` example, except with both the x and y axes turned on.
|
The below will draw the same chart as the `basic` example, except with both the x and y axes turned on.
|
||||||
|
@ -19,14 +21,12 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
Height: 500,
|
Height: 500,
|
||||||
Width: 500,
|
Width: 500,
|
||||||
XAxis: chart.XAxis{
|
XAxis: chart.XAxis{
|
||||||
Style: chart.StyleShow(),
|
|
||||||
/*Range: &chart.ContinuousRange{
|
/*Range: &chart.ContinuousRange{
|
||||||
Descending: true,
|
Descending: true,
|
||||||
},*/
|
},*/
|
||||||
},
|
},
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Style: chart.StyleShow(),
|
|
||||||
Range: &chart.ContinuousRange{
|
Range: &chart.ContinuousRange{
|
||||||
Descending: true,
|
Descending: true,
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
Series: []chart.Series{
|
Series: []chart.Series{
|
||||||
chart.ContinuousSeries{
|
chart.ContinuousSeries{
|
||||||
Style: chart.Style{
|
Style: chart.Style{
|
||||||
Show: true,
|
|
||||||
StrokeColor: chart.GetDefaultColor(0).WithAlpha(64),
|
StrokeColor: chart.GetDefaultColor(0).WithAlpha(64),
|
||||||
FillColor: chart.GetDefaultColor(0).WithAlpha(64),
|
FillColor: chart.GetDefaultColor(0).WithAlpha(64),
|
||||||
},
|
},
|
||||||
|
@ -44,11 +43,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/descending/output.png
Normal file
After Width: | Height: | Size: 19 KiB |
28
examples/donut_chart/main.go
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
pie := chart.DonutChart{
|
||||||
|
Width: 512,
|
||||||
|
Height: 512,
|
||||||
|
Values: []chart.Value{
|
||||||
|
{Value: 5, Label: "Blue"},
|
||||||
|
{Value: 5, Label: "Green"},
|
||||||
|
{Value: 4, Label: "Gray"},
|
||||||
|
{Value: 4, Label: "Orange"},
|
||||||
|
{Value: 3, Label: "Deep Blue"},
|
||||||
|
{Value: 3, Label: "test"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
pie.Render(chart.PNG, f)
|
||||||
|
}
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
222
examples/horizontal_stacked_bar/main.go
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2/drawing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
chart.DefaultBackgroundColor = chart.ColorTransparent
|
||||||
|
chart.DefaultCanvasColor = chart.ColorTransparent
|
||||||
|
|
||||||
|
barWidth := 80
|
||||||
|
|
||||||
|
var (
|
||||||
|
colorWhite = drawing.Color{R: 241, G: 241, B: 241, A: 255}
|
||||||
|
colorMariner = drawing.Color{R: 60, G: 100, B: 148, A: 255}
|
||||||
|
colorLightSteelBlue = drawing.Color{R: 182, G: 195, B: 220, A: 255}
|
||||||
|
colorPoloBlue = drawing.Color{R: 126, G: 155, B: 200, A: 255}
|
||||||
|
colorSteelBlue = drawing.Color{R: 73, G: 120, B: 177, A: 255}
|
||||||
|
)
|
||||||
|
|
||||||
|
stackedBarChart := chart.StackedBarChart{
|
||||||
|
Title: "Quarterly Sales",
|
||||||
|
TitleStyle: chart.Shown(),
|
||||||
|
Background: chart.Style{
|
||||||
|
Padding: chart.Box{
|
||||||
|
Top: 75,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Width: 800,
|
||||||
|
Height: 600,
|
||||||
|
XAxis: chart.Shown(),
|
||||||
|
YAxis: chart.Shown(),
|
||||||
|
BarSpacing: 40,
|
||||||
|
IsHorizontal: true,
|
||||||
|
Bars: []chart.StackedBar{
|
||||||
|
{
|
||||||
|
Name: "Q1",
|
||||||
|
Width: barWidth,
|
||||||
|
Values: []chart.Value{
|
||||||
|
{
|
||||||
|
Label: "32K",
|
||||||
|
Value: 32,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorMariner,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "46K",
|
||||||
|
Value: 46,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorLightSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "48K",
|
||||||
|
Value: 48,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorPoloBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "42K",
|
||||||
|
Value: 42,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Q2",
|
||||||
|
Width: barWidth,
|
||||||
|
Values: []chart.Value{
|
||||||
|
{
|
||||||
|
Label: "45K",
|
||||||
|
Value: 45,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorMariner,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "60K",
|
||||||
|
Value: 60,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorLightSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "62K",
|
||||||
|
Value: 62,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorPoloBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "53K",
|
||||||
|
Value: 53,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Q3",
|
||||||
|
Width: barWidth,
|
||||||
|
Values: []chart.Value{
|
||||||
|
{
|
||||||
|
Label: "54K",
|
||||||
|
Value: 54,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorMariner,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "58K",
|
||||||
|
Value: 58,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorLightSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "55K",
|
||||||
|
Value: 55,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorPoloBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "47K",
|
||||||
|
Value: 47,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Q4",
|
||||||
|
Width: barWidth,
|
||||||
|
Values: []chart.Value{
|
||||||
|
{
|
||||||
|
Label: "46K",
|
||||||
|
Value: 46,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorMariner,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "70K",
|
||||||
|
Value: 70,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorLightSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "74K",
|
||||||
|
Value: 74,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorPoloBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: "60K",
|
||||||
|
Value: 60,
|
||||||
|
Style: chart.Style{
|
||||||
|
StrokeWidth: .01,
|
||||||
|
FillColor: colorSteelBlue,
|
||||||
|
FontColor: colorWhite,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pngFile, err := os.Create("output.png")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stackedBarChart.Render(chart.PNG, pngFile); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pngFile.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
BIN
examples/horizontal_stacked_bar/output.png
Normal file
After Width: | Height: | Size: 34 KiB |
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
chart "git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In this example we add a `Renderable` or a custom component to the `Elements` array.
|
In this example we add a `Renderable` or a custom component to the `Elements` array.
|
||||||
|
@ -15,12 +17,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
XAxis: chart.XAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Background: chart.Style{
|
Background: chart.Style{
|
||||||
Padding: chart.Box{
|
Padding: chart.Box{
|
||||||
Top: 20,
|
Top: 20,
|
||||||
|
@ -41,11 +37,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
chart.Legend(&graph),
|
chart.Legend(&graph),
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/legend/output.png
Normal file
After Width: | Height: | Size: 24 KiB |
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In this example we add a `Renderable` or a custom component to the `Elements` array.
|
In this example we add a `Renderable` or a custom component to the `Elements` array.
|
||||||
|
@ -15,12 +17,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
graph := chart.Chart{
|
graph := chart.Chart{
|
||||||
XAxis: chart.XAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
YAxis: chart.YAxis{
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
|
||||||
Background: chart.Style{
|
Background: chart.Style{
|
||||||
Padding: chart.Box{
|
Padding: chart.Box{
|
||||||
Top: 20,
|
Top: 20,
|
||||||
|
@ -101,11 +97,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
chart.LegendLeft(&graph),
|
chart.LegendLeft(&graph),
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/legend_left/output.png
Normal file
After Width: | Height: | Size: 44 KiB |
|
@ -1,13 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
"github.com/wcharczuk/go-chart/seq"
|
"os"
|
||||||
|
|
||||||
|
chart "git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In this example we add a new type of series, a `SimpleMovingAverageSeries` that takes another series as a required argument.
|
In this example we add a new type of series, a `SimpleMovingAverageSeries` that takes another series as a required argument.
|
||||||
|
@ -16,8 +17,8 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
mainSeries := chart.ContinuousSeries{
|
mainSeries := chart.ContinuousSeries{
|
||||||
Name: "A test series",
|
Name: "A test series",
|
||||||
XValues: SeqRange(1.0, 100.0), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements.
|
XValues: chart.Seq{Sequence: chart.NewLinearSequence().WithStart(1.0).WithEnd(100.0)}.Values(), //generates a []float64 from 1.0 to 100.0 in 1.0 step increments, or 100 elements.
|
||||||
YValues: seq.RandomValuesWithMax(100, 100), //generates a []float64 randomly from 0 to 100 with 100 elements.
|
YValues: chart.Seq{Sequence: chart.NewRandomSequence().WithLen(100).WithMin(0).WithMax(100)}.Values(), //generates a []float64 randomly from 0 to 100 with 100 elements.
|
||||||
}
|
}
|
||||||
|
|
||||||
// note we create a LinearRegressionSeries series by assignin the inner series.
|
// note we create a LinearRegressionSeries series by assignin the inner series.
|
||||||
|
@ -33,11 +34,7 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/linear_regression/output.png
Normal file
After Width: | Height: | Size: 71 KiB |
41
examples/logarithmic_axes/main.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
In this example we set the primary YAxis to have logarithmic range.
|
||||||
|
*/
|
||||||
|
|
||||||
|
graph := chart.Chart{
|
||||||
|
Background: chart.Style{
|
||||||
|
Padding: chart.Box{
|
||||||
|
Top: 20,
|
||||||
|
Left: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Series: []chart.Series{
|
||||||
|
chart.ContinuousSeries{
|
||||||
|
Name: "A test series",
|
||||||
|
XValues: []float64{1.0, 2.0, 3.0, 4.0, 5.0},
|
||||||
|
YValues: []float64{1, 10, 100, 1000, 10000},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
YAxis: chart.YAxis{
|
||||||
|
Style: chart.Shown(),
|
||||||
|
NameStyle: chart.Shown(),
|
||||||
|
Range: &chart.LogarithmicRange{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
graph.Render(chart.PNG, f)
|
||||||
|
}
|
BIN
examples/logarithmic_axes/output.png
Normal file
After Width: | Height: | Size: 16 KiB |
|
@ -1,22 +1,22 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
//go:generate go run main.go
|
||||||
"net/http"
|
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
import (
|
||||||
"github.com/wcharczuk/go-chart/seq"
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func main() {
|
||||||
mainSeries := chart.ContinuousSeries{
|
mainSeries := chart.ContinuousSeries{
|
||||||
Name: "A test series",
|
Name: "A test series",
|
||||||
XValues: SeqRange(1.0, 100.0),
|
XValues: chart.Seq{Sequence: chart.NewLinearSequence().WithStart(1.0).WithEnd(100.0)}.Values(),
|
||||||
YValues: seq.New(seq.NewRandom().WithLen(100).WithMax(150).WithMin(50)).Array(),
|
YValues: chart.Seq{Sequence: chart.NewRandomSequence().WithLen(100).WithMin(50).WithMax(150)}.Values(),
|
||||||
}
|
}
|
||||||
|
|
||||||
minSeries := &chart.MinSeries{
|
minSeries := &chart.MinSeries{
|
||||||
Style: chart.Style{
|
Style: chart.Style{
|
||||||
Show: true,
|
|
||||||
StrokeColor: chart.ColorAlternateGray,
|
StrokeColor: chart.ColorAlternateGray,
|
||||||
StrokeDashArray: []float64{5.0, 5.0},
|
StrokeDashArray: []float64{5.0, 5.0},
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,6 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
maxSeries := &chart.MaxSeries{
|
maxSeries := &chart.MaxSeries{
|
||||||
Style: chart.Style{
|
Style: chart.Style{
|
||||||
Show: true,
|
|
||||||
StrokeColor: chart.ColorAlternateGray,
|
StrokeColor: chart.ColorAlternateGray,
|
||||||
StrokeDashArray: []float64{5.0, 5.0},
|
StrokeDashArray: []float64{5.0, 5.0},
|
||||||
},
|
},
|
||||||
|
@ -36,35 +35,27 @@ func drawChart(res http.ResponseWriter, req *http.Request) {
|
||||||
Width: 1920,
|
Width: 1920,
|
||||||
Height: 1080,
|
Height: 1080,
|
||||||
YAxis: chart.YAxis{
|
YAxis: chart.YAxis{
|
||||||
Name: "Random Values",
|
Name: "Random Values",
|
||||||
NameStyle: chart.StyleShow(),
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
Range: &chart.ContinuousRange{
|
Range: &chart.ContinuousRange{
|
||||||
Min: 25,
|
Min: 25,
|
||||||
Max: 175,
|
Max: 175,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
XAxis: chart.XAxis{
|
XAxis: chart.XAxis{
|
||||||
Name: "Random Other Values",
|
Name: "Random Other Values",
|
||||||
NameStyle: chart.StyleShow(),
|
|
||||||
Style: chart.StyleShow(),
|
|
||||||
},
|
},
|
||||||
Series: []chart.Series{
|
Series: []chart.Series{
|
||||||
mainSeries,
|
mainSeries,
|
||||||
minSeries,
|
minSeries,
|
||||||
maxSeries,
|
maxSeries,
|
||||||
chart.LastValueAnnotation(minSeries),
|
chart.LastValueAnnotationSeries(minSeries),
|
||||||
chart.LastValueAnnotation(maxSeries),
|
chart.LastValueAnnotationSeries(maxSeries),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.Elements = []chart.Renderable{chart.Legend(&graph)}
|
graph.Elements = []chart.Renderable{chart.Legend(&graph)}
|
||||||
|
|
||||||
res.Header().Set("Content-Type", "image/png")
|
f, _ := os.Create("output.png")
|
||||||
graph.Render(chart.PNG, res)
|
defer f.Close()
|
||||||
}
|
graph.Render(chart.PNG, f)
|
||||||
|
|
||||||
func main() {
|
|
||||||
http.HandleFunc("/", drawChart)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
|
||||||
}
|
}
|
BIN
examples/min_max/output.png
Normal file
After Width: | Height: | Size: 168 KiB |
29
examples/pie_chart/main.go
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
//go:generate go run main.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
pie := chart.PieChart{
|
||||||
|
Width: 512,
|
||||||
|
Height: 512,
|
||||||
|
Values: []chart.Value{
|
||||||
|
{Value: 5, Label: "Blue"},
|
||||||
|
{Value: 5, Label: "Green"},
|
||||||
|
{Value: 4, Label: "Gray"},
|
||||||
|
{Value: 4, Label: "Orange"},
|
||||||
|
{Value: 3, Label: "Deep Blue"},
|
||||||
|
{Value: 3, Label: "??"},
|
||||||
|
{Value: 1, Label: "!!"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
f, _ := os.Create("output.png")
|
||||||
|
defer f.Close()
|
||||||
|
pie.Render(chart.PNG, f)
|
||||||
|
}
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 565 B After Width: | Height: | Size: 565 B |
|
@ -5,7 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
chart "github.com/wcharczuk/go-chart"
|
"git.smarteching.com/zeni/go-chart/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func drawChart(res http.ResponseWriter, req *http.Request) {
|
func drawChart(res http.ResponseWriter, req *http.Request) {
|