crystalwindsnake / ex4nicegui Goto Github PK
View Code? Open in Web Editor NEWAn extension library for nicegui. It has built-in responsive components and fully implements data-responsive interface programming.
License: MIT License
An extension library for nicegui. It has built-in responsive components and fully implements data-responsive interface programming.
License: MIT License
from nicegui import ui
from ex4nicegui.reactive import rxui
from ex4nicegui import ref_computed, to_ref, on
data = {
"opts1": [f"{n}{i}" for i, n in enumerate("abcd")],
"opts2": [f"{n}{i}" for i, n in enumerate("mnxy")],
}
value1 = to_ref("opts1")
value2 = to_ref("")
@ref_computed
def opts2():
return data[value1.value]
@on(opts2)
def _():
value2.value = opts2.value[0]
rxui.select(list(data.keys()), value=value1)
rxui.select(opts2, value=value2)
rxui.label(value1)
rxui.label(value2)
When the first select box changed from option opts1 to opts2, the value of the second select box should have been m0, but now the value is None
from ex4nicegui import rxui, to_ref
a = to_ref("x")
rxui.input(value=a)
rxui.label(text=a)
When the browser opens 2 pages and then deletes one of them, the other page loses responsiveness.
If you use the page defined by ui.page, there is no problem
from nicegui import ui
from ex4nicegui.reactive import rxui
def onchange(e):
print(e.value)
rxui.input(on_change=onchange)
ui.run()
error when type input
TypeError: onchange() missing 1 required positional argument: 'e'
from nicegui import ui
from ex4nicegui.reactive import rxui
from ex4nicegui import to_ref
r_value = to_ref("")
rxui.lazy_input(value=r_value).props("outlined clearable")
rxui.label(r_value)
rxui.select(["a", "b", "c"], multiple=True)
when select item,error show:
TypeError: list indices must be integers or slices, not str
I hope support like this
from ex4nicegui.reactive import rxui
with rxui.button(""):
ui.avatar("home")
but it not ,just like this
from ex4nicegui.reactive import rxui
with rxui.button("").element:
ui.avatar("home")
from nicegui import ui
from ex4nicegui.reactive import rxui
from ex4nicegui import on, to_ref, effect, ref_computed, batch
a = to_ref(0)
b = to_ref(0)
text = ref_computed(lambda: f"a={a.value};b={b.value}")
@on([a, b, text])
def when_vars_changed():
ui.notify(f"a:{a.value};b:{b.value};text={text.value}")
def when_click():
a.value += 1
b.value += 1
ui.button("change all values", on_click=when_click)
ui.run()
Every time the button is clicked, notify will be triggered twice. because modifying a reactive variable always immediately triggers a reactive event.
we can improve it in this way
...
def when_click():
@batch
def _():
a.value += 1
b.value += 1
now,button clicked,notify will be triggered only once.
Perhaps we can provide an event_batch
decorator that is used like this:
@event_batch
def when_click():
a.value += 1
b.value += 1
from nicegui import ui
from ex4nicegui import deep_ref, rxui
r_opts = deep_ref(
{
"xAxis": {
"type": "category",
"data": ["Mon", "Tue", "Wed"],
},
"yAxis": {"type": "value"},
"series": [{"data": [120, 200, 150], "type": "bar"}],
}
)
rxui.number(value=rxui.vmodel(r_opts.value["series"][0]["data"][0]))
rxui.echarts(r_opts, not_merge=False)
the above code reports an error
data = deep_ref({"a": [1, 2]})
rxui.label(data)
@rxui.vfor(data.value["a"])
def _(s):
rxui.label(s.get())
rxui.input(value=rxui.vmodel(s.get()))
err
AttributeError: 'ListProxy' object has no attribute 'value'
from nicegui import ui
from ex4nicegui.reactive import rxui
from ex4nicegui import to_ref
opts = {
"title": {"text": "title", "bottom": 0},
"xAxis": {"type": "value"},
"yAxis": {
"type": "category",
"data": ["a", "b"],
},
"series": [
{
"name": "first",
"type": "bar",
"data": [18203, 23489],
},
{
"name": "second",
"type": "bar",
"data": [19325, 23438],
},
],
}
r_opts = to_ref(opts)
bar = rxui.echarts(r_opts)
def on_click():
del r_opts.value["title"]["bottom"]
r_opts.value = r_opts.value
ui.button("del title bottom", on_click=on_click)
When the button is clicked, the title position should return to the top left corner, but it doesn't
api like this:
code = """
flowchart TD
A --> B
B --> C
"""
def node_click(e):
ui.notify(e.args["nodeId"])
rxui.mermaid(code, ["A", "B"]).on("onNodeClick", node_click)
rxui.number(format="%.2f", step=0.1)
input 1111
, display 1.00
expect display 1111
aggrid in nicegui allows grouped table headers, but not in the bi module in ex4nicegui.
grid = ui.aggrid(
{
"defaultColDef": {"flex": 1},
"columnDefs": [
{
"headerName": "xxxx",
"children": [
{
"field": "name",
},
{
"field": "age",
},
],
},
{
"field": "parent",
},
],
"rowData": [
{"name": "Alice", "age": 18, "parent": "David"},
{"name": "Bob", "age": 21, "parent": "Eve"},
{"name": "Carol", "age": 42, "parent": "Frank"},
],
"rowSelection": "multiple",
}
).classes("max-h-40")
ds = bi.data_source(
pd.DataFrame(
{"name": "Alice", "age": 18, "parent": "David"},
{"name": "Bob", "age": 21, "parent": "Eve"},
{"name": "Carol", "age": 42, "parent": "Frank"},
)
)
ds.ui_aggrid(
options={
"columnDefs": [
{
"headerName": "xxxx",
"children": [
{
"field": "name",
},
{
"field": "age",
},
],
},
{
"field": "parent",
},
],
}
)
from nicegui import ui
from pyecharts.charts import Bar
from ex4nicegui import ref_computed, to_ref
from ex4nicegui.reactive import rxui
show = to_ref(True)
@ref_computed
def chart():
if not show.value:
return None
c = (
Bar()
.add_xaxis(
[
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
]
)
.add_yaxis(
"商家A",
[120, 200, 150, 80, 70, 110, 130],
)
)
return c
rxui.checkbox("show", value=show)
rxui.echarts.from_pyecharts(chart)
raise error when click the checkbox
就单一个to_ref就很爽了,给我一种用kotlin compose的感觉,思考起来很流畅,用起来也很方便
from ex4nicegui.reactive import rxui
echart = rxui.echarts(
{
"xAxis": {"type": "value"},
"yAxis": {
"type": "category",
"data": ["A", "B"],
"inverse": True,
},
"legend": {
"textStyle": {"color": "gray"}
},
"series": [
{
"type": "bar",
"name": "Alpha",
"data": [0.1, 0.2],
},
{
"type": "bar",
"name": "Beta",
"data": [0.3, 0.4],
},
],
}
)
def onclick(e):
print(e)
echart.on(
"click",
onclick
)
error:
TypeError: EChartsMouseEventArguments. init() takes 1 positional argument but 3 positional alord-only arguments ) were given
columns = [
{
"name": "a",
"label": "a",
"field": "a",
},
{"name": "b", "label": "b", "field": "b"},
]
rows = deep_ref(
[
{"a": "n1", "b": 18},
{"a": "n2", "b": 21},
]
)
rxui.table(columns=columns, rows=rows, row_key="name")
def onclick():
rows.value.append(
{"a": "n3"},
)
ui.button("change", on_click=onclick)
table should add new row when click button,but not now
from nicegui import ui
from ex4nicegui import to_ref, effect
from ex4nicegui.reactive import rxui
r_value = to_ref(None)
@effect
def _():
print(r_value.value)
rxui.select([], value=r_value, new_value_mode="add-unique")
it doesn't work
value = deep_ref(1)
rxui.number("number", min=0, max=100, step=1, value=value)
type hints error
Unable to assign parameter of type "Ref[int]" to parameter "value" of type "_TMaybeRef[float] | None" in function "__init__".
from nicegui import ui
from ex4nicegui.reactive import rxui
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.commons import utils
c = (
Bar()
.add_xaxis(["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"])
.add_yaxis(
"商家A",
[120, 200, 150, 80, 70, 110, 130],
)
.set_global_opts(
yaxis_opts=opts.AxisOpts(
axislabel_opts={
"formatter": utils.JsCode(
"""function (value, index) {
return value + 'kg';
}"""
)
}
)
)
)
rxui.echarts.from_pyecharts(c)
error:
simplejson.errors.JSONDecodeError: Expecting value: line 148 column 30
from ex4nicegui import bi
import pandas as pd
df = pd.DataFrame(
{
"cls1": [
"x1",
"x1",
"x1",
"x2",
"x2",
"x2",
],
"cls2": ["a", "b", "c", "c", "b", "a"],
}
)
ds = bi.data_source(df)
ds.ui_select("cls1", value="x1", multiple=False)
ds.ui_select("cls2")
At this point, the cls2 dropdown box has two selected 'a' values, which is correct. There should be no selected values.
rxui.echarts.register_map(
"china", "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json"
)
rxui.echarts(
{
"geo": {
"map": "china",
"roam": True,
},
"tooltip": {},
"legend": {},
"series": [],
}
)
Hi,
Do you have any plan to support Vue flow (https://vueflow.dev/guide/getting-started.html)
Thank!
“@bar2.on_chart_click”报错。
# 使用pyecharts配置图表
@ds.ui_echarts
def bar2(data: pd.DataFrame):
data = data.groupby("name").agg({"idc1": "sum", "idc2": "sum"}).reset_index()
return (
Bar()
.add_xaxis(data["name"].tolist())
.add_yaxis("idc1", data["idc1"].tolist())
.add_yaxis("idc2", data["idc2"].tolist())
)
bar2.classes("h-[20rem]")
# 绑定点击事件,即可实现跳转
@bar2.on_chart_click
def cl(e):
ui.open(f"/details/{e.name}", new_tab=True)
This parameter only needs to support the len and slicing interfaces.
r_df = to_ref(pd.DataFrame({"value": range(100)}))
pagination = rxui.use_pagination(source = r_df)
Currently, the type annotation of source parameter is list, but an interface type should be used.
from nicegui import ui
from ex4nicegui import on
from ex4nicegui.reactive import use_pagination
page = use_pagination(list(range(100)))
@on(page.current_page)
def _():
print(page.current_page.value)
ui.button("prev page", on_click=page.prev)
ui.button("next page", on_click=page.next)
ui.run()
If you keep clicking the previous page, the value of the current page in the console will be less than 0.
from ex4nicegui.reactive import rxui
from ex4nicegui import to_ref
from nicegui import ui
options = to_ref({'a': '我是a', 'b': '我是b'})
rxui.radio(options=options)
ui.run()
console error when click radio option:
KeyError: 0
Currently, rxui.use_draggable
obtains the responsive variable of the drag and drop position.
from nicegui import ui
from ex4nicegui.reactive import rxui
from ex4nicegui import ref_computed, to_ref
with ui.card().classes("select-none") as card:
ui.label("卡片")
dg = rxui.use_draggable(card)
@ref_computed
def position_text():
return f"x:{dg.x.value},y:{dg.y.value}"
rxui.label(position_text)
However, if it is supported to pass in a responsive variable from outside, this may be more useful.
x = to_ref(100.0)
y = to_ref(100.0)
@ref_computed
def position_text():
return f"x:{x.value},y:{y.value}"
# ui
with ui.card().classes("select-none") as card:
ui.label("卡片")
rxui.label(position_text)
dg = rxui.use_draggable(card, init_x=x, init_y=y)
this example allows data to be separated from interface code.
bug:
from ex4nicegui.reactive import rxui
text = to_ref("old text")
rxui.button(text).props("no-caps")
text.value='new text'
button text still 'old text'
from ex4nicegui.reactive import rxui
rxui.color_picker()
error
TypeError: ColorPicker.__init__() got an unexpected keyword argument 'color'
value = to_ref(0)
rxui.slider(min=0, max=1, step=0.1, value=value)
rxui.label(value)
label test not change
def onchange():
print('change')
rxui.lazy_input(value='value', on_change=onchange)
If the value of the input box does not change, the event should not be triggered
from ex4nicegui import bi
import pandas as pd
df = pd.DataFrame({"name": ["d", "a", "c", "e", None]})
ds = bi.data_source(df)
ds.ui_select("name")
I want to filter out null values and sort the options
bg_color = to_ref(False)
has_error = to_ref(False)
class_obj = ref_computed(
lambda: {"bg-blue": bg_color.value, "text-red": has_error.value}
)
rxui.switch("bg_color", value=bg_color)
rxui.switch("has_error", value=has_error)
# it works
rxui.label("bind to ref_computed").bind_classes(class_obj)
# not works
rxui.label("bind to ref_computed").bind_classes([class_obj](lambda: {"bg-blue": bg_color.value, "text-red": has_error.value}))
data=list(range(100))
pagination = rxui.use_pagination(data)
pagination.create_q_pagination()
from nicegui import ui
from ex4nicegui import deep_ref, rxui, to_raw
series_data = deep_ref([120, 200, 150])
def opts():
return {
"xAxis": {
"type": "category",
"data": ["Mon", "Tue", "Wed"],
},
"yAxis": {"type": "value"},
"series": [{"data": series_data.value, "type": "bar"}],
}
rxui.number(value=rxui.vmodel(series_data.value[0]))
rxui.echarts(opts, not_merge=False)
error:
TypeError: Type is not JSON serializable: ListProxy
If to raw is used, responsive is lost:
...
"series": [{"data": to_raw(series_data.value), "type": "bar"}],
...
You have to convert to list and then use to raw to get it to work.
...
"series": [{"data": to_raw(list(series_data.value)), "type": "bar"}],
...
like this:
rxui.table.from_pandas(
r_page_df,
columns_define_fn=lambda x: {"sortable": True},
)
text = to_ref("")
opacity = to_ref(1)
rxui.lazy_slider(min=0, max=1, step=0.1, value=opacity)
rx_label(text).bind_style({"opacity": opacity})
rxui.input(value=text)
No problem with the program, just a warning on the type hint
from nicegui import ui
import pandas as pd
from ex4nicegui.utils.signals import to_ref
from ex4nicegui.reactive import rxui
df = pd.DataFrame({"name": list("abcd"), "value": [1, 2, 3, 4]})
r_current_data = to_ref(df)
def onselect():
print(table.selection_ref.value)
table = rxui.table.from_pandas(
r_current_data, row_key="name", selection="multiple", on_select=onselect
)
When any row is checked, print result is an empty list.
columns = [
{"name": "name", "label": "Name", "field": "name"},
]
data = deep_ref(
{
"rows": [
{"name": "Alice"},
{"name": "Bob"},
{"name": "Carol"},
]
}
)
rxui.table(columns=columns, rows=rxui.vmodel(data.value["rows"]))
TypeError: 'RefWrapper' object is not callable
from nicegui import ui
from ex4nicegui import deep_ref, rxui
from ex4nicegui.utils.signals import to_ref_wrapper
import time
def calculate_execution_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(
f"Function '{func.__name__}' took {end_time - start_time} seconds to execute."
)
return result
return wrapper
@calculate_execution_time
def use_vmodel():
data = deep_ref({"a": "text"})
rxui.label(data)
rxui.input(value=rxui.vmodel(data.value["a"]))
use_vmodel()
@calculate_execution_time
def use_to_wrap():
data = deep_ref({"a": "text"})
def setter(new_value):
data.value["a"] = new_value
wrapper = to_ref_wrapper(lambda: data.value["a"], setter)
rxui.label(data)
rxui.input(value=wrapper)
use_to_wrap()
ui.run()
Using rxui.vmodel is much slower than using to_ref_wrapper
Function 'use_vmodel' took 0.6890246868133545 seconds to execute.
Function 'use_to_wrap' took 0.0 seconds to execute.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.