Skip to content

Commit 0325aec

Browse files
committed
feat: Limit number of char values
1 parent 01d0548 commit 0325aec

File tree

2 files changed

+287
-82
lines changed

2 files changed

+287
-82
lines changed

internal/app/ui/wealth.go

Lines changed: 163 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ui
22

33
import (
4+
"cmp"
45
"context"
56
"fmt"
67
"image/color"
@@ -18,32 +19,38 @@ import (
1819

1920
"github.com/ErikKalkoken/evebuddy/internal/app"
2021
ihumanize "github.com/ErikKalkoken/evebuddy/internal/humanize"
22+
"github.com/ErikKalkoken/evebuddy/internal/xslices"
2123
)
2224

2325
type wealth struct {
2426
widget.BaseWidget
2527

2628
onUpdate func(wallet, assets float64)
2729

28-
breakdown *coord.CartesianCategoricalChart
29-
characters *prop.PieChart
30-
top *widget.Label
31-
types *prop.PieChart
32-
u *baseUI
30+
assetDetail *coord.CartesianCategoricalChart
31+
assetSplit *prop.PieChart
32+
top *widget.Label
33+
u *baseUI
34+
walletDetail *coord.CartesianCategoricalChart
35+
walletSplit *prop.PieChart
3336
}
3437

3538
func newWealth(u *baseUI) *wealth {
3639
a := &wealth{
37-
breakdown: coord.NewCartesianCategoricalChart("Wealth Breakdown By Character in B ISK"),
38-
characters: prop.NewPieChart("Total Wealth By Character in B ISK"),
39-
top: makeTopLabel(),
40-
types: prop.NewPieChart("Total Wealth By Type"),
41-
u: u,
40+
assetDetail: coord.NewCartesianCategoricalChart(""),
41+
assetSplit: prop.NewPieChart(""),
42+
top: makeTopLabel(),
43+
u: u,
44+
walletDetail: coord.NewCartesianCategoricalChart(""),
45+
walletSplit: prop.NewPieChart(""),
4246
}
4347
a.ExtendBaseWidget(a)
44-
a.breakdown.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
45-
a.characters.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
46-
a.types.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
48+
a.assetDetail.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
49+
a.assetDetail.HideLegend()
50+
a.assetSplit.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
51+
a.walletSplit.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
52+
a.walletDetail.SetTitleStyle(theme.SizeNameSubHeadingText, theme.ColorNameForeground)
53+
a.walletDetail.HideLegend()
4754

4855
a.u.characterSectionChanged.AddListener(func(_ context.Context, arg characterSectionUpdated) {
4956
switch arg.section {
@@ -56,27 +63,20 @@ func newWealth(u *baseUI) *wealth {
5663
a.update()
5764
}
5865
})
59-
6066
return a
6167
}
6268

6369
func (a *wealth) CreateRenderer() fyne.WidgetRenderer {
64-
var total *fyne.Container
65-
if a.u.isDesktop {
66-
total = container.NewGridWithColumns(2, a.types, a.characters)
67-
} else {
68-
total = container.NewAdaptiveGrid(2, a.types, a.characters)
69-
}
70-
charts := container.NewAppTabs(
71-
container.NewTabItem("Total", total),
72-
container.NewTabItem("Breakdown", a.breakdown),
73-
)
7470
c := container.NewBorder(
7571
a.top,
7672
nil,
7773
nil,
7874
nil,
79-
container.NewScroll(charts),
75+
container.NewAppTabs(
76+
container.NewTabItem("Distribution", container.NewAdaptiveGrid(2, a.assetSplit, a.walletSplit)),
77+
container.NewTabItem("Assets", a.assetDetail),
78+
container.NewTabItem("Wallets", a.walletDetail),
79+
),
8080
)
8181
return widget.NewSimpleRenderer(c)
8282
}
@@ -101,106 +101,188 @@ func (a *wealth) update() {
101101
return
102102
}
103103

104-
colors := newColorWheel()
105-
// type
104+
const maxCharacters = 7
106105
var totalWallet, totalAssets float64
107106
for _, r := range data {
108107
totalAssets += r.assets
109108
totalWallet += r.wallet
110109
}
111-
s1, err := prop.NewSeries("Type", []chartData.ProportionalPoint{{
112-
C: "Assets",
113-
Val: totalAssets,
114-
Col: colors.next(),
115-
}, {
116-
C: "Wallets",
117-
Val: totalWallet,
118-
Col: colors.next(),
119-
}})
110+
colors := newColorWheel()
111+
112+
// totals
113+
totalText := ihumanize.Number(totalAssets+totalWallet, 1)
114+
fyne.Do(func() {
115+
a.top.Text = fmt.Sprintf("%s ISK total wealth • %d characters", totalText, characters)
116+
a.top.Importance = widget.MediumImportance
117+
a.top.Refresh()
118+
})
119+
120+
if a.onUpdate != nil {
121+
a.onUpdate(totalWallet, totalAssets)
122+
}
123+
124+
// total
125+
// s3, err := prop.NewSeries("", []chartData.ProportionalPoint{
126+
// {
127+
// C: "Assets",
128+
// Val: totalAssets,
129+
// Col: colors.next(),
130+
// },
131+
// {
132+
// C: "Wallets",
133+
// Val: totalWallet,
134+
// Col: colors.next(),
135+
// },
136+
// })
137+
// fyne.Do(func() {
138+
// a.total.RemoveSeries("")
139+
// err = a.total.AddSeries(s3)
140+
// if err != nil {
141+
// panic(err)
142+
// }
143+
// a.wallets.SetTitle(fmt.Sprintf("Wealth - Total: %.1f B ISK", totalWallet+totalAssets))
144+
// })
145+
146+
// Asset splits
147+
d1 := xslices.Map(data, func(r dataRow) chartData.ProportionalPoint {
148+
return chartData.ProportionalPoint{
149+
C: r.label,
150+
Val: r.assets,
151+
Col: colors.next(),
152+
}
153+
})
154+
d1 = reduceProportionalPoints(d1, maxCharacters)
155+
s1, err := prop.NewSeries("Characters", d1)
120156
if err != nil {
121157
panic(err)
122158
}
123159
fyne.Do(func() {
124-
a.types.RemoveSeries("Type")
125-
err = a.types.AddSeries(s1)
160+
a.assetSplit.RemoveSeries("Characters")
161+
err = a.assetSplit.AddSeries(s1)
126162
if err != nil {
127163
panic(err)
128164
}
165+
a.assetSplit.SetTitle(fmt.Sprintf("Assets By Character - Total: %.1f B ISK", totalAssets))
129166
})
130167

131-
// characters
168+
// Wallet split
132169
colors.reset()
133-
d1 := make([]chartData.ProportionalPoint, 0)
134-
for _, r := range data {
135-
d1 = append(d1, chartData.ProportionalPoint{
170+
d2 := xslices.Map(data, func(r dataRow) chartData.ProportionalPoint {
171+
return chartData.ProportionalPoint{
136172
C: r.label,
137-
Val: r.total,
173+
Val: r.wallet,
138174
Col: colors.next(),
139-
})
175+
}
176+
})
177+
d2 = reduceProportionalPoints(d2, maxCharacters)
178+
s2, err := prop.NewSeries("Characters", d2)
179+
if err != nil {
180+
panic(err)
140181
}
141-
s2, err := prop.NewSeries("Characters", d1)
142182
fyne.Do(func() {
143-
a.characters.RemoveSeries("Characters")
144-
err = a.characters.AddSeries(s2)
183+
a.walletSplit.RemoveSeries("Characters")
184+
err = a.walletSplit.AddSeries(s2)
145185
if err != nil {
146186
panic(err)
147187
}
188+
a.walletSplit.SetTitle(fmt.Sprintf("Wallets By Character - Total: %.1f B ISK", totalWallet))
148189
})
149190

150-
// Breakdown
151-
d3 := make([]chartData.CategoricalPoint, 0)
152-
for _, r := range data {
153-
d3 = append(d3, chartData.CategoricalPoint{
191+
// Assets detail
192+
colors.reset()
193+
d4 := xslices.Map(data, func(r dataRow) chartData.CategoricalPoint {
194+
return chartData.CategoricalPoint{
154195
C: r.label,
155196
Val: r.assets,
156-
})
157-
}
158-
s3, err := coord.NewCategoricalPointSeries("Assets", theme.Color(theme.ColorNameSuccess), d3)
197+
}
198+
})
199+
d4 = reduceCategoricalPoints(d4, maxCharacters)
200+
s4, err := coord.NewCategoricalPointSeries("Characters", colors.next(), d4)
159201
if err != nil {
160202
panic(err)
161203
}
162-
d4 := make([]chartData.CategoricalPoint, 0)
163-
for _, r := range data {
164-
d4 = append(d4, chartData.CategoricalPoint{
204+
fyne.Do(func() {
205+
a.assetDetail.RemoveSeries("Characters")
206+
err = a.assetDetail.AddBarSeries(s4)
207+
if err != nil {
208+
panic(err)
209+
}
210+
a.assetDetail.SetTitle(fmt.Sprintf("Assets By Character - Total: %.1f B ISK", totalAssets))
211+
})
212+
213+
// Wallet details
214+
colors.reset()
215+
d3 := xslices.Map(data, func(r dataRow) chartData.CategoricalPoint {
216+
return chartData.CategoricalPoint{
165217
C: r.label,
166218
Val: r.wallet,
167-
})
168-
}
169-
s4, err := coord.NewCategoricalPointSeries("Wallets", theme.Color(theme.ColorNameError), d4)
219+
}
220+
})
221+
d3 = reduceCategoricalPoints(d3, maxCharacters)
222+
s3, err := coord.NewCategoricalPointSeries("Characters", colors.next(), d3)
170223
if err != nil {
171224
panic(err)
172225
}
173-
174226
fyne.Do(func() {
175-
a.breakdown.RemoveSeries("Assets")
176-
a.breakdown.RemoveSeries("Wallets")
177-
err = a.breakdown.AddBarSeries(s3)
227+
a.walletDetail.RemoveSeries("Characters")
228+
err = a.walletDetail.AddBarSeries(s3)
178229
if err != nil {
179230
panic(err)
180231
}
181-
err = a.breakdown.AddBarSeries(s4)
182-
if err != nil {
183-
panic(err)
184-
}
185-
a.breakdown.SetYAxisLabel("B ISK")
232+
a.walletDetail.SetTitle(fmt.Sprintf("Wallets By Character - Total: %.1f B ISK", totalWallet))
186233
})
187234

188-
var total float64
189-
for _, r := range data {
190-
total += r.assets + r.wallet
191-
}
192-
193-
totalText := ihumanize.Number(total, 1)
235+
}
194236

195-
fyne.Do(func() {
196-
a.top.Text = fmt.Sprintf("%s ISK total wealth • %d characters", totalText, characters)
197-
a.top.Importance = widget.MediumImportance
198-
a.top.Refresh()
237+
func reduceProportionalPoints(data []chartData.ProportionalPoint, m int) []chartData.ProportionalPoint {
238+
if len(data) <= m {
239+
return data
240+
}
241+
slices.SortFunc(data, func(a, b chartData.ProportionalPoint) int {
242+
return cmp.Compare(b.Val, a.Val)
243+
})
244+
others := data[m].Val
245+
if len(data) > m {
246+
for _, x := range data[m+1:] {
247+
others += x.Val
248+
}
249+
}
250+
data = data[:m]
251+
slices.SortFunc(data, func(a, b chartData.ProportionalPoint) int {
252+
return strings.Compare(a.C, b.C)
199253
})
254+
data = append(data,
255+
chartData.ProportionalPoint{
256+
C: "Others",
257+
Val: others,
258+
Col: theme.Color(theme.ColorNameDisabled),
259+
})
260+
return data
261+
}
200262

201-
if a.onUpdate != nil {
202-
a.onUpdate(totalWallet, totalAssets)
263+
func reduceCategoricalPoints(data []chartData.CategoricalPoint, m int) []chartData.CategoricalPoint {
264+
if len(data) <= m {
265+
return data
203266
}
267+
slices.SortFunc(data, func(a, b chartData.CategoricalPoint) int {
268+
return cmp.Compare(b.Val, a.Val)
269+
})
270+
others := data[m].Val
271+
if len(data) > m {
272+
for _, x := range data[m+1:] {
273+
others += x.Val
274+
}
275+
}
276+
data = data[:m]
277+
slices.SortFunc(data, func(a, b chartData.CategoricalPoint) int {
278+
return strings.Compare(a.C, b.C)
279+
})
280+
data = append(data,
281+
chartData.CategoricalPoint{
282+
C: "Others",
283+
Val: others,
284+
})
285+
return data
204286
}
205287

206288
type dataRow struct {
@@ -270,7 +352,6 @@ func newColorWheel() colorWheel {
270352
theme.Color(colorNameSystem),
271353
theme.Color(colorNameAttention),
272354
theme.Color(theme.ColorNamePlaceHolder),
273-
theme.Color(theme.ColorNameDisabled),
274355
}
275356
return w
276357
}

0 commit comments

Comments
 (0)