Skip to content

Commit

Permalink
feat: dynamic width columns based on content
Browse files Browse the repository at this point in the history
  • Loading branch information
achannarasappa committed Apr 5, 2021
1 parent 7dcee18 commit 310f1cc
Showing 1 changed file with 109 additions and 34 deletions.
143 changes: 109 additions & 34 deletions internal/ui/component/watchlist/watchlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ import (
grid "github.com/achannarasappa/term-grid"
)

const (
WIDTH_MARKET_STATE = 5
WIDTH_GUTTER = 1
WIDTH_LABEL = 15
WIDTH_NAME = 20
WIDTH_POSITION_GUTTER = 2
WIDTH_CHANGE_STATIC = 12 // "↓ " + " (100.00%)" = 12 length
WIDTH_RANGE_STATIC = 3 // " - " = 3 length
)

type Model struct {
Width int
Quotes []Quote
Expand All @@ -24,11 +34,17 @@ type Model struct {
Sorter Sorter
Context c.Context
styles c.Styles
cellWidths CellWidths
}

type CellWidths struct {
PositionMaxWidth int
QuoteMaxWidth int
positionLength int
quoteLength int
WidthQuote int
WidthQuoteExtended int
WidthQuoteRange int
WidthPosition int
WidthPositionExtended int
}

// NewModel returns a model with default values.
Expand All @@ -50,6 +66,10 @@ func (m Model) View() string {
return fmt.Sprintf("Terminal window too narrow to render content\nResize to fix (%d/80)", m.Width)
}

if (m.cellWidths == CellWidths{}) {
m.cellWidths = getCellWidths(m.Quotes, m.Positions)
}

quotes := m.Sorter(m.Quotes, m.Positions)
rows := make([]grid.Row, 0)
for _, quote := range quotes {
Expand All @@ -60,7 +80,7 @@ func (m Model) View() string {
rows,
grid.Row{
Width: m.Width,
Cells: buildCells(quote, position, m.Context.Config, m.styles),
Cells: buildCells(quote, position, m.Context.Config, m.styles, m.cellWidths),
})

if m.Context.Config.ExtraInfoExchange {
Expand All @@ -87,73 +107,128 @@ func (m Model) View() string {

}

return grid.Render(grid.Grid{Rows: rows, GutterHorizontal: 1})
return grid.Render(grid.Grid{Rows: rows, GutterHorizontal: WIDTH_GUTTER})
}

func getCellWidths(quotes []Quote, positions []Position) CellWidths {
func getCellWidths(quotes []Quote, positions map[string]Position) CellWidths {

cellMaxWidths := CellWidths{}

for _, quote := range quotes {
quoteMaxWidth := len(ConvertFloatToString(quote.FiftyTwoWeekHigh, quote.IsVariablePrecision)) + 1
if quoteMaxWidth > cellMaxWidths.QuoteMaxWidth {
cellMaxWidths.QuoteMaxWidth = quoteMaxWidth
quoteLength := len(ConvertFloatToString(quote.FiftyTwoWeekHigh, quote.IsVariablePrecision))

if quoteLength > cellMaxWidths.quoteLength {
cellMaxWidths.quoteLength = quoteLength
cellMaxWidths.WidthQuote = quoteLength + WIDTH_CHANGE_STATIC
cellMaxWidths.WidthQuoteExtended = quoteLength
cellMaxWidths.WidthQuoteRange = WIDTH_RANGE_STATIC + (quoteLength * 2)
}
}

for _, position := range positions {
positionMaxWidth := len(ConvertFloatToString(position., quote.IsVariablePrecision)) + 1
if positionMaxWidth > cellMaxWidths.QuoteMaxWidth {
cellMaxWidths.QuoteMaxWidth = quoteMaxWidth
if position, ok := positions[quote.Symbol]; ok {
positionLength := len(ConvertFloatToString(position.Value, quote.IsVariablePrecision))
positionQuantityLength := len(ConvertFloatToString(position.Quantity, quote.IsVariablePrecision))

if positionLength > cellMaxWidths.positionLength {
cellMaxWidths.positionLength = positionLength
cellMaxWidths.WidthPosition = positionLength + WIDTH_CHANGE_STATIC + WIDTH_POSITION_GUTTER
}

if positionLength > cellMaxWidths.WidthPositionExtended {
cellMaxWidths.WidthPositionExtended = positionLength
}

if positionQuantityLength > cellMaxWidths.WidthPositionExtended {
cellMaxWidths.WidthPositionExtended = positionQuantityLength
}

}

}

return cellMaxWidths

}

func buildCells(quote Quote, position Position, config c.Config, styles c.Styles) []grid.Cell {
func buildCells(quote Quote, position Position, config c.Config, styles c.Styles, cellWidths CellWidths) []grid.Cell {

if !config.ExtraInfoFundamentals && !config.ShowHoldings {

return []grid.Cell{
{Text: textName(quote, styles)},
{Text: textMarketState(quote, styles), Width: 5, Align: grid.Right},
{Text: textQuote(quote, styles), Width: 25, Align: grid.Right},
{Text: textMarketState(quote, styles), Width: WIDTH_MARKET_STATE, Align: grid.Right},
{Text: textQuote(quote, styles), Width: cellWidths.WidthQuote, Align: grid.Right},
}

}

cellName := []grid.Cell{
{Text: textName(quote, styles), Width: 20},
{Text: textName(quote, styles), Width: WIDTH_NAME},
{Text: ""},
{Text: textMarketState(quote, styles), Width: 5, Align: grid.Right},
{Text: textMarketState(quote, styles), Width: WIDTH_MARKET_STATE, Align: grid.Right},
}

widthMinTerm := 53
cells := []grid.Cell{
{Text: textQuote(quote, styles), Width: 25, Align: grid.Right},
{Text: textQuote(quote, styles), Width: cellWidths.WidthQuote, Align: grid.Right},
}

widthMinTerm := WIDTH_NAME + WIDTH_MARKET_STATE + cellWidths.WidthQuote + (3 * WIDTH_GUTTER)

if config.ShowHoldings {
widthHoldings := widthMinTerm + cellWidths.WidthPosition + (3 * WIDTH_GUTTER) + cellWidths.WidthPositionExtended + WIDTH_LABEL

cells = append(
[]grid.Cell{
{Text: textPositionExtendedLabels(position, styles), Width: 15, Align: grid.Right, VisibleMinWidth: widthMinTerm + 53},
{Text: textPositionExtended(quote, position, styles), Width: 10, Align: grid.Right, VisibleMinWidth: widthMinTerm + 37},
{Text: textPosition(quote, position, styles), Width: 25, Align: grid.Right, VisibleMinWidth: widthMinTerm + 26},
{
Text: textPositionExtendedLabels(position, styles),
Width: WIDTH_LABEL,
Align: grid.Right,
VisibleMinWidth: widthHoldings,
},
{
Text: textPositionExtended(quote, position, styles),
Width: cellWidths.WidthPositionExtended,
Align: grid.Right,
VisibleMinWidth: widthMinTerm + cellWidths.WidthPosition + (2 * WIDTH_GUTTER) + cellWidths.WidthPositionExtended,
},
{
Text: textPosition(quote, position, styles),
Width: cellWidths.WidthPosition,
Align: grid.Right,
VisibleMinWidth: widthMinTerm + cellWidths.WidthPosition + WIDTH_GUTTER,
},
},
cells...,
)
widthMinTerm += 60
widthMinTerm = widthHoldings
}

if config.ExtraInfoFundamentals {
cells = append(
[]grid.Cell{
{Text: textQuoteRangeLabels(quote, styles), Width: 15, Align: grid.Right, VisibleMinWidth: widthMinTerm + 63},
{Text: textQuoteRange(quote, styles), Width: 20, Align: grid.Right, VisibleMinWidth: widthMinTerm + 47},
{Text: textQuoteExtendedLabels(quote, styles), Width: 15, Align: grid.Right, VisibleMinWidth: widthMinTerm + 27},
{Text: textQuoteExtended(quote, styles), Width: 7, Align: grid.Right, VisibleMinWidth: widthMinTerm + 11},
{
Text: textQuoteRangeLabels(quote, styles),
Width: WIDTH_LABEL,
Align: grid.Right,
VisibleMinWidth: widthMinTerm + cellWidths.WidthQuoteExtended + (4 * WIDTH_GUTTER) + (2 * WIDTH_LABEL) + cellWidths.WidthQuoteRange,
},
{
Text: textQuoteRange(quote, styles),
Width: cellWidths.WidthQuoteRange,
Align: grid.Right,
VisibleMinWidth: widthMinTerm + cellWidths.WidthQuoteExtended + (3 * WIDTH_GUTTER) + WIDTH_LABEL + cellWidths.WidthQuoteRange,
},
{
Text: textQuoteExtendedLabels(quote, styles),
Width: WIDTH_LABEL,
Align: grid.Right,
VisibleMinWidth: widthMinTerm + cellWidths.WidthQuoteExtended + (2 * WIDTH_GUTTER) + WIDTH_LABEL,
},
{
Text: textQuoteExtended(quote, styles),
Width: cellWidths.WidthQuoteExtended,
Align: grid.Right,
VisibleMinWidth: widthMinTerm + cellWidths.WidthQuoteExtended + WIDTH_GUTTER,
},
},
cells...,
)
Expand Down Expand Up @@ -216,9 +291,9 @@ func textQuoteExtended(quote Quote, styles c.Styles) string {

func textQuoteExtendedLabels(quote Quote, styles c.Styles) string {

return styles.TextLabel("Prev. Close: ") +
return styles.TextLabel("Prev. Close:") +
"\n" +
styles.TextLabel("Open: ")
styles.TextLabel("Open:")
}

func textPositionExtended(quote Quote, position Position, styles c.Styles) string {
Expand Down Expand Up @@ -267,9 +342,9 @@ func textQuoteRangeLabels(quote Quote, styles c.Styles) string {
textDayRange := ""

if quote.PriceDayHigh != 0.0 && quote.PriceDayLow != 0.0 {
textDayRange = styles.TextLabel("Day Range: ") +
textDayRange = styles.TextLabel("Day Range:") +
"\n" +
styles.TextLabel("52wk Range: ")
styles.TextLabel("52wk Range:")
}

return textDayRange
Expand Down Expand Up @@ -316,11 +391,11 @@ func textMarketState(q Quote, styles c.Styles) string {

func quoteChangeText(change float64, changePercent float64, isVariablePrecision bool, styles c.Styles) string {
if change == 0.0 {
return styles.TextPrice(changePercent, " "+ConvertFloatToString(change, isVariablePrecision)+" ("+ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, " "+ConvertFloatToString(change, isVariablePrecision)+" ("+ConvertFloatToString(changePercent, false)+"%)")
}

if change > 0.0 {
return styles.TextPrice(changePercent, "↑ "+ConvertFloatToString(change, isVariablePrecision)+" ("+ConvertFloatToString(changePercent, false)+"%)")
return styles.TextPrice(changePercent, "↑ "+ConvertFloatToString(change, isVariablePrecision)+" ("+ConvertFloatToString(changePercent, false)+"%)")
}

return styles.TextPrice(changePercent, "↓ "+ConvertFloatToString(change, isVariablePrecision)+" ("+ConvertFloatToString(changePercent, false)+"%)")
Expand Down

0 comments on commit 310f1cc

Please sign in to comment.