-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from nao1215/piechart
Introduce pie chart (mermaid)
- Loading branch information
Showing
11 changed files
with
594 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## Pie Chart | ||
```mermaid | ||
%%{init: {"pie": {"textPosition": 0.75}, "themeVariables": {"pieOuterStrokeWidth": "5px"}} }%% | ||
pie showData | ||
title mermaid pie chart builder | ||
"A" : 10 | ||
"B" : 20.100000 | ||
"C" : 30 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
//go:build linux || darwin | ||
|
||
// Package main is generating mermaid sequence diagram. | ||
package main | ||
|
||
import ( | ||
"io" | ||
"os" | ||
|
||
"github.com/nao1215/markdown" | ||
"github.com/nao1215/markdown/mermaid/piechart" | ||
) | ||
|
||
//go:generate go run main.go | ||
|
||
func main() { | ||
f, err := os.Create("generated.md") | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
chart := piechart.NewPieChart( | ||
io.Discard, | ||
piechart.WithTitle("mermaid pie chart builder"), | ||
piechart.WithShowData(true), | ||
). | ||
LabelAndIntValue("A", 10). | ||
LabelAndFloatValue("B", 20.1). | ||
LabelAndIntValue("C", 30). | ||
String() | ||
|
||
err = markdown.NewMarkdown(f). | ||
H2("Pie Chart"). | ||
CodeBlocks(markdown.SyntaxHighlightMermaid, chart). | ||
Build() | ||
|
||
if err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package piechart | ||
|
||
// config is a pie chart configuration. | ||
type config struct { | ||
// The axial position of the pie slice labels, | ||
// from 0.0 at the center to 1.0 at the outside edge of the circle. | ||
textPosition float64 | ||
// showData is a flag to show the data in the pie chart. | ||
showData bool | ||
// title is the title of the pie chart. | ||
title string | ||
} | ||
|
||
// newConfig returns a new Config with default values. | ||
func newConfig() *config { | ||
return &config{ | ||
textPosition: defaultTextPosition, | ||
} | ||
} | ||
|
||
const ( | ||
// defaultTextPosition is the default axial position of the pie slice labels. | ||
defaultTextPosition float64 = 0.75 | ||
// minTextPosition is the minimum axial position of the pie slice labels. | ||
minTextPosition float64 = 0.0 | ||
// maxTextPosition is the maximum axial position of the pie slice labels. | ||
maxTextPosition float64 = 1.0 | ||
// noTitle is a constant for no title. | ||
noTitle string = "" | ||
) | ||
|
||
// Option sets the options for the PieChart struct. | ||
type Option func(*config) | ||
|
||
// WithTextPosition sets the axial position of the pie slice labels. | ||
// The axial position of the pie slice labels, from 0.0 at the center | ||
// to 1.0 at the outside edge of the circle. | ||
// If pos is less than 0.0 or greater than 1.0, it will be set to the default value (0.75) | ||
func WithTextPosition(pos float64) Option { | ||
return func(c *config) { | ||
if pos < minTextPosition || pos > maxTextPosition { | ||
pos = defaultTextPosition | ||
} | ||
c.textPosition = pos | ||
} | ||
} | ||
|
||
// WithShowData sets the showData configuration. | ||
func WithShowData(showData bool) Option { | ||
return func(c *config) { | ||
c.showData = showData | ||
} | ||
} | ||
|
||
// WithTitle sets the title configuration. | ||
func WithTitle(title string) Option { | ||
return func(c *config) { | ||
c.title = title | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Package piechart is mermaid pie chart builder. | ||
package piechart | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"runtime" | ||
"strings" | ||
) | ||
|
||
// PieChart is a pie chart builder. | ||
type PieChart struct { | ||
// body is pie chart body. | ||
body []string | ||
// dest is output destination for pie chart body. | ||
dest io.Writer | ||
// err manages errors that occur in all parts of the pie chart building. | ||
err error | ||
// config is the configuration for the pie chart. | ||
config *config | ||
} | ||
|
||
// NewPieChart returns a new PieChart. | ||
func NewPieChart(w io.Writer, opts ...Option) *PieChart { | ||
c := newConfig() | ||
|
||
for _, opt := range opts { | ||
opt(c) | ||
} | ||
|
||
lines := []string{} | ||
lines = append( | ||
lines, | ||
fmt.Sprintf( | ||
"%%%%{init: {\"pie\": {\"textPosition\": %.2f}, \"themeVariables\": {\"pieOuterStrokeWidth\": \"5px\"}} }%%%%", | ||
c.textPosition, | ||
)) | ||
|
||
baseLine := "pie" | ||
if c.showData { | ||
baseLine += " showData" | ||
} | ||
|
||
if c.title == noTitle { | ||
lines = append(lines, baseLine) | ||
} else { | ||
lines = append(lines, baseLine) | ||
lines = append(lines, fmt.Sprintf(" title %s", c.title)) | ||
} | ||
|
||
return &PieChart{ | ||
body: lines, | ||
dest: w, | ||
config: c, | ||
} | ||
} | ||
|
||
// String returns the pie chart body. | ||
func (p *PieChart) String() string { | ||
return strings.Join(p.body, lineFeed()) | ||
} | ||
|
||
// Build writes the pie chart body to the output destination. | ||
func (p *PieChart) Build() error { | ||
if _, err := fmt.Fprint(p.dest, p.String()); err != nil { | ||
if p.err != nil { | ||
return fmt.Errorf("failed to write: %w: %s", err, p.err.Error()) //nolint:wrapcheck | ||
} | ||
return fmt.Errorf("failed to write: %w", err) | ||
} | ||
return nil | ||
} | ||
|
||
// LabelAndIntValue adds a label and value to the pie chart. | ||
func (p *PieChart) LabelAndIntValue(label string, value uint64) *PieChart { | ||
p.body = append(p.body, fmt.Sprintf(" \"%s\" : %d", label, value)) | ||
return p | ||
} | ||
|
||
// LabelAndFloatValue adds a label and value to the pie chart. | ||
// The value is formatted with a precision of 6 digits after the decimal point. | ||
func (p *PieChart) LabelAndFloatValue(label string, value float64) *PieChart { | ||
p.body = append(p.body, fmt.Sprintf(" \"%s\" : %f", label, value)) | ||
return p | ||
} | ||
|
||
// lineFeed return line feed for current OS. | ||
func lineFeed() string { | ||
if runtime.GOOS == "windows" { | ||
return "\r\n" | ||
} | ||
return "\n" | ||
} |
Oops, something went wrong.