diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f5739f2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "cwd": "./examples", + "program": "${fileDirname}" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 04e4d1d..6517b2d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ -goplot -====== +# goplot goplot 是一个使用简单的绘制图表的工具,图表绘制使用了[Chart.js](http://www.chartjs.org/)开源库,编译好的goplot只有一个二进制文件,不依赖任何库/网络。 -##### 下载 +## 下载 [Mac OS X](http://www.bigendian123.com/goplot-darwin.tar.gz) @@ -11,23 +10,32 @@ goplot 是一个使用简单的绘制图表的工具,图表绘制使用了[Cha Windows暂缺 -##### 使用方法 +## 使用方法 * 解压下载包后,进入解压目录,可以看到一个 goplot 的可执行文件和一些 *.chart 文件,这些 chart 文件是默认的一些数据文件样例。可以在这些 chart 文件的目录执行 goplot,然后通过浏览器访问: 就可以看到图表了。 * 你可以把 `goplot` 工具放到你的 `PATH` 中,在 chart 文件所在的目录执行 goplot 即可。 * chart 文件必须是 .chart 后缀名,内容可以参考源码 examples 目录中的例子。启动 goplot 的目录如果有多个 chart 文件,可以通过不断刷新网页来切换图表。 -.chart 文件定义了 Chart 的 Name,goplot 会根据该 Name 建立路由规则,访问对应 Name 的 Chart 规则为: +.chart 文件定义了 Chart 的 Type,可以为以下字符串: + +* line +* bar +* pie + +goplot 根据路由来匹配 .chart 文件,URL 一级名称即为需要解析的 .chart 文件名(路由中不包含扩展名部分) ```url -http://localhost:8000/\ +http://localhost:8000/\ ``` -##### 曲线图 -![](image/line.png) +## 曲线图 -##### 柱状图 -![](image/bar.png) +![line](image/line.png) -##### 饼图 -![](image/pie.png) \ No newline at end of file +## 柱状图 + +![bar](image/bar.png) + +## 饼图 + +![pie](image/pie.png) diff --git a/data.go b/data.go index 3102f1b..789c3f9 100644 --- a/data.go +++ b/data.go @@ -8,13 +8,14 @@ import ( "io" "log" "os" - "path/filepath" "strconv" "strings" ) +type ParseState int + const ( - START = iota + START ParseState = iota PROP DATA ) @@ -25,9 +26,9 @@ var ( ) type ChartPropType struct { - Name string - Width int - Height int + Type string `json:"Type"` + Width int `json:"Width"` + Height int `json:"Height"` } type ChartItemType struct { @@ -146,20 +147,20 @@ func ParseDataFile(file string) ([]*ChartDataType, error) { switch status { case START: - if bytes.Compare(line, prop_header_str) == 0 { + if bytes.Equal(line, prop_header_str) { status = PROP c = newChartData() } else { return nil, errors.New("invalid chart file") } case PROP: - if bytes.Compare(line, data_header_str) == 0 { + if bytes.Equal(line, data_header_str) { status = DATA } else { c.appendProp(line) } case DATA: - if bytes.Compare(line, prop_header_str) == 0 { + if bytes.Equal(line, prop_header_str) { status = PROP charts = append(charts, c) c = newChartData() @@ -173,28 +174,3 @@ func ParseDataFile(file string) ([]*ChartDataType, error) { charts = append(charts, c) return charts, nil } - -func LookupCurrentDir(dir string) ([]string, error) { - var tmp []string = make([]string, 0, 5) - - err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { - if f == nil { - return err - } - - if f.IsDir() { - return nil - } - - if ok, err := filepath.Match("*.chart", f.Name()); err != nil { - return err - } else if ok { - if path == f.Name() { - tmp = append(tmp, path) - } - } - return nil - }) - - return tmp, err -} diff --git a/examples/bar.chart b/examples/bar.chart index cc8e02d..2ddb64e 100644 --- a/examples/bar.chart +++ b/examples/bar.chart @@ -1,5 +1,5 @@ === -{ "Name" : "bar", "Height" : 300, "Width" : 550 } +{ "Type":"bar", "Height":300, "Width":550 } --- aaa 10 13 bbb 15 12 diff --git a/examples/line.chart b/examples/line.chart index 77f7672..3fbb4b8 100644 --- a/examples/line.chart +++ b/examples/line.chart @@ -1,7 +1,7 @@ === -{ "Name" : "line", "Height" : 300, "Width" : 550 } +{ "Type":"line", "Height":300, "Width":550 } --- -aaa 10 13 10 -bbb 15 12 11 -ccc 23 14 15 -ddd 20 24 25 +1.0 10 13 10 +2.0 15 12 11 +3.0 23 14 15 +4.0 20 24 25 diff --git a/examples/pie.chart b/examples/pie.chart index a5bc11f..5f70c82 100644 --- a/examples/pie.chart +++ b/examples/pie.chart @@ -1,5 +1,5 @@ === -{ "Name" : "pie", "Height" : 300, "Width" : 550 } +{ "Type":"pie", "Height":300, "Width":550 } --- aaa 10 bbb 15 diff --git a/main.go b/main.go index 9c5a5da..3d3bb54 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,29 @@ package main -const start = `version: 1.0 -http://localhost:8000` +import ( + "flag" + "fmt" +) + +var ( + ChartDir string + Welcome string = `version: 1.0 +http://localhost:` +) + +func usage() { + fmt.Println("goplot version v1.0.1") + flag.PrintDefaults() +} func main() { - println(start) - println(ListenAndServe(":8000").Error()) + var port string + flag.StringVar(&ChartDir, "c", "./", "Chart dir") + flag.StringVar(&port, "p", "8000", "Listen port") + flag.Usage = usage + flag.Parse() + + Welcome += port + println(Welcome) + println(ListenAndServe(":" + port).Error()) } diff --git a/server.go b/server.go index c05e3b7..fb70a01 100644 --- a/server.go +++ b/server.go @@ -2,6 +2,7 @@ package main import ( "net/http" + "path/filepath" "strings" "text/template" ) @@ -40,24 +41,17 @@ type ChartIf interface { NewChart(string) string } -var ( - ChartHandlers = make(map[string]ChartIf) - ChartFiles []string - Index int -) +var ChartHandlers = make(map[string]ChartIf) func handler(w http.ResponseWriter, r *http.Request) { - if len(ChartFiles) == 0 { + urls := strings.Split(r.URL.String(), "/") + if 2 > len(urls) { + w.Write([]byte("RouteError")) return } - var file string - if Index < len(ChartFiles) { - file = ChartFiles[Index] - Index++ - } else { - Index = 0 - file = ChartFiles[Index] - } + + file := urls[1] + ".chart" + file = filepath.Join(ChartDir, file) datas, err := ParseDataFile(file) if err != nil { @@ -80,12 +74,8 @@ func handler(w http.ResponseWriter, r *http.Request) { return } else { var ok bool - urls := strings.Split(r.URL.String(), "/") - if 2 > len(urls) { - w.Write([]byte(err.Error())) - return - } - chart, ok = ChartHandlers[urls[1]] + + chart, ok = ChartHandlers[prop.Type] if !ok { w.Write([]byte(err.Error())) return @@ -118,10 +108,5 @@ func ListenAndServe(addr string) error { http.HandleFunc("/", handler) http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {}) - var err error - ChartFiles, err = LookupCurrentDir(".") - if err != nil { - return err - } return http.ListenAndServe(addr, nil) }