Skip to content

Commit 2a93a41

Browse files
Adding sig fig support (#588)
* Make decimal places in UI consistent * Remove old files * Checkpoint file for implementation Adding a checkpoint for step by step implementation of a solution that allows users to change the number of significant figures in setup.yaml and changes the number of significant figures shown when mousing over the stepped chart * Add frontend configuration for charts in setup.yaml * Adding sig fig support Sig fig support added on backend --------- Co-authored-by: Jordan George <jordanngeorge@gmail.com>
1 parent 6288af7 commit 2a93a41

File tree

14 files changed

+195
-7
lines changed

14 files changed

+195
-7
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
## The goal:
2+
3+
- Have users able to change the number of significant figures displayed on a stepped chart by editing setup.yaml (between 2 and 9 significant figures)
4+
- Prediction market charts to display a variable number of significant figures (2-9) based on the user input in setup.yaml
5+
6+
## Step by step implementation
7+
8+
1) Modify setup.yaml so that users can set the number of significant figures in the market charts
9+
10+
2) Create a tiny helper that:
11+
12+
- fetches the yaml file
13+
14+
- parses it with our SocialPredict tools
15+
16+
- clamps the number of significant figures to the allowed range (2–9)
17+
18+
- provides a ready-to-use number formatter
19+
20+
3) Build a single formatting utility
21+
22+
4) Wire the formatter into your Chart.js options
23+
24+
Apply it to:
25+
26+
- Y-axis ticks (most common)
27+
28+
- Tooltip label (so hover values match the tick style)

backend/handlers/setup/setuphandler.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,33 @@ func GetSetupHandler(loadEconomicsConfig func() (*setup.EconomicConfig, error))
2121
}
2222
}
2323
}
24+
25+
type frontendChartsResponse struct {
26+
SigFigs int `json:"sigFigs"`
27+
}
28+
29+
type frontendConfigResponse struct {
30+
Charts frontendChartsResponse `json:"charts"`
31+
}
32+
33+
func GetFrontendSetupHandler(loadEconomicsConfig func() (*setup.EconomicConfig, error)) func(w http.ResponseWriter, r *http.Request) {
34+
return func(w http.ResponseWriter, r *http.Request) {
35+
_, err := loadEconomicsConfig()
36+
if err != nil {
37+
http.Error(w, "Failed to load frontend config", http.StatusInternalServerError)
38+
return
39+
}
40+
41+
response := frontendConfigResponse{
42+
Charts: frontendChartsResponse{
43+
SigFigs: setup.ChartSigFigs(),
44+
},
45+
}
46+
47+
w.Header().Set("Content-Type", "application/json")
48+
if err := json.NewEncoder(w).Encode(response); err != nil {
49+
http.Error(w, "Failed to encode frontend setup response", http.StatusInternalServerError)
50+
return
51+
}
52+
}
53+
}

backend/server/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ func Start() {
114114

115115
// application setup and stats information
116116
router.Handle("/v0/setup", securityMiddleware(http.HandlerFunc(setuphandlers.GetSetupHandler(setup.LoadEconomicsConfig)))).Methods("GET")
117+
router.Handle("/v0/setup/frontend", securityMiddleware(http.HandlerFunc(setuphandlers.GetFrontendSetupHandler(setup.LoadEconomicsConfig)))).Methods("GET")
117118
router.Handle("/v0/stats", securityMiddleware(http.HandlerFunc(statshandlers.StatsHandler()))).Methods("GET")
118119
router.Handle("/v0/system/metrics", securityMiddleware(http.HandlerFunc(metricshandlers.GetSystemMetricsHandler))).Methods("GET")
119120
router.Handle("/v0/global/leaderboard", securityMiddleware(http.HandlerFunc(metricshandlers.GetGlobalLeaderboardHandler))).Methods("GET")

backend/setup/setup.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,27 @@ type Economics struct {
4848
Betting Betting `yaml:"betting"`
4949
}
5050

51+
type FrontendCharts struct {
52+
SigFigs int `yaml:"sigFigs"`
53+
}
54+
55+
type Frontend struct {
56+
Charts FrontendCharts `yaml:"charts"`
57+
}
58+
5159
type EconomicConfig struct {
5260
Economics Economics `yaml:"economics"`
61+
Frontend Frontend `yaml:"frontend"`
5362
}
5463

5564
var economicConfig *EconomicConfig
5665

66+
const (
67+
minChartSigFigs = 2
68+
maxChartSigFigs = 9
69+
defaultChartSigFigs = 4
70+
)
71+
5772
// load once as a singleton pattern
5873
var once sync.Once
5974

@@ -88,3 +103,23 @@ func mustLoadEconomicsConfig() {
88103
func init() {
89104
mustLoadEconomicsConfig()
90105
}
106+
107+
// ChartSigFigs returns a clamped significant figures value for chart formatting.
108+
func ChartSigFigs() int {
109+
if economicConfig == nil {
110+
mustLoadEconomicsConfig()
111+
}
112+
113+
sigFigs := economicConfig.Frontend.Charts.SigFigs
114+
if sigFigs == 0 {
115+
sigFigs = defaultChartSigFigs
116+
}
117+
118+
if sigFigs < minChartSigFigs {
119+
return minChartSigFigs
120+
}
121+
if sigFigs > maxChartSigFigs {
122+
return maxChartSigFigs
123+
}
124+
return sigFigs
125+
}

backend/setup/setup.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ economics:
1818
initialBetFee: 1
1919
buySharesFee: 0
2020
sellSharesFee: 0
21+
22+
frontend:
23+
charts:
24+
sigFigs: 4

backend/setup/setup_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,30 @@ func TestLoadEconomicsConfigSingleton(t *testing.T) {
2828
t.Fatalf("EconomicsConfig should return the singleton instance")
2929
}
3030
}
31+
32+
func TestChartSigFigsClamping(t *testing.T) {
33+
cfg, err := LoadEconomicsConfig()
34+
if err != nil {
35+
t.Fatalf("unexpected error loading config: %v", err)
36+
}
37+
38+
original := cfg.Frontend.Charts.SigFigs
39+
t.Cleanup(func() {
40+
cfg.Frontend.Charts.SigFigs = original
41+
})
42+
43+
cfg.Frontend.Charts.SigFigs = 1
44+
if got := ChartSigFigs(); got != minChartSigFigs {
45+
t.Fatalf("expected minChartSigFigs (%d), got %d", minChartSigFigs, got)
46+
}
47+
48+
cfg.Frontend.Charts.SigFigs = 99
49+
if got := ChartSigFigs(); got != maxChartSigFigs {
50+
t.Fatalf("expected maxChartSigFigs (%d), got %d", maxChartSigFigs, got)
51+
}
52+
53+
cfg.Frontend.Charts.SigFigs = 6
54+
if got := ChartSigFigs(); got != 6 {
55+
t.Fatalf("expected unclamped value 6, got %d", got)
56+
}
57+
}

frontend/src/components/layouts/activity/bets/BetsActivity.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const BetsActivityLayout = ({ marketId, refreshTrigger }) => {
5050
<div className="sp-cell-num text-xs sm:text-sm text-gray-300">{bet.amount}</div>
5151

5252
{/* After (sm+) */}
53-
<div className="hidden sm:block sp-cell-num text-gray-300">{bet.probability.toFixed(3)}</div>
53+
<div className="hidden sm:block sp-cell-num text-gray-300">{bet.probability.toFixed(2)}</div>
5454

5555
{/* Placed (stack full width on xs) */}
5656
<div className="col-span-3 sm:col-span-1 text-right sp-subline">

frontend/src/components/layouts/marketprojection/MarketProjectionLayout.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const MarketProjectionLayout = ({ marketId, amount, direction }) => {
5252
</button>
5353
{error && <div className="error-message">Error: {error}</div>}
5454
{projectionData && (
55-
<p>New Market Probability: {projectionData.projectedprobability.toFixed(4)}</p>
55+
<p>New Market Probability: {projectionData.projectedprobability.toFixed(2)}</p>
5656
)}
5757
{!projectionData && !error && !loading && (
5858
<p>Click "Update Projection" to see the new market probability after this trade.</p>

frontend/src/components/tables/MarketTable.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const MarketRow = ({ marketData }) => (
4141
</Link>
4242
</td>
4343
<td className='px-6 py-4 whitespace-nowrap text-sm text-gray-300'>
44-
{marketData.lastProbability.toFixed(3)}
44+
{marketData.lastProbability.toFixed(2)}
4545
</td>
4646
<td className='px-6 py-4 text-sm font-medium text-gray-300'>
4747
<Link

frontend/src/components/tables/MarketTables.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const MarketRow = ({ marketData }) => (
4242
</Link>
4343
</td>
4444
<td className='px-6 py-4 whitespace-nowrap text-sm text-gray-300'>
45-
{marketData.lastProbability.toFixed(3)}
45+
{marketData.lastProbability.toFixed(2)}
4646
</td>
4747
<td className='px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-300'>
4848
<Link

0 commit comments

Comments
 (0)