Load chart data from db
This commit is contained in:
parent
00ee710246
commit
ecee2f2a46
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild public/js/chart.js --bundle --minify --outfile=public/js/bundle.min.js"
|
"build": "esbuild public/js/chart.js --bundle --minify --outfile=public/js/chart.min.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chart.js": "^4.4.4",
|
"chart.js": "^4.4.4",
|
||||||
|
|
|
@ -18,14 +18,13 @@ Chart.register(
|
||||||
|
|
||||||
const element = document.getElementById('chart')
|
const element = document.getElementById('chart')
|
||||||
|
|
||||||
// TODO: get data from server
|
|
||||||
const yes = [
|
|
||||||
{ x: new Date('2024-01-01'), y: 20 },
|
|
||||||
{ x: new Date('2024-02-01'), y: 41 },
|
|
||||||
{ x: new Date('2024-03-01'), y: 53 }
|
|
||||||
]
|
|
||||||
|
|
||||||
const no = yes.map(({ x, y }) => ({ x, y: 100 - y }))
|
function transformPoint({ X, Y }) {
|
||||||
|
return { x: new Date(X), y: Y * 100 }
|
||||||
|
}
|
||||||
|
|
||||||
|
const no = JSON.parse($("#chart-data").getAttribute("chart-data-p0")).map(transformPoint)
|
||||||
|
const yes = JSON.parse($("#chart-data").getAttribute("chart-data-p1")).map(transformPoint)
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
|
@ -35,7 +34,7 @@ const config = {
|
||||||
data: yes,
|
data: yes,
|
||||||
backgroundColor: '#149e613d',
|
backgroundColor: '#149e613d',
|
||||||
borderColor: '#149e613d',
|
borderColor: '#149e613d',
|
||||||
borderWidth: 5,
|
borderWidth: 3,
|
||||||
tension: 0, // draw straight lines instead of bezier curves
|
tension: 0, // draw straight lines instead of bezier curves
|
||||||
pointStyle: false
|
pointStyle: false
|
||||||
},
|
},
|
||||||
|
@ -43,7 +42,7 @@ const config = {
|
||||||
data: no,
|
data: no,
|
||||||
backgroundColor: '#f5395e3d',
|
backgroundColor: '#f5395e3d',
|
||||||
borderColor: '#f5395e3d',
|
borderColor: '#f5395e3d',
|
||||||
borderWidth: 5,
|
borderWidth: 3,
|
||||||
tension: 0,
|
tension: 0,
|
||||||
pointStyle: false
|
pointStyle: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,9 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
|
||||||
quote1 = types.MarketQuote{}
|
quote1 = types.MarketQuote{}
|
||||||
uQ0 int
|
uQ0 int
|
||||||
uQ1 int
|
uQ1 int
|
||||||
|
rows *sql.Rows
|
||||||
|
p0 []types.MarketPoint
|
||||||
|
p1 []types.MarketPoint
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -172,6 +175,38 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rows, err = db.QueryContext(ctx, ""+
|
||||||
|
"SELECT created_at, quote(b, q0, q1, 1) AS p0, quote(b, q1, q0, 1) AS p1 "+
|
||||||
|
"FROM ( "+
|
||||||
|
" SELECT "+
|
||||||
|
" m.lmsr_b AS b, o.created_at, "+
|
||||||
|
" COALESCE(SUM(quantity) FILTER(WHERE o.outcome = 0) OVER (ORDER BY o.created_at ASC), 0) AS q0, "+
|
||||||
|
" COALESCE(sum(quantity) filter(where o.outcome = 1) over (order by o.created_at ASC), 0) AS q1 "+
|
||||||
|
" FROM markets m "+
|
||||||
|
" JOIN orders o ON o.market_id = m.id "+
|
||||||
|
" JOIN invoices i ON i.id = o.invoice_id "+
|
||||||
|
" WHERE m.id = $1 AND i.confirmed_at IS NOT NULL "+
|
||||||
|
") AS o "+
|
||||||
|
"UNION "+
|
||||||
|
"SELECT m.created_at, quote(m.lmsr_b, 0, 0, 1) AS p0, quote(m.lmsr_b, 0, 0, 1) AS p1 "+
|
||||||
|
"FROM markets m "+
|
||||||
|
"ORDER BY created_at", id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var (
|
||||||
|
createdAt time.Time
|
||||||
|
_p0 float64
|
||||||
|
_p1 float64
|
||||||
|
)
|
||||||
|
if err = rows.Scan(&createdAt, &_p0, &_p1); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p0 = append(p0, types.MarketPoint{X: createdAt, Y: _p0})
|
||||||
|
p1 = append(p1, types.MarketPoint{X: createdAt, Y: _p1})
|
||||||
|
}
|
||||||
|
|
||||||
total = lmsr.Quote(l.B, l.Q1, l.Q2, int(q))
|
total = lmsr.Quote(l.B, l.Q1, l.Q2, int(q))
|
||||||
quote0 = types.MarketQuote{
|
quote0 = types.MarketQuote{
|
||||||
Outcome: 0,
|
Outcome: 0,
|
||||||
|
@ -188,7 +223,11 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
|
||||||
Reward: float64(q) - total,
|
Reward: float64(q) - total,
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages.Market(m, quote0, quote1, uQ0, uQ1).Render(context.RenderContext(sc, c), c.Response().Writer)
|
return pages.Market(
|
||||||
|
m,
|
||||||
|
p0, p1,
|
||||||
|
quote0, quote1,
|
||||||
|
uQ0, uQ1).Render(context.RenderContext(sc, c), c.Response().Writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Add countdown? Use or at least show somewhere precise timestamps?
|
// TODO: Add countdown? Use or at least show somewhere precise timestamps?
|
||||||
templ Market(m types.Market, q0 types.MarketQuote, q1 types.MarketQuote, uQ0 int, uQ1 int) {
|
templ Market(m types.Market, p0 []types.MarketPoint, p1 []types.MarketPoint, q0 types.MarketQuote, q1 types.MarketQuote, uQ0 int, uQ1 int) {
|
||||||
<html>
|
<html>
|
||||||
@components.Head()
|
@components.Head()
|
||||||
<body
|
<body
|
||||||
|
@ -20,8 +20,14 @@ templ Market(m types.Market, q0 types.MarketQuote, q1 types.MarketQuote, uQ0 int
|
||||||
<div class="text-center font-bold my-1 mt-3">{ m.Question }</div>
|
<div class="text-center font-bold my-1 mt-3">{ m.Question }</div>
|
||||||
<div class="text-center text-muted my-1">{ humanize.Time(m.EndDate) }</div>
|
<div class="text-center text-muted my-1">{ humanize.Time(m.EndDate) }</div>
|
||||||
<div class="text-center text-muted my-1"></div>
|
<div class="text-center text-muted my-1"></div>
|
||||||
|
<div
|
||||||
|
class="none"
|
||||||
|
id="chart-data"
|
||||||
|
chart-data-p0={ templ.JSONString(p0) }
|
||||||
|
chart-data-p1={ templ.JSONString(p1) }
|
||||||
|
></div>
|
||||||
<div class="flex justify-center w-full max-h-64 my-3"><canvas id="chart"></canvas></div>
|
<div class="flex justify-center w-full max-h-64 my-3"><canvas id="chart"></canvas></div>
|
||||||
<script src="/js/bundle.min.js"></script>
|
<script src="/js/chart.min.js"></script>
|
||||||
<blockquote class="p-4 mb-4 border-s-4 border-muted">
|
<blockquote class="p-4 mb-4 border-s-4 border-muted">
|
||||||
if m.Description != "" {
|
if m.Description != "" {
|
||||||
{ m.Description }
|
{ m.Description }
|
||||||
|
|
|
@ -50,3 +50,8 @@ type MarketQuote struct {
|
||||||
TotalPrice float64
|
TotalPrice float64
|
||||||
Reward float64
|
Reward float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MarketPoint struct {
|
||||||
|
X time.Time
|
||||||
|
Y float64
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue