Compare commits

...

122 Commits
v0.5.0 ... main

Author SHA1 Message Date
Navid Yaghoobi
7b0dba28a6
Merge pull request #81 from navidys/dependabot/go_modules/github.com/gdamore/tcell/v2-2.8.1
Bump github.com/gdamore/tcell/v2 from 2.7.4 to 2.8.1
2025-01-13 21:46:37 +11:00
dependabot[bot]
f7a965b9b1
Bump github.com/gdamore/tcell/v2 from 2.7.4 to 2.8.1
Bumps [github.com/gdamore/tcell/v2](https://github.com/gdamore/tcell) from 2.7.4 to 2.8.1.
- [Release notes](https://github.com/gdamore/tcell/releases)
- [Changelog](https://github.com/gdamore/tcell/blob/main/CHANGESv2.md)
- [Commits](https://github.com/gdamore/tcell/compare/v2.7.4...v2.8.1)

---
updated-dependencies:
- dependency-name: github.com/gdamore/tcell/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-13 10:29:46 +00:00
Navid Yaghoobi
7a7632ee73
Merge pull request #79 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.22.2
Bump github.com/onsi/ginkgo/v2 from 2.22.1 to 2.22.2
2025-01-02 10:35:51 +11:00
dependabot[bot]
5c75618ec1
Bump github.com/onsi/ginkgo/v2 from 2.22.1 to 2.22.2
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.22.1 to 2.22.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.22.1...v2.22.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-31 10:16:57 +00:00
Navid Yaghoobi
657ca691c4
Merge pull request #77 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.22.1
Bump github.com/onsi/ginkgo/v2 from 2.21.0 to 2.22.1
2024-12-22 22:08:53 +11:00
dependabot[bot]
5c8253e8d9
Bump github.com/onsi/ginkgo/v2 from 2.21.0 to 2.22.1
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.21.0 to 2.22.1.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.21.0...v2.22.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-20 10:33:37 +00:00
Navid Yaghoobi
487c87b304
Merge pull request #71 from navidys/dependabot/go_modules/github.com/onsi/gomega-1.35.0
Bump github.com/onsi/gomega from 1.34.2 to 1.35.0
2024-10-30 21:20:27 +11:00
dependabot[bot]
d80a351c3c
Bump github.com/onsi/gomega from 1.34.2 to 1.35.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.34.2 to 1.35.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.34.2...v1.35.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-30 10:17:32 +00:00
Navid Yaghoobi
9dc06ec28d
Merge pull request #72 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.21.0
Bump github.com/onsi/ginkgo/v2 from 2.20.2 to 2.21.0
2024-10-30 21:16:20 +11:00
dependabot[bot]
04fd610c5b
Bump github.com/onsi/ginkgo/v2 from 2.20.2 to 2.21.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.20.2 to 2.21.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.20.2...v2.21.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-30 10:12:38 +00:00
Navid Yaghoobi
8a454d1c5e fix gh action failure
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-10-26 21:29:02 +11:00
Navid Yaghoobi
b6def86254
Merge pull request #70 from navidys/golangci_lint_update
golangci-lint update 1.61.0
2024-10-26 21:19:04 +11:00
Navid Yaghoobi
f97e54d849 golangci-lint update 1.61.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-10-26 21:16:51 +11:00
Navid Yaghoobi
3ddb90bd10
Merge pull request #69 from markusressel/feature/custom-x-axis-labeling
Feature: Allow custom X-Axis labeling
2024-10-13 22:29:42 +11:00
Navid Yaghoobi
091fcae5c5 running golangci-lint
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-10-13 22:28:43 +11:00
Markus Ressel
12e9f953a3
lint fixes
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 12:22:19 +02:00
Markus Ressel
fb7e4a8141
run gofmt -s -w
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 12:19:54 +02:00
Markus Ressel
362ed76a2b
lint fix
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 12:17:32 +02:00
Markus Ressel
a6b632c4f6
lint fix
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:48:58 +02:00
Markus Ressel
7e165355fc
cleanup demo
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:41:10 +02:00
Markus Ressel
00c6cca493
update docs, fix small error in demo
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:40:11 +02:00
Markus Ressel
543712cedb
integrate custom y range feature
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:24:54 +02:00
Markus Ressel
329fcead2e
refactor
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:14 +02:00
Markus Ressel
ca09c00451
refactor
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
2036aacbcb
simplify code
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
253e22ef1a
performance improvement
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
ac5e17721f
fix typo
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
d3a7c777e0
fix slice rotation in main demo
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
63d5ed1494
reset animation after multiple periods
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
0d4a60f69d
toggle animation on click
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
ed9012b1bf
refactor
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
5d0440879d
improve example
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
bb6ca0a79c
cleanup
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
bba8fe74ca
refactor
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
6119df590d
simplify
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
004135d96f
add screenshot
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
cb36b86f14
rework drawXAxisLabelToScreen to support drawing custom x-axis labels, add custom demo
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
d3cf38290d
do not write labels beyond bounds
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
d46f48fbe0
do not write labels beyond bounds
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Markus Ressel
d3dc728102
added SetXAxisLabelFunc method to provide custom X-Axis labels
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-13 10:23:06 +02:00
Navid Yaghoobi
40e5944bdc
Merge pull request #68 from markusressel/feature/allow-y-axis-range-override
allow manual override of Y-Axis MinValue and MaxValue
2024-10-13 12:48:55 +11:00
Navid Yaghoobi
3cfbbb446a running golangci-lint
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-10-13 12:44:01 +11:00
Markus Ressel
718914020b
change call order to better reflect real world usage
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 17:46:57 +02:00
Markus Ressel
a89f40eb4c
fix demo, add SetYRange to set both min and max at the same time
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 17:35:45 +02:00
Markus Ressel
d550a262e6
refactor and simplify calcBrailleLines logic and respect bounds
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 17:04:38 +02:00
Markus Ressel
e468a23392
fix property visibility
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 15:03:43 +02:00
Markus Ressel
83dbdb49e6
add screenshot
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 14:55:41 +02:00
Markus Ressel
7e3024f613
add parameters to control auto scaling behavior and prevent breaking change
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 14:54:53 +02:00
Markus Ressel
4632165f80
do not draw points that exceed the available height, fix scatter plots
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 14:45:42 +02:00
Markus Ressel
9d6693060a
revert changes to original plot example, add custom_range example
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 14:19:37 +02:00
Markus Ressel
eafbe24268
apply NaN fix to getMinFloat64From2dSlice
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 03:46:05 +02:00
Markus Ressel
e95a6c091d
allow manual override of Y-Axis MinValue and MaxValue
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-12 03:44:35 +02:00
Navid Yaghoobi
89b22f5d1d
Merge pull request #67 from markusressel/feature/do-not-draw-math-nan-values
ignore math.NaN() values when drawing plots
2024-10-12 12:03:06 +11:00
Navid Yaghoobi
5f3f2f99fc running golangci-lint
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-10-12 12:01:56 +11:00
Markus Ressel
6ec082d4f7
draw single valid data points in braille plot
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-11 22:42:46 +02:00
Markus Ressel
444dcd17a9
fix wrong braille line when data contains math.NaN
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-11 22:29:41 +02:00
Markus Ressel
170954e0d7
ignore math.NaN() values when drawing sparkline plots
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-11 01:19:47 +02:00
Markus Ressel
01b00ebe51
ignore math.NaN() values when determining max value
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-11 01:01:31 +02:00
Markus Ressel
3dd7ecf34b ignore math.NaN() values when drawing plots
Signed-off-by: Markus Ressel <mail@markusressel.de>
2024-10-11 00:32:08 +02:00
Navid Yaghoobi
ddfd01579e
Merge pull request #66 from navidys/plot_y_axis_type
add plot Y axis label type (float, integer)
2024-09-28 12:34:53 +10:00
Navid Yaghoobi
1dfc3feec1 add plot Y axis label type (float, integer)
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-09-28 12:33:20 +10:00
Navid Yaghoobi
ef7a0912d9
Merge pull request #65 from navidys/lint
running golangci-lint
2024-09-28 12:17:54 +10:00
Navid Yaghoobi
4aedeab3b0 running golangci-lint
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-09-28 12:16:31 +10:00
Navid Yaghoobi
1110c53694
Merge pull request #59 from Topvennie/bars
Delete bar items
2024-09-28 12:09:41 +10:00
Navid Yaghoobi
9cfa279d8d
Merge pull request #63 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.20.2
Bump github.com/onsi/ginkgo/v2 from 2.20.0 to 2.20.2
2024-09-27 20:12:10 +10:00
dependabot[bot]
5625bd86d5
Bump github.com/onsi/ginkgo/v2 from 2.20.0 to 2.20.2
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.20.0 to 2.20.2.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.20.0...v2.20.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-27 10:03:02 +00:00
Navid Yaghoobi
43529b16f2
Merge pull request #64 from navidys/dependabot/go_modules/github.com/onsi/gomega-1.34.2
Bump github.com/onsi/gomega from 1.34.1 to 1.34.2
2024-09-27 20:01:53 +10:00
dependabot[bot]
c35dc08b42
Bump github.com/onsi/gomega from 1.34.1 to 1.34.2
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.34.1 to 1.34.2.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.34.1...v1.34.2)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-27 09:37:50 +00:00
Navid Yaghoobi
984a311125 update go to 1.22.6
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-09-27 19:36:33 +10:00
Topvennie
335e9835f3
chore(bar): linting 2024-08-21 14:05:33 +02:00
Topvennie
a65ef0c1c5
chore(bar): allow multiple bars to be deleted at once 2024-08-14 23:19:41 +02:00
Topvennie
224c39bcd2
feat(bar): remove bars 2024-08-14 23:14:06 +02:00
Navid Yaghoobi
3a2e991738
Merge pull request #57 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.20.0
Bump github.com/onsi/ginkgo/v2 from 2.19.1 to 2.20.0
2024-08-12 08:07:02 +10:00
dependabot[bot]
1946bda711
Bump github.com/onsi/ginkgo/v2 from 2.19.1 to 2.20.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.19.1 to 2.20.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.19.1...v2.20.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-08 11:02:34 +00:00
Navid Yaghoobi
f1922269c0
Merge pull request #54 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.19.1
Bump github.com/onsi/ginkgo/v2 from 2.19.0 to 2.19.1
2024-07-30 21:30:56 +10:00
dependabot[bot]
aa9f7893de
Bump github.com/onsi/ginkgo/v2 from 2.19.0 to 2.19.1
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.19.0 to 2.19.1.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.19.0...v2.19.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-29 10:23:49 +00:00
Navid Yaghoobi
d5dda69eaa remove cirrus
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-07-28 20:31:41 +10:00
Navid Yaghoobi
770f88c853
Merge pull request #53 from navidys/go_version
go version 1.21.0
2024-07-28 20:28:57 +10:00
Navid Yaghoobi
8987c247bb go version 1.21.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-07-28 20:25:17 +10:00
Navid Yaghoobi
7ee00ea004 go version 1.21.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-07-28 20:22:24 +10:00
Navid Yaghoobi
903d9edb12
Merge pull request #52 from navidys/dialog_title_bugfix
bugfix for dialog title display
2024-06-21 18:14:02 +10:00
Navid Yaghoobi
09f153c313 bugfix for dialog title display
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-06-21 18:09:37 +10:00
Navid Yaghoobi
c5e08f5545
Merge pull request #51 from navidys/tview_vendor_update
tview module update
2024-06-21 18:03:59 +10:00
Navid Yaghoobi
383bde043c tview module update
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-06-21 18:01:38 +10:00
Navid Yaghoobi
b555c093da
Merge pull request #49 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.19.0
Bump github.com/onsi/ginkgo/v2 from 2.18.0 to 2.19.0
2024-06-08 18:54:19 +10:00
dependabot[bot]
e3a8e9ee6f
Bump github.com/onsi/ginkgo/v2 from 2.18.0 to 2.19.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.18.0 to 2.19.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.18.0...v2.19.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-08 08:34:36 +00:00
Navid Yaghoobi
24c34d8655 github action update
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-06-08 18:33:44 +10:00
Navid Yaghoobi
578159ac6f running codespell
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-06-08 18:29:19 +10:00
Navid Yaghoobi
458cbc6c7c
Merge pull request #48 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.18.0
Bump github.com/onsi/ginkgo/v2 from 2.17.3 to 2.18.0
2024-05-23 06:37:50 +10:00
dependabot[bot]
0cac81fb0c
---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-22 10:41:51 +00:00
Navid Yaghoobi
f98902679a
Merge pull request #40 from navidys/dependabot/go_modules/github.com/onsi/gomega-1.33.1
Bump github.com/onsi/gomega from 1.32.0 to 1.33.1
2024-05-11 19:15:55 +10:00
dependabot[bot]
f797d8124c
Bump github.com/onsi/gomega from 1.32.0 to 1.33.1
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.32.0 to 1.33.1.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.32.0...v1.33.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-11 09:14:45 +00:00
Navid Yaghoobi
e4b840b0d7
Merge pull request #45 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.17.3
Bump github.com/onsi/ginkgo/v2 from 2.17.1 to 2.17.3
2024-05-11 19:14:03 +10:00
dependabot[bot]
87b5f8820b
Bump github.com/onsi/ginkgo/v2 from 2.17.1 to 2.17.3
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.17.1 to 2.17.3.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.17.1...v2.17.3)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-11 09:11:10 +00:00
Navid Yaghoobi
78b9f38c5a
Merge pull request #47 from navidys/ghaction
fix codecoverage upload action
2024-05-11 19:10:02 +10:00
Navid Yaghoobi
29c7875502 fix codecoverage upload action
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-05-11 19:08:08 +10:00
Navid Yaghoobi
03accf7634
Merge pull request #44 from anderspitman/expose-plot-rect
Expose GetPlotRect in public interface
2024-05-08 06:19:13 +10:00
Anders Pitman
e9eb5cdbdc
Expose GetPlotRect 2024-05-07 12:23:28 -06:00
Navid Yaghoobi
f4a44f8b74
Merge pull request #37 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.17.1
Bump github.com/onsi/ginkgo/v2 from 2.17.0 to 2.17.1
2024-03-26 09:32:11 +11:00
dependabot[bot]
bb2e442902
Bump github.com/onsi/ginkgo/v2 from 2.17.0 to 2.17.1
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.17.0 to 2.17.1.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.17.0...v2.17.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-25 10:49:20 +00:00
Navid Yaghoobi
c1149f4730
Merge pull request #35 from navidys/dependabot/go_modules/github.com/onsi/gomega-1.32.0
Bump github.com/onsi/gomega from 1.31.1 to 1.32.0
2024-03-20 15:11:24 +11:00
dependabot[bot]
9f6c73d584
Bump github.com/onsi/gomega from 1.31.1 to 1.32.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.31.1 to 1.32.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.31.1...v1.32.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-20 04:10:00 +00:00
Navid Yaghoobi
9a8419ba8b
Merge pull request #36 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.17.0
Bump github.com/onsi/ginkgo/v2 from 2.16.0 to 2.17.0
2024-03-20 15:09:23 +11:00
dependabot[bot]
852d3a1c2b
Bump github.com/onsi/ginkgo/v2 from 2.16.0 to 2.17.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.16.0 to 2.17.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.16.0...v2.17.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-19 11:02:08 +00:00
Navid Yaghoobi
8c8addff08
Merge pull request #33 from navidys/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.16.0
Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.16.0
2024-03-05 22:06:31 +11:00
dependabot[bot]
2ef68bb07e
Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.16.0
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.15.0 to 2.16.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.15.0...v2.16.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 11:02:33 +00:00
Navid Yaghoobi
f0f35dace5 golangci-lint update 1.56.2
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-03-05 22:01:34 +11:00
Navid Yaghoobi
f50a0fb83b
Merge pull request #34 from navidys/golangci_lint
golangci-lint update 1.56.2
2024-03-05 21:58:05 +11:00
Navid Yaghoobi
36e3d86da4 golangci-lint update 1.56.2
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-03-05 21:56:13 +11:00
Navid Yaghoobi
89ca96e1d6
Merge pull request #32 from navidys/dependabot/go_modules/github.com/gdamore/tcell/v2-2.7.4
Bump github.com/gdamore/tcell/v2 from 2.7.1 to 2.7.4
2024-03-04 22:09:16 +11:00
dependabot[bot]
113ea8b938
Bump github.com/gdamore/tcell/v2 from 2.7.1 to 2.7.4
Bumps [github.com/gdamore/tcell/v2](https://github.com/gdamore/tcell) from 2.7.1 to 2.7.4.
- [Release notes](https://github.com/gdamore/tcell/releases)
- [Changelog](https://github.com/gdamore/tcell/blob/main/CHANGESv2.md)
- [Commits](https://github.com/gdamore/tcell/compare/v2.7.1...v2.7.4)

---
updated-dependencies:
- dependency-name: github.com/gdamore/tcell/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 10:50:19 +00:00
Navid Yaghoobi
d640b32096
Merge pull request #31 from navidys/dependabot/go_modules/github.com/gdamore/tcell/v2-2.7.1
Bump github.com/gdamore/tcell/v2 from 2.7.0 to 2.7.1
2024-02-19 21:37:11 +11:00
dependabot[bot]
1c80e02217
Bump github.com/gdamore/tcell/v2 from 2.7.0 to 2.7.1
Bumps [github.com/gdamore/tcell/v2](https://github.com/gdamore/tcell) from 2.7.0 to 2.7.1.
- [Release notes](https://github.com/gdamore/tcell/releases)
- [Changelog](https://github.com/gdamore/tcell/blob/main/CHANGESv2.md)
- [Commits](https://github.com/gdamore/tcell/compare/v2.7.0...v2.7.1)

---
updated-dependencies:
- dependency-name: github.com/gdamore/tcell/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 10:10:01 +00:00
Navid Yaghoobi
55176a3e08
Merge pull request #30 from navidys/go_version
go version update to 1.20
2024-01-27 20:51:04 +11:00
Navid Yaghoobi
fe7c2ef80c go version update to 1.20
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-01-27 20:48:23 +11:00
Navid Yaghoobi
172e1e9661
Merge pull request #29 from navidys/dependabot/go_modules/github.com/onsi/gomega-1.31.1
Bump github.com/onsi/gomega from 1.31.0 to 1.31.1
2024-01-22 21:55:39 +11:00
dependabot[bot]
6ef8527c29
Bump github.com/onsi/gomega from 1.31.0 to 1.31.1
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.31.0 to 1.31.1.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.31.0...v1.31.1)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-22 10:11:11 +00:00
Navid Yaghoobi
20d0b5b64b
Merge pull request #28 from navidys/dependabot/go_modules/github.com/onsi/gomega-1.31.0
Bump github.com/onsi/gomega from 1.30.0 to 1.31.0
2024-01-19 09:09:28 +11:00
dependabot[bot]
0d11f83a24
Bump github.com/onsi/gomega from 1.30.0 to 1.31.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.30.0 to 1.31.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.30.0...v1.31.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-18 22:04:01 +00:00
dependabot[bot]
f492db7976
Bump github.com/onsi/ginkgo/v2 from 2.14.0 to 2.15.0 (#27)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.14.0 to 2.15.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.14.0...v2.15.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-19 09:02:54 +11:00
dependabot[bot]
bbacde1cec
Bump github.com/onsi/ginkgo/v2 from 2.13.2 to 2.14.0 (#26)
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.13.2 to 2.14.0.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.13.2...v2.14.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-12 21:46:31 +11:00
Hidayat
d8a9aeb20e
feat option to draw y or x axis label independently (#25)
Signed-off-by: Hidayat Hamir <hidayat.03@erajaya.com>
2023-12-29 18:51:02 +11:00
25 changed files with 787 additions and 255 deletions

View File

@ -1,50 +0,0 @@
---
env:
DEST_BRANCH: "main"
CIRRUS_SHELL: "/bin/bash"
timeout_in: 30m
# Run on PRs and main branch post submit only. Don't run tests when tagging.
only_if: $CIRRUS_TAG == '' && ($CIRRUS_PR != '' || $CIRRUS_BRANCH == 'main')
clone_script: &full_clone |
if [ -z "$CIRRUS_PR" ]; then
git clone --recursive --branch=$CIRRUS_BRANCH https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR
git reset --hard $CIRRUS_CHANGE_IN_REPO
else
git clone --recursive https://x-access-token:${CIRRUS_REPO_CLONE_TOKEN}@github.com/${CIRRUS_REPO_FULL_NAME}.git $CIRRUS_WORKING_DIR
git fetch origin pull/$CIRRUS_PR/head:pull/$CIRRUS_PR
git reset --hard $CIRRUS_CHANGE_IN_REPO
fi
precommit_test_task:
name: "Precommit"
alias: precommit
clone_script: *full_clone
container:
image: python:3.10
script: |
python3 -m pip install pre-commit
pre-commit run -a
gofmt_task:
name: "Gofmt"
alias: gofmt
clone_script: *full_clone
container:
image: golang:1.18
script: |
SRC=$(find . -type f -name '*.go' -not -path "./vendor/*")
gofmt -w ${SRC}
golangci_lint_task:
name: "Golangci-lint"
alias: lint
clone_script: *full_clone
container:
image: golang:1.18
script: |
make .install.golangci-lint
make lint

View File

@ -10,13 +10,11 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
# cannot use 1.21.X latest version since golangci-lint has an issue.
go-version: '1.21.4'
go-version: '>=1.22'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.51
- run: |
make .install.golangci-lint
make lint
unit_test:
name: Unit test
@ -25,7 +23,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '>=1.19.0'
go-version: '>=1.22'
id: go
- name: Check out code into the Go module directory
@ -43,9 +41,9 @@ jobs:
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
file: .coverage/coverprofile
name: codecov-umbrella
fail_ci_if_error: true
slug: navidys/tvxwidgets
token: ${{ secrets.CODECOV_TOKEN }}

View File

@ -40,8 +40,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
# cannot use 1.21.X latest version since golangci-lint has an issue.
go-version: '1.21.4'
go-version: '>=1.22'
cache: false
- run: |
make .install.golangci-lint
@ -55,7 +54,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '>=1.19.0'
go-version: '>=1.22'
id: go
- name: Check out code into the Go module directory
@ -78,7 +77,7 @@ jobs:
with:
file: .coverage/coverprofile
name: codecov-umbrella
fail_ci_if_error: true
fail_ci_if_error: false
goreportcard:
name: update reportcard

View File

@ -1,30 +1,28 @@
run:
timeout: 10m
deadline: 5m
skip-dirs:
- demos
skip-files:
- ".*_test.go"
linters:
enable-all: true
disable:
- varnamelen
- exhaustruct
- depguard
# deprecated
- gomnd
- execinquery
- exportloopref
- rowserrcheck
- wastedassign
- structcheck
- deadcode
- varcheck
- nosnakecase
- ifshort
- golint
- maligned
- interfacer
- scopelint
- exhaustivestruct
linters-settings:
errcheck:
check-blank: false
ignore: fmt:.*
exclude-functions:
- fmt:.*
nolintlint:
require-specific: true
issues:
exclude-dirs:
- demos
exclude-files:
- ".*_test.go"

View File

@ -5,7 +5,7 @@
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
identity and expression, level of experience, education, socioeconomic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

View File

@ -32,7 +32,7 @@ install.tools: .install.pre-commit .install.codespell .install.golangci-lint .in
.PHONY: .install.golangci-lint
.install.golangci-lint:
VERSION=1.51.1 ./hack/install_golangci.sh
VERSION=1.61.0 ./hack/install_golangci.sh
#=================================================
# Testing (units, functionality, ...) targets

View File

@ -1,7 +1,7 @@
package tvxwidgets
import (
"fmt"
"strconv"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
@ -67,8 +67,8 @@ func (c *BarChart) Draw(screen tcell.Screen) { //nolint:funlen,cyclop
x, y, width, height := c.Box.GetInnerRect()
maxValY := y + 1
xAxisStartY := y + height - 2 //nolint:gomnd
barStartY := y + height - 3 //nolint:gomnd
xAxisStartY := y + height - 2 //nolint:mnd
barStartY := y + height - 3 //nolint:mnd
borderPadding := 0
if c.hasBorder {
@ -76,7 +76,7 @@ func (c *BarChart) Draw(screen tcell.Screen) { //nolint:funlen,cyclop
}
// set max value if not set
c.initMaxValue()
maxValueSr := fmt.Sprintf("%d", c.maxVal)
maxValueSr := strconv.Itoa(c.maxVal)
maxValLenght := len(maxValueSr) + 1
if maxValLenght < barChartYAxisLabelWidth {
@ -108,7 +108,7 @@ func (c *BarChart) Draw(screen tcell.Screen) { //nolint:funlen,cyclop
tview.PrintJoinedSemigraphics(screen, x+maxValLenght-1, xAxisStartY, '0', axesLabelStyle)
mxValRune := []rune(maxValueSr)
for i := 0; i < len(mxValRune); i++ {
for i := range mxValRune {
tview.PrintJoinedSemigraphics(screen, x+borderPadding+i, maxValY, mxValRune[i], axesLabelStyle)
}
@ -123,23 +123,23 @@ func (c *BarChart) Draw(screen tcell.Screen) { //nolint:funlen,cyclop
}
// set labels
r := []rune(item.label)
for j := 0; j < len(r); j++ {
for j := range r {
tview.PrintJoinedSemigraphics(screen, startX+j, labelY, r[j], axesLabelStyle)
}
// bar style
bStyle := tcell.StyleDefault.Background(c.GetBackgroundColor()).Foreground(item.color)
barHeight := c.getHeight(valueMaxHeight, item.value)
for k := 0; k < barHeight; k++ {
for l := 0; l < c.barWidth; l++ {
for k := range barHeight {
for l := range c.barWidth {
tview.PrintJoinedSemigraphics(screen, startX+l, barStartY-k, fullBlockRune, bStyle)
}
}
// bar value
vSt := fmt.Sprintf("%d", item.value)
vSt := strconv.Itoa(item.value)
vRune := []rune(vSt)
for i := 0; i < len(vRune); i++ {
for i := range vRune {
tview.PrintJoinedSemigraphics(screen, startX+i, barStartY-barHeight, vRune[i], bStyle)
}
@ -170,8 +170,8 @@ func (c *BarChart) SetRect(x, y, width, height int) {
}
// SetMaxValue sets maximum value of bars.
func (c *BarChart) SetMaxValue(max int) {
c.maxVal = max
func (c *BarChart) SetMaxValue(maxValue int) {
c.maxVal = maxValue
}
// SetAxesColor sets axes x and y lines color.
@ -193,9 +193,22 @@ func (c *BarChart) AddBar(label string, value int, color tcell.Color) {
})
}
// RemoveBar removes a bar item from the bar chart.
func (c *BarChart) RemoveBar(label string) {
bars := c.bars[:0]
for _, barItem := range c.bars {
if barItem.label != label {
bars = append(bars, barItem)
}
}
c.bars = bars
}
// SetBarValue sets bar values.
func (c *BarChart) SetBarValue(name string, value int) {
for i := 0; i < len(c.bars); i++ {
for i := range c.bars {
if c.bars[i].label == name {
c.bars[i].value = value
}

View File

@ -204,20 +204,9 @@ func main() {
}
moveSinData := func(data [][]float64) [][]float64 {
n := 220
newData := make([][]float64, 2)
newData[0] = make([]float64, n)
newData[1] = make([]float64, n)
for i := 0; i < n; i++ {
if i+1 < len(data[0]) {
newData[0][i] = data[0][i+1]
}
if i+1 < len(data[1]) {
newData[1][i] = data[1][i+1]
}
}
newData[0] = rotate(data[0], -1)
newData[1] = rotate(data[1], -1)
return newData
}
@ -330,3 +319,23 @@ func newBarChart() *tvxwidgets.BarChart {
return barGraph
}
// Source: https://stackoverflow.com/questions/50833673/rotate-array-in-go/79079760#79079760
// rotate rotates the given slice by k positions to the left or right.
func rotate[T any](slice []T, k int) []T {
if len(slice) == 0 {
return slice
}
var r int
if k > 0 {
r = len(slice) - k%len(slice)
} else {
kAbs := int(math.Abs(float64(k)))
r = kAbs % len(slice)
}
slice = append(slice[r:], slice[:r]...)
return slice
}

View File

@ -35,6 +35,7 @@ func main() {
})
bmLineChart.SetMarker(tvxwidgets.PlotMarkerBraille)
bmLineChart.SetData(sinData)
bmLineChart.SetDrawXAxisLabel(false)
dmLineChart := tvxwidgets.NewPlot()
dmLineChart.SetBorder(true)
@ -72,6 +73,7 @@ func main() {
dmScatterPlot.SetPlotType(tvxwidgets.PlotTypeScatter)
dmScatterPlot.SetMarker(tvxwidgets.PlotMarkerDot)
dmScatterPlot.SetData(scatterPlotData)
dmScatterPlot.SetDrawYAxisLabel(false)
bmScatterPlot := tvxwidgets.NewPlot()
bmScatterPlot.SetBorder(true)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1 @@
![Screenshot](screenshot.png)

View File

@ -0,0 +1,119 @@
package main
import (
"github.com/gdamore/tcell/v2"
"github.com/navidys/tvxwidgets"
"github.com/rivo/tview"
"math"
)
func main() {
app := tview.NewApplication()
sinData := func() [][]float64 {
n := 220
data := make([][]float64, 2)
data[0] = make([]float64, n)
data[1] = make([]float64, n)
for i := 0; i < n; i++ {
data[0][i] = math.Sin(float64(i+1) / 5)
// Avoid taking Cos(0) because it creates a high point of 2 that
// will never be hit again and makes the graph look a little funny
data[1][i] = math.Cos(float64(i+1) / 5)
}
return data
}()
bmLineChart := tvxwidgets.NewPlot()
bmLineChart.SetBorder(true)
bmLineChart.SetTitle("line chart (braille mode)")
bmLineChart.SetLineColor([]tcell.Color{
tcell.ColorSteelBlue,
tcell.ColorGreen,
})
bmLineChart.SetMarker(tvxwidgets.PlotMarkerBraille)
bmLineChart.SetYAxisAutoScaleMin(false)
bmLineChart.SetYAxisAutoScaleMax(false)
bmLineChart.SetYRange(-1.5, 1.5)
bmLineChart.SetData(sinData)
bmLineChart.SetDrawXAxisLabel(false)
dmLineChart := tvxwidgets.NewPlot()
dmLineChart.SetBorder(true)
dmLineChart.SetTitle("line chart (dot mode)")
dmLineChart.SetLineColor([]tcell.Color{
tcell.ColorDarkOrange,
})
dmLineChart.SetAxesLabelColor(tcell.ColorGold)
dmLineChart.SetAxesColor(tcell.ColorGold)
dmLineChart.SetMarker(tvxwidgets.PlotMarkerDot)
dmLineChart.SetDotMarkerRune('\u25c9')
sampleData1 := []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
sampleData2 := []float64{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
dotModeChartData := [][]float64{sampleData1}
dotModeChartData[0] = append(dotModeChartData[0], sampleData2...)
dotModeChartData[0] = append(dotModeChartData[0], sampleData1[:5]...)
dotModeChartData[0] = append(dotModeChartData[0], sampleData2[5:]...)
dotModeChartData[0] = append(dotModeChartData[0], sampleData1[:7]...)
dotModeChartData[0] = append(dotModeChartData[0], sampleData2[3:]...)
dmLineChart.SetYAxisAutoScaleMin(false)
dmLineChart.SetYAxisAutoScaleMax(false)
dmLineChart.SetYRange(0, 3)
dmLineChart.SetData(dotModeChartData)
scatterPlotData := make([][]float64, 2)
scatterPlotData[0] = []float64{1, 2, 3, 4, 5}
scatterPlotData[1] = sinData[1][4:]
dmScatterPlot := tvxwidgets.NewPlot()
dmScatterPlot.SetBorder(true)
dmScatterPlot.SetTitle("scatter plot (dot mode)")
dmScatterPlot.SetLineColor([]tcell.Color{
tcell.ColorMediumSlateBlue,
tcell.ColorLightSkyBlue,
})
dmScatterPlot.SetPlotType(tvxwidgets.PlotTypeScatter)
dmScatterPlot.SetMarker(tvxwidgets.PlotMarkerDot)
dmScatterPlot.SetYAxisAutoScaleMin(false)
dmScatterPlot.SetYAxisAutoScaleMax(false)
dmScatterPlot.SetYRange(-1, 3)
dmScatterPlot.SetData(scatterPlotData)
dmScatterPlot.SetDrawYAxisLabel(false)
bmScatterPlot := tvxwidgets.NewPlot()
bmScatterPlot.SetBorder(true)
bmScatterPlot.SetTitle("scatter plot (braille mode)")
bmScatterPlot.SetLineColor([]tcell.Color{
tcell.ColorGold,
tcell.ColorLightSkyBlue,
})
bmScatterPlot.SetPlotType(tvxwidgets.PlotTypeScatter)
bmScatterPlot.SetMarker(tvxwidgets.PlotMarkerBraille)
bmScatterPlot.SetYAxisAutoScaleMin(false)
bmScatterPlot.SetYAxisAutoScaleMax(false)
bmScatterPlot.SetYRange(-1, 5)
bmScatterPlot.SetData(scatterPlotData)
firstRow := tview.NewFlex().SetDirection(tview.FlexColumn)
firstRow.AddItem(dmLineChart, 0, 1, false)
firstRow.AddItem(bmLineChart, 0, 1, false)
firstRow.SetRect(0, 0, 100, 15)
secondRow := tview.NewFlex().SetDirection(tview.FlexColumn)
secondRow.AddItem(dmScatterPlot, 0, 1, false)
secondRow.AddItem(bmScatterPlot, 0, 1, false)
secondRow.SetRect(0, 0, 100, 15)
layout := tview.NewFlex().SetDirection(tview.FlexRow)
layout.AddItem(firstRow, 0, 1, false)
layout.AddItem(secondRow, 0, 1, false)
layout.SetRect(0, 0, 100, 30)
if err := app.SetRoot(layout, false).EnableMouse(true).Run(); err != nil {
panic(err)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1 @@
![Screenshot](screenshot.png)

View File

@ -0,0 +1,133 @@
package main
import (
"fmt"
"github.com/gdamore/tcell/v2"
"github.com/navidys/tvxwidgets"
"github.com/rivo/tview"
"math"
"time"
)
func main() {
app := tview.NewApplication()
// >>> Data Function <<<
// With these values, the curve will start with a value of 0 and reach a
// high point of 2 at x = 3.14 (Pi) and then return to 0 at x = 6.28 (2*Pi).
// Play around with these values to get a feel for how they affect the curve
// and how you might adapt this code to plot other functions.
period := 2 * math.Pi
horizontalStretchFactor := 1.0
verticalStretchFactor := 1.0
xOffset := 0.0
yOffset := 0.0
// >>> Graph View/Camera Controls <<<
// These values influence which part of the curve is shown in
// what "zoom level".
xAxisZoomFactor := 3.0
yAxisZoomFactor := 1.0
xAxisShift := 0.0
yAxisShift := 0.0
// xFunc1 defines the x values that should be used for each vertical "slot" in the graph.
xFunc1 := func(i int) float64 {
return (float64(i) / xAxisZoomFactor) + xAxisShift
}
// yFunc1 defines the y values that result from a given input value x (this is the actual function).
yFunc1 := func(x float64) float64 {
return (math.Sin((x+xOffset)/horizontalStretchFactor) + yOffset) * verticalStretchFactor
}
// xLabelFunc1 defines a label for each vertical "slot". Which labels are shown is determined automatically
// based on the available space.
xLabelFunc1 := func(i int) string {
xVal := xFunc1(i)
labelVal := xVal
label := fmt.Sprintf("%.1f", labelVal)
return label
}
// computeDataArray computes the y values for n vertical slots based on the definitions above.
computeDataArray := func() [][]float64 {
n := 150
data := make([][]float64, 1)
data[0] = make([]float64, n)
for i := 0; i < n; i++ {
xVal := xFunc1(i)
yVal := yFunc1(xVal)
data[0][i] = yVal
}
return data
}
data := computeDataArray()
bmLineChart := tvxwidgets.NewPlot()
bmLineChart.SetBorder(true)
bmLineChart.SetTitle("line chart (braille mode)")
bmLineChart.SetLineColor([]tcell.Color{
tcell.ColorSteelBlue,
tcell.ColorGreen,
})
bmLineChart.SetMarker(tvxwidgets.PlotMarkerBraille)
bmLineChart.SetXAxisLabelFunc(xLabelFunc1)
bmLineChart.SetYAxisAutoScaleMin(false)
bmLineChart.SetYAxisAutoScaleMax(false)
bmLineChart.SetYRange(
(-1+yOffset+yAxisShift)/yAxisZoomFactor,
(1+yOffset+yAxisShift)/yAxisZoomFactor,
)
bmLineChart.SetData(data)
firstRow := tview.NewFlex().SetDirection(tview.FlexColumn)
firstRow.AddItem(bmLineChart, 0, 1, false)
firstRow.SetRect(0, 0, 100, 15)
layout := tview.NewFlex().SetDirection(tview.FlexRow)
layout.AddItem(firstRow, 0, 1, false)
layout.SetRect(0, 0, 100, 30)
animate := true
rotateDataContinuously := func() {
tick := time.NewTicker(100 * time.Millisecond)
go func() {
initialxAxisShift := xAxisShift
for {
select {
case <-tick.C:
if !animate {
continue
}
xAxisShift = xAxisShift + 0.1
if xAxisShift >= initialxAxisShift+period*4 {
xAxisShift = initialxAxisShift
}
data = computeDataArray()
bmLineChart.SetData(data)
app.Draw()
}
}
}()
}
go rotateDataContinuously()
if err := app.SetRoot(layout, false).EnableMouse(true).SetMouseCapture(func(event *tcell.EventMouse, action tview.MouseAction) (*tcell.EventMouse, tview.MouseAction) {
if action == tview.MouseLeftClick {
animate = !animate
}
return event, action
}).Run(); err != nil {
panic(err)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -76,6 +76,11 @@ func (d *MessageDialog) SetType(dtype int) {
}
}
// SetTitle sets dialog title.
func (d *MessageDialog) SetTitle(title string) {
d.layout.SetTitle(title)
}
// SetBackgroundColor sets dialog background color.
func (d *MessageDialog) SetBackgroundColor(color tcell.Color) {
d.bgColor = color
@ -133,6 +138,7 @@ func (d *MessageDialog) InputHandler() func(event *tcell.EventKey, setFocus func
return
}
}
if formHandler := d.form.InputHandler(); formHandler != nil {
formHandler(event, setFocus)
@ -148,6 +154,7 @@ func (d *MessageDialog) MouseHandler() func(action tview.MouseAction, event *tce
consumed, capture = d.form.MouseHandler()(action, event, setFocus)
if !consumed && action == tview.MouseLeftClick && d.InRect(event.Position()) {
setFocus(d)
consumed = true
}

View File

@ -34,13 +34,13 @@ func (g *ActivityModeGauge) Draw(screen tcell.Screen) {
x, y, width, height := g.Box.GetInnerRect()
tickStr := g.tickStr(width)
for i := 0; i < height; i++ {
for i := range height {
tview.Print(screen, tickStr, x, y+i, width, tview.AlignLeft, g.pgBgColor)
}
}
// Focus is called when this primitive receives focus.
func (g *ActivityModeGauge) Focus(delegate func(p tview.Primitive)) {
func (g *ActivityModeGauge) Focus(delegate func(p tview.Primitive)) { //nolint:revive
}
// HasFocus returns whether or not this primitive has focus.
@ -73,27 +73,27 @@ func (g *ActivityModeGauge) Reset() {
g.counter = 0
}
func (g *ActivityModeGauge) tickStr(max int) string {
func (g *ActivityModeGauge) tickStr(maxCount int) string {
var (
prgHeadStr string
prgEndStr string
prgStr string
)
if g.counter >= max-4 {
if g.counter >= maxCount-4 {
g.counter = 0
}
hWidth := 0
for i := 0; i < g.counter; i++ {
for range g.counter {
prgHeadStr += fmt.Sprintf("[%s::]%s", getColorName(tview.Styles.PrimitiveBackgroundColor), prgCell)
hWidth++
}
prgStr = prgCell + prgCell + prgCell + prgCell
for i := 0; i < max+hWidth+4; i++ {
for range maxCount + hWidth + 4 {
prgEndStr += fmt.Sprintf("[%s::]%s", getColorName(tview.Styles.PrimitiveBackgroundColor), prgCell)
}

View File

@ -47,8 +47,8 @@ func (g *PercentageModeGauge) Draw(screen tcell.Screen) {
prgBlock := g.progressBlock(width)
style := tcell.StyleDefault.Background(g.pgBgColor).Foreground(tview.Styles.PrimaryTextColor)
for i := 0; i < height; i++ {
for j := 0; j < prgBlock; j++ {
for i := range height {
for j := range prgBlock {
screen.SetContent(x+j, y+i, ' ', nil, style)
}
}
@ -56,21 +56,22 @@ func (g *PercentageModeGauge) Draw(screen tcell.Screen) {
// print percentage in middle of box
pcRune := []rune(pcString)
for j := 0; j < len(pcRune); j++ {
for j := range pcRune {
style = tcell.StyleDefault.Background(tview.Styles.PrimitiveBackgroundColor).Foreground(tview.Styles.PrimaryTextColor)
if x+prgBlock >= tX+j {
style = tcell.StyleDefault.Background(g.pgBgColor).Foreground(tview.Styles.PrimaryTextColor)
}
for i := 0; i < height; i++ {
for i := range height {
screen.SetContent(tX+j, y+i, ' ', nil, style)
}
screen.SetContent(tX+j, tY, pcRune[j], nil, style)
}
}
// Focus is called when this primitive receives focus.
func (g *PercentageModeGauge) Focus(delegate func(p tview.Primitive)) {
func (g *PercentageModeGauge) Focus(delegate func(p tview.Primitive)) { //nolint:revive
}
// HasFocus returns whether or not this primitive has focus.
@ -122,13 +123,13 @@ func (g *PercentageModeGauge) Reset() {
g.value = 0
}
func (g *PercentageModeGauge) progressBlock(max int) int {
func (g *PercentageModeGauge) progressBlock(maxValue int) int {
if g.maxValue == 0 {
return g.maxValue
}
pc := g.value * gaugeMaxPc / g.maxValue
value := pc * max / gaugeMaxPc
value := pc * maxValue / gaugeMaxPc
return value
}

View File

@ -59,7 +59,7 @@ func (g *UtilModeGauge) SetLabelColor(color tcell.Color) {
}
// Focus is called when this primitive receives focus.
func (g *UtilModeGauge) Focus(delegate func(p tview.Primitive)) {
func (g *UtilModeGauge) Focus(delegate func(p tview.Primitive)) { //nolint:revive
}
// HasFocus returns whether or not this primitive has focus.
@ -97,8 +97,8 @@ func (g *UtilModeGauge) Draw(screen tcell.Screen) {
labelWidth := len(g.label)
barWidth := width - labelPCWidth - labelWidth
for i := 0; i < barWidth; i++ {
for j := 0; j < height; j++ {
for i := range barWidth {
for j := range height {
value := float64(i * 100 / barWidth)
color := g.getBarColor(value)

32
go.mod
View File

@ -1,27 +1,27 @@
module github.com/navidys/tvxwidgets
go 1.18
go 1.22.6
require (
github.com/gdamore/tcell/v2 v2.7.0
github.com/onsi/ginkgo/v2 v2.13.2
github.com/onsi/gomega v1.30.0
github.com/rivo/tview v0.0.0-20231206124440-5f078138442e
github.com/gdamore/tcell/v2 v2.8.1
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/gomega v1.36.2
github.com/rivo/tview v0.0.0-20240616192244-23476fa0bab2
)
require (
github.com/gdamore/encoding v1.0.0 // indirect
github.com/go-logr/logr v1.3.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gdamore/encoding v1.0.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.14.0 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/tools v0.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

103
go.sum
View File

@ -1,86 +1,107 @@
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.7.0 h1:I5LiGTQuwrysAt1KS9wg1yFfOI3arI3ucFrxtd/xqaA=
github.com/gdamore/tcell/v2 v2.7.0/go.mod h1:hl/KtAANGBecfIPxk+FzKvThTqI84oplgbPEmVX60b8=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU=
github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/tview v0.0.0-20231206124440-5f078138442e h1:mPy47VW9tkqImnSPgcjnEHJuG3XHDBtXj2hDb1qBrRs=
github.com/rivo/tview v0.0.0-20231206124440-5f078138442e/go.mod h1:c0SPlNPXkM+/Zgjn/0vD3W0Ds1yxstN7lpquqLDpWCg=
github.com/rivo/tview v0.0.0-20240616192244-23476fa0bab2 h1:LXMiBMxtuXw8e2paN61dI2LMp8JZYyH4UXDwssRI3ys=
github.com/rivo/tview v0.0.0-20240616192244-23476fa0bab2/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

355
plot.go
View File

@ -3,6 +3,9 @@ package tvxwidgets
import (
"fmt"
"image"
"math"
"strconv"
"strings"
"sync"
"github.com/gdamore/tcell/v2"
@ -18,6 +21,14 @@ const (
PlotMarkerDot
)
// PlotYAxisLabelDataType represents plot y axis type (integer or float).
type PlotYAxisLabelDataType uint
const (
PlotYAxisLabelDataInt PlotYAxisLabelDataType = iota
PlotYAxisLabelDataFloat
)
// PlotType represents plot type (line chart or scatter).
type PlotType uint
@ -31,6 +42,8 @@ const (
plotXAxisLabelsHeight = 1
plotXAxisLabelsGap = 2
plotYAxisLabelsGap = 1
gapRune = " "
)
type brailleCell struct {
@ -41,29 +54,44 @@ type brailleCell struct {
// Plot represents a plot primitive used for different charts.
type Plot struct {
*tview.Box
data [][]float64
maxVal float64
marker Marker
ptype PlotType
dotMarkerRune rune
lineColors []tcell.Color
axesColor tcell.Color
axesLabelColor tcell.Color
drawAxes bool
brailleCellMap map[image.Point]brailleCell
mu sync.Mutex
data [][]float64
// maxVal is the maximum y-axis (vertical) value found in any of the lines in the data set.
maxVal float64
// minVal is the minimum y-axis (vertical) value found in any of the lines in the data set.
minVal float64
marker Marker
ptype PlotType
dotMarkerRune rune
lineColors []tcell.Color
axesColor tcell.Color
axesLabelColor tcell.Color
drawAxes bool
drawXAxisLabel bool
xAxisLabelFunc func(int) string
drawYAxisLabel bool
yAxisLabelDataType PlotYAxisLabelDataType
yAxisAutoScaleMin bool
yAxisAutoScaleMax bool
brailleCellMap map[image.Point]brailleCell
mu sync.Mutex
}
// NewPlot returns a plot widget.
func NewPlot() *Plot {
return &Plot{
Box: tview.NewBox(),
marker: PlotMarkerDot,
ptype: PlotTypeLineChart,
dotMarkerRune: dotRune,
axesColor: tcell.ColorDimGray,
axesLabelColor: tcell.ColorDimGray,
drawAxes: true,
Box: tview.NewBox(),
marker: PlotMarkerDot,
ptype: PlotTypeLineChart,
dotMarkerRune: dotRune,
axesColor: tcell.ColorDimGray,
axesLabelColor: tcell.ColorDimGray,
drawAxes: true,
drawXAxisLabel: true,
xAxisLabelFunc: strconv.Itoa,
drawYAxisLabel: true,
yAxisLabelDataType: PlotYAxisLabelDataFloat,
yAxisAutoScaleMin: false,
yAxisAutoScaleMax: true,
lineColors: []tcell.Color{
tcell.ColorSteelBlue,
},
@ -94,6 +122,21 @@ func (plot *Plot) SetLineColor(color []tcell.Color) {
plot.lineColors = color
}
// SetYAxisLabelDataType sets Y axis label data type (integer or float).
func (plot *Plot) SetYAxisLabelDataType(dataType PlotYAxisLabelDataType) {
plot.yAxisLabelDataType = dataType
}
// SetYAxisAutoScaleMin enables YAxis min value autoscale.
func (plot *Plot) SetYAxisAutoScaleMin(autoScale bool) {
plot.yAxisAutoScaleMin = autoScale
}
// SetYAxisAutoScaleMax enables YAxix max value autoscale.
func (plot *Plot) SetYAxisAutoScaleMax(autoScale bool) {
plot.yAxisAutoScaleMax = autoScale
}
// SetAxesColor sets axes x and y lines color.
func (plot *Plot) SetAxesColor(color tcell.Color) {
plot.axesColor = color
@ -109,6 +152,21 @@ func (plot *Plot) SetDrawAxes(draw bool) {
plot.drawAxes = draw
}
// SetDrawXAxisLabel set true in order to draw x axis label to screen.
func (plot *Plot) SetDrawXAxisLabel(draw bool) {
plot.drawXAxisLabel = draw
}
// SetXAxisLabelFunc sets x axis label function.
func (plot *Plot) SetXAxisLabelFunc(f func(int) string) {
plot.xAxisLabelFunc = f
}
// SetDrawYAxisLabel set true in order to draw y axis label to screen.
func (plot *Plot) SetDrawYAxisLabel(draw bool) {
plot.drawYAxisLabel = draw
}
// SetMarker sets marker type braille or dot mode.
func (plot *Plot) SetMarker(marker Marker) {
plot.marker = marker
@ -126,7 +184,27 @@ func (plot *Plot) SetData(data [][]float64) {
plot.brailleCellMap = make(map[image.Point]brailleCell)
plot.data = data
plot.maxVal = getMaxFloat64From2dSlice(data)
if plot.yAxisAutoScaleMax {
plot.maxVal = getMaxFloat64From2dSlice(data)
}
if plot.yAxisAutoScaleMin {
plot.minVal = getMinFloat64From2dSlice(data)
}
}
func (plot *Plot) SetMaxVal(maxVal float64) {
plot.maxVal = maxVal
}
func (plot *Plot) SetMinVal(minVal float64) {
plot.minVal = minVal
}
func (plot *Plot) SetYRange(minVal float64, maxVal float64) {
plot.minVal = minVal
plot.maxVal = maxVal
}
// SetDotMarkerRune sets dot marker rune.
@ -139,7 +217,8 @@ func (plot *Plot) getYAxisLabelsWidth() int {
return len(fmt.Sprintf("%.2f", plot.maxVal))
}
func (plot *Plot) getChartAreaRect() (int, int, int, int) {
// GetPlotRect returns the rect for the inner part of the plot, ie not including axes.
func (plot *Plot) GetPlotRect() (int, int, int, int) {
x, y, width, height := plot.Box.GetInnerRect()
plotYAxisLabelsWidth := plot.getYAxisLabelsWidth()
@ -192,43 +271,137 @@ func (plot *Plot) drawAxesToScreen(screen tcell.Screen) {
y+height-plotXAxisLabelsHeight-1,
tview.BoxDrawingsLightUpAndRight, axesStyle)
// draw x axis labels
tview.Print(screen, "0",
x+plotYAxisLabelsWidth,
y+height-plotXAxisLabelsHeight,
1,
tview.AlignLeft, plot.axesLabelColor)
for labelX := x + plotYAxisLabelsWidth +
(plotXAxisLabelsGap)*plotHorizontalScale + 1; labelX < x+width-1; {
label := fmt.Sprintf(
"%d",
(labelX-(x+plotYAxisLabelsWidth)-1)/(plotHorizontalScale)+1,
)
tview.Print(screen, label, labelX, y+height-plotXAxisLabelsHeight, width, tview.AlignLeft, plot.axesLabelColor)
labelX += (len(label) + plotXAxisLabelsGap) * plotHorizontalScale
if plot.drawXAxisLabel {
plot.drawXAxisLabelsToScreen(screen, plotYAxisLabelsWidth, x, y, width, height)
}
// draw Y axis labels
verticalScale := plot.maxVal / float64(height-plotXAxisLabelsHeight-1)
if plot.drawYAxisLabel {
plot.drawYAxisLabelsToScreen(screen, plotYAxisLabelsWidth, x, y, height)
}
}
//nolint:funlen,cyclop
func (plot *Plot) drawXAxisLabelsToScreen(
screen tcell.Screen, plotYAxisLabelsWidth int, x int, y int, width int, height int,
) {
xAxisAreaStartX := x + plotYAxisLabelsWidth + 1
xAxisAreaEndX := x + width
xAxisAvailableWidth := xAxisAreaEndX - xAxisAreaStartX
labelMap := map[int]string{}
labelStartMap := map[int]int{}
maxDataPoints := 0
for _, d := range plot.data {
maxDataPoints = max(maxDataPoints, len(d))
}
// determine the width needed for the largest label
maxXAxisLabelWidth := 0
for _, d := range plot.data {
for i := range d {
label := plot.xAxisLabelFunc(i)
labelMap[i] = label
maxXAxisLabelWidth = max(maxXAxisLabelWidth, len(label))
}
}
// determine the start position for each label, if they were
// to be centered below the data point.
// Note: not all of these labels will be printed, as they would
// overlap with each other
for i, label := range labelMap {
expectedLabelWidth := len(label)
if i == 0 {
expectedLabelWidth += plotXAxisLabelsGap / 2 //nolint:mnd
} else {
expectedLabelWidth += plotXAxisLabelsGap
}
currentLabelStart := i - int(math.Round(float64(expectedLabelWidth)/2)) //nolint:mnd
labelStartMap[i] = currentLabelStart
}
// print the labels, skipping those that would overlap,
// stopping when there is no more space
lastUsedLabelEnd := math.MinInt
initialOffset := xAxisAreaStartX
for i := range maxDataPoints {
labelStart := labelStartMap[i]
if labelStart < lastUsedLabelEnd {
// the label would overlap with the previous label
continue
}
rawLabel := labelMap[i]
labelWithGap := rawLabel
if i == 0 {
labelWithGap += strings.Repeat(gapRune, plotXAxisLabelsGap/2) //nolint:mnd
} else {
labelWithGap = strings.Repeat(gapRune, plotXAxisLabelsGap/2) + labelWithGap + strings.Repeat(gapRune, plotXAxisLabelsGap/2) //nolint:lll,mnd
}
expectedLabelWidth := len(labelWithGap)
remainingWidth := xAxisAvailableWidth - labelStart
if expectedLabelWidth > remainingWidth {
// the label would be too long to fit in the remaining space
if expectedLabelWidth-1 <= remainingWidth {
// if we omit the last gap, it fits, so we draw that before stopping
labelWithoutGap := labelWithGap[:len(labelWithGap)-1]
plot.printXAxisLabel(screen, labelWithoutGap, initialOffset+labelStart, y+height-plotXAxisLabelsHeight)
}
break
}
lastUsedLabelEnd = labelStart + expectedLabelWidth
plot.printXAxisLabel(screen, labelWithGap, initialOffset+labelStart, y+height-plotXAxisLabelsHeight)
}
}
func (plot *Plot) printXAxisLabel(screen tcell.Screen, label string, x, y int) {
tview.Print(screen, label, x, y, len(label), tview.AlignLeft, plot.axesLabelColor)
}
func (plot *Plot) drawYAxisLabelsToScreen(screen tcell.Screen, plotYAxisLabelsWidth int, x int, y int, height int) {
verticalOffset := plot.minVal
verticalScale := (plot.maxVal - plot.minVal) / float64(height-plotXAxisLabelsHeight-1)
previousLabel := ""
for i := 0; i*(plotYAxisLabelsGap+1) < height-1; i++ {
label := fmt.Sprintf("%.2f", float64(i)*verticalScale*(plotYAxisLabelsGap+1))
var label string
if plot.yAxisLabelDataType == PlotYAxisLabelDataFloat {
label = fmt.Sprintf("%.2f", float64(i)*verticalScale*(plotYAxisLabelsGap+1)+verticalOffset)
} else {
label = strconv.Itoa(int(float64(i)*verticalScale*(plotYAxisLabelsGap+1) + verticalOffset))
}
// Prevent same label being shown twice.
// Mainly relevant for integer labels with small data sets (in value)
if label == previousLabel {
continue
}
previousLabel = label
tview.Print(screen,
label,
x,
y+height-(i*(plotYAxisLabelsGap+1))-2, //nolint:gomnd
y+height-(i*(plotYAxisLabelsGap+1))-2, //nolint:mnd
plotYAxisLabelsWidth,
tview.AlignLeft, plot.axesLabelColor)
}
}
//nolint:gocognit,cyclop
//nolint:cyclop,gocognit
func (plot *Plot) drawDotMarkerToScreen(screen tcell.Screen) {
x, y, width, height := plot.getChartAreaRect()
x, y, width, height := plot.GetPlotRect()
chartData := plot.getData()
verticalOffset := -plot.minVal
switch plot.ptype {
case PlotTypeLineChart:
@ -237,7 +410,14 @@ func (plot *Plot) drawDotMarkerToScreen(screen tcell.Screen) {
for j := 0; j < len(line) && j*plotHorizontalScale < width; j++ {
val := line[j]
lheight := int((val / plot.maxVal) * float64(height-1))
if math.IsNaN(val) {
continue
}
lheight := int(((val + verticalOffset) / plot.maxVal) * float64(height-1))
if lheight > height {
continue
}
if (x+(j*plotHorizontalScale) < x+width) && (y+height-1-lheight < y+height) {
tview.PrintJoinedSemigraphics(screen, x+(j*plotHorizontalScale), y+height-1-lheight, plot.dotMarkerRune, style)
@ -250,7 +430,14 @@ func (plot *Plot) drawDotMarkerToScreen(screen tcell.Screen) {
style := tcell.StyleDefault.Background(plot.GetBackgroundColor()).Foreground(plot.lineColors[i])
for j, val := range line {
lheight := int((val / plot.maxVal) * float64(height-1))
if math.IsNaN(val) {
continue
}
lheight := int(((val + verticalOffset) / plot.maxVal) * float64(height-1))
if lheight > height {
continue
}
if (x+(j*plotHorizontalScale) < x+width) && (y+height-1-lheight < y+height) {
tview.PrintJoinedSemigraphics(screen, x+(j*plotHorizontalScale), y+height-1-lheight, plot.dotMarkerRune, style)
@ -261,7 +448,7 @@ func (plot *Plot) drawDotMarkerToScreen(screen tcell.Screen) {
}
func (plot *Plot) drawBrailleMarkerToScreen(screen tcell.Screen) {
x, y, width, height := plot.getChartAreaRect()
x, y, width, height := plot.GetPlotRect()
plot.calcBrailleLines()
@ -274,8 +461,25 @@ func (plot *Plot) drawBrailleMarkerToScreen(screen tcell.Screen) {
}
}
func calcDataPointHeight(val, maxVal, minVal float64, height int) int {
return int(((val - minVal) / (maxVal - minVal)) * float64(height-1))
}
func calcDataPointHeightIfInBounds(val float64, maxVal float64, minVal float64, height int) (int, bool) {
if math.IsNaN(val) {
return 0, false
}
result := calcDataPointHeight(val, maxVal, minVal, height)
if (val > maxVal) || (val < minVal) || (result > height) {
return result, false
}
return result, true
}
func (plot *Plot) calcBrailleLines() {
x, y, _, height := plot.getChartAreaRect()
x, y, _, height := plot.GetPlotRect()
chartData := plot.getData()
for i, line := range chartData {
@ -283,30 +487,57 @@ func (plot *Plot) calcBrailleLines() {
continue
}
previousHeight := int((line[0] / plot.maxVal) * float64(height-1))
previousHeight := 0
lastValWasOk := false
for j, val := range line[1:] {
lheight := int((val / plot.maxVal) * float64(height-1))
for j, val := range line {
lheight, currentValIsOk := calcDataPointHeightIfInBounds(val, plot.maxVal, plot.minVal, height)
plot.setBrailleLine(
image.Pt(
(x+(j*plotHorizontalScale))*2, //nolint:gomnd
(y+height-previousHeight-1)*4, //nolint:gomnd
),
image.Pt(
(x+((j+1)*plotHorizontalScale))*2, //nolint:gomnd
(y+height-lheight-1)*4, //nolint:gomnd
),
plot.lineColors[i],
)
if !lastValWasOk && !currentValIsOk {
// nothing valid to draw, skip to next data point
continue
}
if !lastValWasOk { //nolint:gocritic
// current data point is single valid data point, draw it individually
plot.setBraillePoint(
calcBraillePoint(x, j+1, y, height, lheight),
plot.lineColors[i],
)
} else if !currentValIsOk {
// last data point was single valid data point, draw it individually
plot.setBraillePoint(
calcBraillePoint(x, j, y, height, previousHeight),
plot.lineColors[i],
)
} else {
// we have two valid data points, draw a line between them
plot.setBrailleLine(
calcBraillePoint(x, j, y, height, previousHeight),
calcBraillePoint(x, j+1, y, height, lheight),
plot.lineColors[i],
)
}
lastValWasOk = currentValIsOk
previousHeight = lheight
}
}
}
func calcBraillePoint(x, j, y, maxY, height int) image.Point {
return image.Pt(
(x+(j*plotHorizontalScale))*2, //nolint:mnd
(y+maxY-height-1)*4, //nolint:mnd
)
}
func (plot *Plot) setBraillePoint(p image.Point, color tcell.Color) {
point := image.Pt(p.X/2, p.Y/4) //nolint:gomnd
if p.X < 0 || p.Y < 0 {
return
}
point := image.Pt(p.X/2, p.Y/4) //nolint:mnd
plot.brailleCellMap[point] = brailleCell{
plot.brailleCellMap[point].cRune | brailleRune[p.Y%4][p.X%2],
color,

View File

@ -1,6 +1,7 @@
package tvxwidgets
import (
"math"
"sync"
"github.com/gdamore/tcell/v2"
@ -35,24 +36,30 @@ func (sl *Sparkline) Draw(screen tcell.Screen) {
// print label
if sl.dataTitle != "" {
tview.Print(screen, sl.dataTitle, x, y, width, tview.AlignLeft, sl.dataTitlecolor)
barHeight--
}
maxVal := getMaxFloat64FromSlice(sl.data)
if maxVal == 0 {
if maxVal < 0 {
return
}
// print lines
for i := 0; i < len(sl.data) && i+x < x+width; i++ {
data := sl.data[i]
if math.IsNaN(data) {
continue
}
dHeight := int((data / maxVal) * float64(barHeight))
sparkChar := barsRune[len(barsRune)-1]
style := tcell.StyleDefault.Background(sl.GetBackgroundColor()).Foreground(sl.lineColor)
for j := 0; j < dHeight; j++ {
for j := range dHeight {
tview.PrintJoinedSemigraphics(screen, i+x, y-1+height-j, sparkChar, style)
}

View File

@ -1,6 +1,7 @@
package tvxwidgets
import (
"math"
"strings"
"github.com/gdamore/tcell/v2"
@ -77,26 +78,62 @@ func getMaxFloat64From2dSlice(slices [][]float64) float64 {
}
var (
max float64
maxValue float64
maxIsInit bool
)
for _, slice := range slices {
for _, val := range slice {
if math.IsNaN(val) {
continue
}
if !maxIsInit {
maxIsInit = true
max = val
maxValue = val
continue
}
if val > max {
max = val
if val > maxValue {
maxValue = val
}
}
}
return max
return maxValue
}
func getMinFloat64From2dSlice(slices [][]float64) float64 {
if len(slices) == 0 {
return 0
}
var (
minValue float64
minIsInit bool
)
for _, slice := range slices {
for _, val := range slice {
if math.IsNaN(val) {
continue
}
if !minIsInit {
minIsInit = true
minValue = val
continue
}
if val < minValue {
minValue = val
}
}
}
return minValue
}
// returns max values in float64 slices.
@ -105,14 +142,19 @@ func getMaxFloat64FromSlice(slice []float64) float64 {
return 0
}
max := slice[0]
for i := 1; i < len(slice); i++ {
if slice[i] > max {
max = slice[i]
maxValue := -1.0
for i := range slice {
if math.IsNaN(slice[i]) {
continue
}
if slice[i] > maxValue {
maxValue = slice[i]
}
}
return max
return maxValue
}
func absInt(x int) int {
@ -125,11 +167,11 @@ func absInt(x int) int {
func drawLine(screen tcell.Screen, startX int, startY int, length int, mode drawLineMode, style tcell.Style) {
if mode == horizontalLine {
for i := 0; i < length; i++ {
for i := range length {
tview.PrintJoinedSemigraphics(screen, startX+i, startY, tview.BoxDrawingsLightTripleDashHorizontal, style)
}
} else if mode == verticalLine {
for i := 0; i < length; i++ {
for i := range length {
tview.PrintJoinedSemigraphics(screen, startX, startY+i, tview.BoxDrawingsLightTripleDashVertical, style)
}
}