All Projects → cnguy → gopherjs-frappe-charts

cnguy / gopherjs-frappe-charts

Licence: MIT license
[experimental/outdated; frappe v0.07] GopherJS bindings for frappe/charts - simple Go charts for your frontend

Programming Languages

go
31211 projects - #10 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to gopherjs-frappe-charts

go-pouchdb
GopherJS bindings for PouchDB ⚠️ NOTICE ⚠️ this package has been superseded by https://github.com/go-kivik/kivik
Stars: ✭ 12 (-40%)
Mutual labels:  gopherjs, gopherjs-bindings
slope
C/Gtk+ data visualization library.
Stars: ✭ 91 (+355%)
Mutual labels:  charts
ipychart
The power of Chart.js with Python
Stars: ✭ 48 (+140%)
Mutual labels:  charts
nettemp
Interface for controlling the temperature sensors DS18B20, supports; serial DS9097, usb DS9097U, usb DS2490, Raspberry Pi GPIO
Stars: ✭ 53 (+165%)
Mutual labels:  charts
ggwaffle
Creating waffle charts in a ggplot friendly way
Stars: ✭ 45 (+125%)
Mutual labels:  charts
o-fish-web
Web application for the Officer's Fishery Information Sharing Hub (O-FISH). The web app allows agencies to gain insights from the aggregated information gathered during a routine vessel inspection (submitted via the web app).
Stars: ✭ 29 (+45%)
Mutual labels:  charts
beapi-bench
Tool for benchmarking apis. Uses ApacheBench(ab) to generate data and gnuplot for graphing. Adding new features almost daily
Stars: ✭ 16 (-20%)
Mutual labels:  charts
Samples-ASP.NET-MVC-CSharp
ASP.NET MVC C# samples for Stimulsoft Reports.Web reporting tool.
Stars: ✭ 31 (+55%)
Mutual labels:  charts
apexcharts-flow
ApexCharts.js wrapper for the Vaadin Platform
Stars: ✭ 43 (+115%)
Mutual labels:  charts
JMeter-Charts
Application used to generate reports by uploading a JTL file to a rest server
Stars: ✭ 19 (-5%)
Mutual labels:  charts
elementary-plotlib
C/C++ Plotting Library
Stars: ✭ 19 (-5%)
Mutual labels:  charts
KLineChartAndroid
A kline chart UI widget for android(Android版本的k线).
Stars: ✭ 51 (+155%)
Mutual labels:  charts
vue3-charts
Vue3-Charts is an SVG-based charting library that is very easy to use and highly customizable
Stars: ✭ 86 (+330%)
Mutual labels:  charts
vistime
Pretty timelines in R.
Stars: ✭ 133 (+565%)
Mutual labels:  charts
RealmAndCharts-example
Simple example of how to use RealmSwift and Charts together - iOS 10 & Swift 3
Stars: ✭ 20 (+0%)
Mutual labels:  charts
trakttvstats
A chrome extension adding various improvements to trakt.tv
Stars: ✭ 23 (+15%)
Mutual labels:  charts
PandasVersusExcel
Python数据分析入门,数据分析师入门
Stars: ✭ 120 (+500%)
Mutual labels:  charts
Mtgdb
Mtgdb.Gui - desktop app to search MTG cards and build decks
Stars: ✭ 46 (+130%)
Mutual labels:  charts
oxyplot-avalonia
A cross-platform plotting library for .NET. This package targets Avalonia apps.
Stars: ✭ 102 (+410%)
Mutual labels:  charts
chart-testing-action
A GitHub Action to lint and test Helm charts
Stars: ✭ 139 (+595%)
Mutual labels:  charts

GopherJS bindings for frappe/charts

Go Report Card GoDoc

"Simple, responsive, modern SVG Charts with zero dependencies"

This library provides a type-safe, builder-based API for the simple and awesome frappe/charts.

Event listener with navigable bar chart:

Alt text

Various chart operations (append, remove, pop) with (mock "realtime") randomized data and actions:

Alt text

Contents

Installation

Built on go 1.9

go get -u github.com/cnguy/gopherjs-frappe-charts

Make sure you also have the necessary JS files.

Currently, this API supports frappe/[email protected] (maybe 0.0.8 too, since it seems that they didn't change the API in that version).

Dependencies will be managed via dep in the future.

Unfortunately, gopherjs is not vendorable at the moment.

Breaking Changes

This libary seeks to be updated to always work with the latest version of frappe charts. It also seeks to have a clean API so that users can easily bring in charts into their GopherJS-based website. One can also expect that this library will improve as I improve at Go.

Frappe hasn't changed their API dramatically so far, so one can expect that this library won't change dramatically as well. If there are breaking changes, it should be easy to update one's code by simply following the type errors.

The Bare Minimum

Following examples assume an HTML file like so:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>GopherJS bindings for frappe-charts</title>
</head>
<body>
	<div id="chart"></div>
	<div id="chart-2"></div>
	<div id="heatmap"></div>
	<script src="https://unpkg.com/[email protected]/dist/frappe-charts.min.iife.js"></script>
	<script src="static.js" data-cover></script>
</body>
</html>

where static.js is the name of your bundled JS file when your folder is named static and you run gopherjs build.

package main

import (
	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	chartData := charts.NewChartData()
	chartData.Labels = []string{
		"1", "2", "3",
	}
	chartData.Datasets = []*charts.Dataset{
		charts.NewDataset(
			"Some Data",
			[]float64{25, 40, 30},
		),
		charts.NewDataset(
			"Another Set",
			[]float64{25, 50, -10},
		),
	}

	_ = charts.NewBarChart("#chart", chartData).Render()
}

Alt text

This is the bare minimum needed to create a chart. Try swapping NewBarChart with other functions such as NewPercentageChart or NewPieChart.

frappe already sets defaults for a lot of properties. All New${Type}Chart calls handles the two necessary properties (the title and the chart data).

Everything else is optional (the title, colors, etc).

To learn how to provide more arguments, scroll down to Usage.

Usage

Simply declare chart data via NewChartData() and pass in array of *Datasets constructed by NewDataset().

This data can then be passed in to 99% of the charts (Heatmap is different).

This library uses the builder pattern to handle optional configurations. Every chart can be immediately rendered simply by doing

NewSomeChart("#parent", myData).Render()

If you would like to use optional configuration, check out the docs or simply just use your IDE (NewSomeChart returns a chainable object).

Tip: Prefer using the helpers instead of struct literals.

Hello World:

package main

import (
	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	// Prepare data
	chartData := charts.NewChartData()
	chartData.Labels = []string{
		"12am-3am", "3am-6pm", "6am-9am", "9am-12am",
		"12pm-3pm", "3pm-6pm", "6pm-9pm", "9am-12am",
	}
	chartData.Datasets = []*charts.Dataset{
		charts.NewDataset(
			"Some Data",
			[]float64{25, 40, 30, 35, 8, 52, 17, -4},
		),
		charts.NewDataset(
			"Another Set",
			[]float64{25, 50, -10, 15, 18, 32, 27, 14},
		),
	}

	chart := charts.NewBarChart("#chart", chartData).
		WithHeight(250). // `150` is default if this call is not applied.
		WithColors([]string{"light-blue", "violet"}).
		Render() // not calling Render returns a XXXChartArgs instance instead

	// TIP: Try swapping NewBarChart with NewPercentageChart or NewScatterChart
	// to see how easy it is to swap to a different type of chart.
	println(chart) // to suppress the annoying error
}

Output 1:

Alt text

Navigable:

package main

import (
	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	// Prepare data
	chartData := charts.NewChartData()
	chartData.Labels = []string{
		"2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017",
	}
	values := []float64{17, 40, 33, 44, 126, 156, 324, 333, 478, 495, 373}
	dataset := charts.NewDataset("Events", values)
	chartData.Datasets = []*charts.Dataset{dataset}

	chartTitle := "Fireball/Bolide Events - Yearly (more than 5 reports)"
	chart := charts.NewBarChart("#chart", chartData).
		WithTitle(chartTitle).
		WithColors([]string{"orange"}).
		SetIsNavigable(true). // ChartArgs#IsNavigable = 1
		SetIsSeries(true).    // ChartArgs#IsSeries = 1
		Render()

	println(chart)
}

Output 2:

Using left/right arrow keys to traverse the graph

Alt text

Line Properties:

package main

import (
	charts "github.com/cnguy/gopherjs-frappe-charts"
	chartsUtils "github.com/cnguy/gopherjs-frappe-charts/utils"
)

func main() {
	// Prepare data
	chartData := charts.NewChartData()
	chartData.Labels = chartsUtils.NumberLabelsToStr([]int{
		1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
		1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986,
		1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
		1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
		2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
	})
	values := []float64{
		132.9, 150.0, 149.4, 148.0, 94.4, 97.6, 54.1, 49.2, 22.5, 18.4,
		39.3, 131.0, 220.1, 218.9, 198.9, 162.4, 91.0, 60.5, 20.6, 14.8,
		33.9, 123.0, 211.1, 191.8, 203.3, 133.0, 76.1, 44.9, 25.1, 11.6,
		28.9, 88.3, 136.3, 173.9, 170.4, 163.6, 99.3, 65.3, 45.8, 24.7,
		12.6, 4.2, 4.8, 24.9, 80.8, 84.5, 94.0, 113.3, 69.8, 39.8,
	}
	dataset := charts.NewDataset("", values)
	chartData.Datasets = []*charts.Dataset{dataset}

	chartTitle := "Mean Total Sunspot Count - Yearly"
	chart := charts.NewLineChart("#chart", chartData).
		WithTitle(chartTitle).
		WithColors([]string{"blue"}).
		SetShowDots(false).
		SetHeatline(true).
		SetRegionFill(true).
		SetXAxisMode("tick").
		SetYAxisMode("span").
		SetIsSeries(true).
		Render()

	println(chart)
}

Output 3:

Alt text

Simple Aggregations:

package main

import (
	"time"

	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	chartData := charts.NewChartData()
	chartData.Labels = []string{
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
	}
	chartData.Datasets = []*charts.Dataset{
		charts.NewDataset("", []float64{25, 40, 30, 35, 8, 52, 17}),
		charts.NewDataset("", []float64{25, 50, -10, 15, 18, 32, 27}),
	}

	chart := charts.NewBarChart("#chart", chartData).
		WithColors([]string{"purple", "orange"}).
		Render()

	time.Sleep(1 * time.Second)
	chart.ShowSums()

	time.Sleep(1 * time.Second)
	chart.HideSums()

	time.Sleep(1 * time.Second)
	chart.ShowAverages()

	time.Sleep(1 * time.Second)
	chart.HideAverages()
}

Output 4:

Alt text

Event Listener:

package main

import (
	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	// Make bar chart
	reportCountList := []float64{17, 40, 33, 44, 126, 156,
		324, 333, 478, 495, 373}
	barChartData := charts.NewChartData()
	barChartData.Labels = []string{
		"2007", "2008", "2009", "2010", "2011", "2012",
		"2013", "2014", "2015", "2016", "2017",
	}
	barChartData.Datasets = []*charts.Dataset{
		charts.NewDataset("Events", reportCountList),
	}
	barChartTitle := "Fireball/Bolide Events - Yearly (more than 5 reports"
	barChart := charts.NewBarChart("#chart", barChartData).
		WithTitle(barChartTitle).
		WithHeight(180).
		WithColors([]string{"orange"}).
		SetIsNavigable(true).
		SetIsSeries(true).
		Render()

	// Make line chart
	lineChartValues := []float64{36, 46, 45, 32, 27, 31, 30, 36, 39, 49, 0, 0}
	lineChartData := charts.NewChartData()
	lineChartData.Labels = []string{
		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
	}
	lineChartData.Datasets = []*charts.Dataset{
		charts.NewDataset("", lineChartValues),
	}
	lineChart := charts.NewLineChart("#chart-2", lineChartData).
		WithHeight(180).
		WithColors([]string{"green"}).
		SetIsSeries(true).
		Render()

	// Prepare update values for event listener
	moreLineData := []*charts.UpdateValueSet{
		charts.NewUpdateValueSet([]float64{4, 0, 3, 1, 1, 2, 1, 2, 1, 0, 1, 1}),
		charts.NewUpdateValueSet([]float64{2, 3, 3, 2, 1, 4, 0, 1, 2, 7, 11, 4}),
		charts.NewUpdateValueSet([]float64{7, 7, 2, 4, 0, 1, 5, 3, 1, 2, 0, 1}),
		charts.NewUpdateValueSet([]float64{0, 2, 6, 2, 2, 1, 2, 3, 6, 3, 7, 10}),
		charts.NewUpdateValueSet([]float64{9, 10, 8, 10, 6, 5, 8, 8, 24, 15, 10, 13}),
		charts.NewUpdateValueSet([]float64{9, 13, 16, 9, 4, 5, 7, 10, 14, 22, 23, 24}),
		charts.NewUpdateValueSet([]float64{20, 22, 28, 19, 28, 19, 14, 19, 51, 37, 29, 38}),
		charts.NewUpdateValueSet([]float64{29, 20, 22, 16, 16, 19, 24, 26, 57, 31, 46, 2}),
		charts.NewUpdateValueSet([]float64{36, 24, 38, 27, 15, 22, 24, 38, 32, 57, 139, 26}),
		charts.NewUpdateValueSet([]float64{37, 36, 32, 33, 12, 34, 52, 45, 58, 57, 64, 35}),
		charts.NewUpdateValueSet([]float64{36, 46, 45, 32, 27, 31, 30, 36, 39, 49, 0, 0}),
	}

	barChart.AddDataSelectListener(func(event *charts.DataSelectEvent) {
		updateValues := &charts.UpdateValuesArgs{
			Values: []*charts.UpdateValueSet{moreLineData[event.Index]},
			// keep labels same as before
			Labels: lineChartData.Labels,
		}
		lineChart.UpdateValues(updateValues)
	})
}

Output 5:

Alt text

Heatmaps

package main

import (
	"math/rand"
	"strconv"

	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	data := make(map[string]int)
	currentTimestamp := 1477699200
	for i := 0; i < 375; i++ {
		data[strconv.Itoa(currentTimestamp)] = rand.Intn(10)
		currentTimestamp += 86400
	}
	charts.NewHeatmapChart("#chart", data).
		WithHeight(115).
		/* Halloween colors */
		// WithLegendColors([]string{"#ebedf0", "#fdf436", "#ffc700", "#ff9100", "#06001c"}).
		Render()
}
With discrete domains set to default

Alt text

With discrete domains set to 1 via chartArgs.SetDiscreteDomain(true)

Alt text

With different colors

Alt text

Realtime

package main

import (
	"math/rand"
	"strconv"
	"time"

	charts "github.com/cnguy/gopherjs-frappe-charts"
)

func main() {
	chartData := charts.NewChartData()
	chartData.Labels = []string{
		"1", "2", "3",
	}
	chartData.Datasets = []*charts.Dataset{
		charts.NewDataset(
			"Some Data",
			[]float64{25, 40, 30},
		),
		charts.NewDataset(
			"Another Set",
			[]float64{25, 50, -10},
		),
	}

	chart := charts.NewScatterChart("#chart", chartData).
		WithHeight(250).
		WithColors([]string{"red", "green"}).
		Render()
	temp := 4
	for i := 0; i < 100; i++ {
		go func(i interface{}) {
			val := rand.Intn(3) + 2*i.(int)
			println(i, "sleeping for", val)
			time.Sleep(time.Duration(val) * time.Second)
			newLabel := strconv.Itoa(temp)
			actionCond := rand.Intn(4)
			switch actionCond {
			case 0:
				chart.RemoveDataPoint(rand.Int())
			case 1:
				chart.PopDataPoint()
			case 2:
				chart.AppendDataPoint([]float64{float64(rand.Intn(1000)), float64(rand.Intn(1000))}, newLabel)
			case 3:
				chart.AddDataPoint([]float64{float64(rand.Intn(200)), float64(rand.Intn(200))}, newLabel, rand.Intn(200))
			}
			temp++
			println(temp)
		}(i)
	}

	println("is this async?")
}

Output 6:

Alt text

Disclaimer

I'm still a big Go noob, and so I don't know the proper way to manage releases and dependencies yet. I'll try to figure it out soon!

Contributions

Any contributions are welcome. :)

Changelog

here when available

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].