@@ -26,8 +26,11 @@ import (
2626 "bytes"
2727 "encoding/json"
2828 "fmt"
29+ "strings"
2930
3031 "github.com/anqiansong/github-compare/pkg/stat"
32+ ui "github.com/gizak/termui/v3"
33+ "github.com/gizak/termui/v3/widgets"
3134 "github.com/jedib0t/go-pretty/v6/table"
3235 "github.com/spf13/viper"
3336 "gopkg.in/yaml.v3"
@@ -48,6 +51,10 @@ func render(printStyle style, list ...stat.Data) error {
4851 return err
4952 }
5053
54+ if len (data ) == 1 {
55+ return renderDetail (data [0 ])
56+ }
57+
5158 t := createTable (data , true )
5259 t .SetStyle (table .StyleLight )
5360 prettyText = t .Render ()
@@ -139,3 +146,153 @@ func createRow(title string, field string, emoji bool, data ...*viper.Viper) tab
139146 }
140147 return ret
141148}
149+
150+ const barWidth = 3
151+
152+ func renderDetail (data * viper.Viper ) error {
153+ if err := ui .Init (); err != nil {
154+ return err
155+ }
156+ defer ui .Close ()
157+
158+ starBar := createStarBarChart (data .Get ("latestMonthStargazers" ).(stat.Chart ),
159+ "Star(Latest Week)" , ui .ColorRed , func () []ui.Color {
160+ var colorList []ui.Color
161+ for i := 1 ; i < 18 ; i ++ {
162+ colorList = append (colorList , ui .Color (i ))
163+ }
164+ return colorList
165+ }()... )
166+
167+ forkBar := createStarBarChart (data .Get ("latestWeekForks" ).(stat.Chart ),
168+ "Forks(Latest Week)" , ui .ColorGreen )
169+ commitBar := createStarBarChart (data .Get ("latestWeekCommits" ).(stat.Chart ),
170+ "Commits(Latest Week)" , ui .ColorYellow )
171+ pullBar := createStarBarChart (data .Get ("latestWeekPulls" ).(stat.Chart ),
172+ "Pulls(Latest Week)" , ui .ColorWhite )
173+ issueBar := createStarBarChart (data .Get ("latestWeekIssues" ).(stat.Chart ),
174+ "Issues(Latest Week)" , ui .ColorCyan )
175+
176+ desc := creatParagraph ("About" , ui .ColorYellow , func () []string {
177+ return []string {
178+ fmt .Sprintf ("[◉ Homepage: %s](fg:green)" , data .GetString ("homepage" )),
179+ fmt .Sprintf ("[◉ Description: %s](fg:white)" , data .GetString ("description" )),
180+ fmt .Sprintf ("◉ Tags: %s" , formatTags (data .GetStringSlice ("tags" ))),
181+ }
182+ }()... )
183+ desc .TextStyle = ui .NewStyle (ui .ColorGreen )
184+
185+ metrics1 := creatParagraph ("Metrics1" , ui .ColorRed , func () []string {
186+ return []string {
187+ fmt .Sprintf ("[◉ TotalStars: %s](fg:red)" , data .GetString ("starCount" )),
188+ fmt .Sprintf ("[◉ TotalForks: %s](fg:green)" , data .GetString ("forkCount" )),
189+ fmt .Sprintf ("[◉ TotalWatcers: %s](fg:yellow)" , data .GetString ("watcherCount" )),
190+ fmt .Sprintf ("[◉ TotalContributors: %s](fg:cyan)" , data .GetString ("contributorCount" )),
191+ }
192+ }()... )
193+
194+ metrics2 := creatParagraph ("Metrics2" , ui .ColorGreen , func () []string {
195+ return []string {
196+ fmt .Sprintf ("[◉ LatestDayStars: %s](fg:red)" , data .GetString ("latestDayStarCount" )),
197+ fmt .Sprintf ("[◉ LatestWeekStars: %s](fg:green)" , data .GetString ("latestWeekStarCount" )),
198+ fmt .Sprintf ("[◉ LatestMonthStars: %s](fg:yellow)" ,
199+ data .GetString ("latestMonthStarCount" )),
200+ fmt .Sprintf ("[◉ ReleaseCount: %s](fg:cyan)" , data .GetString ("releaseCount" )),
201+ }
202+ }()... )
203+
204+ metrics3 := creatParagraph ("Metrics3" , ui .ColorYellow , func () []string {
205+ return []string {
206+ fmt .Sprintf ("[◉ Issue: %s](fg:green)" , data .GetString ("issue" )),
207+ fmt .Sprintf ("[◉ Pull: %s](fg:white)" , data .GetString ("pull" )),
208+ fmt .Sprintf ("[◉ License: %s](fg:yellow)" , data .GetString ("license" )),
209+ fmt .Sprintf ("[◉ Language: %s](fg:cyan)" , data .GetString ("language" )),
210+ }
211+ }()... )
212+
213+ metrics4 := creatParagraph ("Metrics4" , ui .ColorCyan , func () []string {
214+ return []string {
215+ fmt .Sprintf ("[◉ Age: %s](fg:green)" , data .GetString ("age" )),
216+ fmt .Sprintf ("[◉ LatestReleaseAt: %s](fg:white)" , data .GetString ("latestReleaseAt" )),
217+ fmt .Sprintf ("[◉ LastUpdatedAt: %s](fg:yellow)" , data .GetString ("lastUpdatedAt" )),
218+ fmt .Sprintf ("[◉ LastUpdatedAt: %s](fg:cyan)" , data .GetString ("lastUpdatedAt" )),
219+ }
220+ }()... )
221+
222+ grid := ui .NewGrid ()
223+ termWidth , termHeight := ui .TerminalDimensions ()
224+ grid .SetRect (0 , 0 , termWidth , termHeight )
225+ grid .Set (
226+ ui .NewRow (1.0 / 4 , ui .NewCol (1.0 , starBar )),
227+ ui .NewRow (1.0 / 4 ,
228+ ui .NewCol (1.0 / 4 , forkBar ),
229+ ui .NewCol (1.0 / 4 , commitBar ),
230+ ui .NewCol (1.0 / 4 , pullBar ),
231+ ui .NewCol (1.0 / 4 , issueBar ),
232+ ),
233+ ui .NewRow (1.0 / 4 , ui .NewCol (1.0 , desc )),
234+ ui .NewRow (1.0 / 4 ,
235+ ui .NewCol (1.0 / 4 , metrics1 ),
236+ ui .NewCol (1.0 / 4 , metrics2 ),
237+ ui .NewCol (1.0 / 4 , metrics3 ),
238+ ui .NewCol (1.0 / 4 , metrics4 ),
239+ ),
240+ )
241+ ui .Render (grid )
242+
243+ uiEvents := ui .PollEvents ()
244+ for {
245+ e := <- uiEvents
246+ switch e .ID {
247+ case "q" , "<C-c>" :
248+ ui .Clear ()
249+ return nil
250+ case "<Resize>" :
251+ payload := e .Payload .(ui.Resize )
252+ grid .SetRect (0 , 0 , payload .Width , payload .Height )
253+ ui .Clear ()
254+ ui .Render (grid )
255+ }
256+ }
257+ }
258+
259+ var colorString = []string {"black" , "red" , "green" , "yellow" , "blue" , "magenta" , "cyan" }
260+
261+ func formatTags (tags []string ) string {
262+ var ret []string
263+ for idx , e := range tags {
264+ colorIndex := idx % len (colorString )
265+ ret = append (ret , fmt .Sprintf ("[%s](fg:white,bg: %s)" , e , colorString [colorIndex ]))
266+ }
267+ return strings .Join (ret , " " )
268+ }
269+
270+ func creatParagraph (title string , titleColor ui.Color , list ... string ) * widgets.Paragraph {
271+ p := widgets .NewParagraph ()
272+ p .Text = strings .Join (list , "\n " )
273+ p .Title = title
274+ p .TextStyle = ui .NewStyle (titleColor )
275+ return p
276+ }
277+
278+ func createStarBarChart (data stat.Chart , title string , titleColor ui.Color ,
279+ barColors ... ui.Color ) * widgets.BarChart {
280+ bar := widgets .NewBarChart ()
281+ bar .Title = title
282+ bar .Data = data .Data
283+ bar .BarWidth = barWidth
284+ bar .Labels = data .Labels
285+ bar .TitleStyle = ui .NewStyle (titleColor )
286+ if len (barColors ) > 0 {
287+ bar .BarColors = barColors
288+ bar .LabelStyles = func () []ui.Style {
289+ var colorList []ui.Style
290+ for _ , c := range barColors {
291+ colorList = append (colorList , ui .NewStyle (c ))
292+ }
293+ return colorList
294+ }()
295+ }
296+ bar .NumStyles = []ui.Style {ui .NewStyle (ui .ColorBlack )}
297+ return bar
298+ }
0 commit comments