feat: replace Handler() method for HTTPServeMux() for better plugin and testing integration; remove via-plugin-picocss dependency from examples; add datastar h.H nodes for data-init, data-effect, and data-ignore-morph; update realtimechart example; other small improvements
This commit is contained in:
@@ -6,7 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-via/via"
|
||||
"github.com/go-via/via-plugin-picocss/picocss"
|
||||
// "github.com/go-via/via-plugin-picocss/picocss"
|
||||
"github.com/go-via/via/h"
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@ func main() {
|
||||
LogLvl: via.LogLevelDebug,
|
||||
DevMode: true,
|
||||
Plugins: []via.Plugin{
|
||||
picocss.Default,
|
||||
// picocss.Default,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -26,8 +26,42 @@ func main() {
|
||||
)
|
||||
|
||||
v.Page("/", func(c *via.Context) {
|
||||
chartComp := c.Component(chartCompFn)
|
||||
|
||||
isLive := true
|
||||
|
||||
isLiveSig := c.Signal("on")
|
||||
|
||||
refreshRate := c.Signal("24")
|
||||
|
||||
computedTickDuration := func() time.Duration {
|
||||
return 1000 / time.Duration(refreshRate.Int()) * time.Millisecond
|
||||
}
|
||||
|
||||
updateData := c.OnInterval(computedTickDuration(), func() {
|
||||
ts := time.Now().UnixMilli()
|
||||
val := rand.ExpFloat64() * 10
|
||||
|
||||
c.ExecScript(fmt.Sprintf(`
|
||||
if (myChart) {
|
||||
myChart.appendData({seriesIndex: 0, data: [[%d, %f]]});
|
||||
myChart.setOption({},{notMerge:false,lazyUpdate:true});
|
||||
};
|
||||
`, ts, val))
|
||||
})
|
||||
updateData.Start()
|
||||
|
||||
updateRefreshRate := c.Action(func() {
|
||||
updateData.UpdateInterval(computedTickDuration())
|
||||
})
|
||||
|
||||
toggleIsLive := c.Action(func() {
|
||||
isLive = isLiveSig.Bool()
|
||||
if isLive {
|
||||
updateData.Start()
|
||||
} else {
|
||||
updateData.Stop()
|
||||
}
|
||||
})
|
||||
c.View(func() h.H {
|
||||
return h.Div(h.Style("overflow-x:hidden"),
|
||||
h.Section(h.Class("container"),
|
||||
@@ -40,144 +74,100 @@ func main() {
|
||||
),
|
||||
),
|
||||
),
|
||||
chartComp(),
|
||||
h.Div(
|
||||
h.Div(h.ID("chart"), h.DataIgnoreMorph(), h.Style("width:100%;height:400px;"),
|
||||
h.Script(h.Raw(`
|
||||
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
var myChart = echarts.init(document.getElementById('chart'), prefersDark.matches ? 'dark' : 'light');
|
||||
var option = {
|
||||
backgroundColor: prefersDark.matches ? 'transparent' : '#ffffff',
|
||||
animationDurationUpdate: 0, // affects updates/redraws
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
position: function (pt) {
|
||||
return [pt[0], '10%'];
|
||||
},
|
||||
syncStrategy: 'closestSampledPoint',
|
||||
backgroundColor: prefersDark.matches ? '#13171fc0' : '#eeeeeec0',
|
||||
extraCssText: 'backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);'
|
||||
},
|
||||
title: {
|
||||
left: 'center',
|
||||
text: '📈 Real-Time Chart Example'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
boundaryGap: false,
|
||||
axisLabel: {
|
||||
hideOverlap: true
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: [0, '100%'],
|
||||
min: 0,
|
||||
max: 100
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 1,
|
||||
end: 100
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Fake Data',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
sampling: 'max',
|
||||
itemStyle: {
|
||||
color: '#e8ae01'
|
||||
},
|
||||
lineStyle: { color: '#e8ae01'},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#fecc63'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#c79400'
|
||||
}
|
||||
])
|
||||
},
|
||||
large: true,
|
||||
data: []
|
||||
}
|
||||
]
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
`)),
|
||||
),
|
||||
h.Section(
|
||||
h.Article(
|
||||
h.H5(h.Text("Controls")),
|
||||
h.Hr(),
|
||||
h.Div(h.Class("grid"),
|
||||
h.FieldSet(
|
||||
h.Legend(h.Text("Live Data")),
|
||||
h.Input(h.Type("checkbox"), h.Role("switch"), isLiveSig.Bind(), toggleIsLive.OnChange()),
|
||||
),
|
||||
h.Label(h.Text("Refresh Rate (Hz) ― "), refreshRate.Text(),
|
||||
h.Input(h.Type("range"), h.Attr("min", "1"), h.Attr("max", "200"), refreshRate.Bind(), updateRefreshRate.OnChange()),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
v.Start()
|
||||
}
|
||||
|
||||
func chartCompFn(c *via.Context) {
|
||||
isLive := true
|
||||
|
||||
isLiveSig := c.Signal("on")
|
||||
|
||||
refreshRate := c.Signal("24")
|
||||
|
||||
computedTickDuration := func() time.Duration {
|
||||
return 1000 / time.Duration(refreshRate.Int()) * time.Millisecond
|
||||
}
|
||||
|
||||
updateData := c.OnInterval(computedTickDuration(), func() {
|
||||
ts := time.Now().UnixMilli()
|
||||
val := rand.ExpFloat64() * 10
|
||||
|
||||
c.ExecScript(fmt.Sprintf(`
|
||||
if (myChart) {
|
||||
myChart.appendData({seriesIndex: 0, data: [[%d, %f]]});
|
||||
myChart.setOption({
|
||||
},{
|
||||
notMerge:false,
|
||||
lazyUpdate:true
|
||||
});
|
||||
};
|
||||
`, ts, val))
|
||||
})
|
||||
updateData.Start()
|
||||
|
||||
updateRefreshRate := c.Action(func() {
|
||||
updateData.UpdateInterval(computedTickDuration())
|
||||
})
|
||||
|
||||
toggleIsLive := c.Action(func() {
|
||||
isLive = isLiveSig.Bool()
|
||||
if isLive {
|
||||
updateData.Start()
|
||||
} else {
|
||||
updateData.Stop()
|
||||
}
|
||||
})
|
||||
|
||||
c.View(func() h.H {
|
||||
return h.Div(h.Div(h.ID("chart"), h.Style("width:100%;height:400px;"),
|
||||
h.Script(h.Raw(`
|
||||
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
var myChart = echarts.init(document.getElementById('chart'), prefersDark.matches ? 'dark' : 'light');
|
||||
var option = {
|
||||
backgroundColor: prefersDark.matches ? 'transparent' : '#ffffff',
|
||||
animationDurationUpdate: 0, // affects updates/redraws
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
position: function (pt) {
|
||||
return [pt[0], '10%'];
|
||||
},
|
||||
syncStrategy: 'closestSampledPoint',
|
||||
backgroundColor: prefersDark.matches ? '#13171fc0' : '#eeeeeec0',
|
||||
extraCssText: 'backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);'
|
||||
},
|
||||
title: {
|
||||
left: 'center',
|
||||
text: '📈 Real-Time Chart Example'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
boundaryGap: false,
|
||||
axisLabel: {
|
||||
hideOverlap: true
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: [0, '100%'],
|
||||
min: 0,
|
||||
max: 100
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 1,
|
||||
end: 100
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 100
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Fake Data',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
sampling: 'max',
|
||||
itemStyle: {
|
||||
color: '#e8ae01'
|
||||
},
|
||||
lineStyle: { color: '#e8ae01'},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: '#fecc63'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: '#c79400'
|
||||
}
|
||||
])
|
||||
},
|
||||
large: true,
|
||||
data: []
|
||||
}
|
||||
]
|
||||
};
|
||||
option && myChart.setOption(option);
|
||||
`))),
|
||||
h.Section(
|
||||
h.Article(
|
||||
h.H5(h.Text("Controls")),
|
||||
h.Hr(),
|
||||
h.Div(h.Class("grid"),
|
||||
h.FieldSet(
|
||||
h.Legend(h.Text("Live Data")),
|
||||
h.Input(h.Type("checkbox"), h.Role("switch"), isLiveSig.Bind(), toggleIsLive.OnChange()),
|
||||
),
|
||||
h.Label(h.Text("Refresh Rate (Hz) ― "), refreshRate.Text(),
|
||||
h.Input(h.Type("range"), h.Attr("min", "1"), h.Attr("max", "200"), refreshRate.Bind(), updateRefreshRate.OnChange()),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user