diff --git a/py/examples/tour.py b/py/examples/tour.py
index ef4f99168f5..ff683c13ec0 100644
--- a/py/examples/tour.py
+++ b/py/examples/tour.py
@@ -233,6 +233,7 @@ def get_wave_completions(line, character, file_content):
q.page['meta'] = ui.meta_card(
box='',
title=app_title,
+ animate=True,
scripts=[ui.script(q.app.tour_assets + '/loader.min.js')],
script=ui.inline_script(content=template, requires=['require'], targets=['monaco-editor']),
layouts=[
diff --git a/py/h2o_lightwave/h2o_lightwave/types.py b/py/h2o_lightwave/h2o_lightwave/types.py
index b98d6be9b76..aea7fa964b1 100644
--- a/py/h2o_lightwave/h2o_lightwave/types.py
+++ b/py/h2o_lightwave/h2o_lightwave/types.py
@@ -5626,6 +5626,7 @@ def __init__(
visible: Optional[bool] = None,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
):
_guard_scalar('Visualization.plot', plot, (Plot,), False, False, False)
_guard_scalar('Visualization.width', width, (str,), False, True, False)
@@ -5634,6 +5635,7 @@ def __init__(
_guard_scalar('Visualization.visible', visible, (bool,), False, True, False)
_guard_vector('Visualization.events', events, (str,), False, True, False)
_guard_vector('Visualization.interactions', interactions, (str,), False, True, False)
+ _guard_scalar('Visualization.animate', animate, (bool,), False, True, False)
self.plot = plot
"""The plot to be rendered in this visualization."""
self.data = data
@@ -5650,6 +5652,8 @@ def __init__(
"""The events to capture on this visualization. One of 'select_marks'."""
self.interactions = interactions
"""The interactions to be allowed for this plot. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event."""
+ self.animate = animate
+ """EXPERIMENTAL: True to turn on the chart animations. Defaults to False."""
def dump(self) -> Dict:
"""Returns the contents of this object as a dict."""
@@ -5660,6 +5664,7 @@ def dump(self) -> Dict:
_guard_scalar('Visualization.visible', self.visible, (bool,), False, True, False)
_guard_vector('Visualization.events', self.events, (str,), False, True, False)
_guard_vector('Visualization.interactions', self.interactions, (str,), False, True, False)
+ _guard_scalar('Visualization.animate', self.animate, (bool,), False, True, False)
return _dump(
plot=self.plot.dump(),
data=self.data,
@@ -5669,6 +5674,7 @@ def dump(self) -> Dict:
visible=self.visible,
events=self.events,
interactions=self.interactions,
+ animate=self.animate,
)
@staticmethod
@@ -5689,6 +5695,8 @@ def load(__d: Dict) -> 'Visualization':
_guard_vector('Visualization.events', __d_events, (str,), False, True, False)
__d_interactions: Any = __d.get('interactions')
_guard_vector('Visualization.interactions', __d_interactions, (str,), False, True, False)
+ __d_animate: Any = __d.get('animate')
+ _guard_scalar('Visualization.animate', __d_animate, (bool,), False, True, False)
plot: Plot = Plot.load(__d_plot)
data: PackedRecord = __d_data
width: Optional[str] = __d_width
@@ -5697,6 +5705,7 @@ def load(__d: Dict) -> 'Visualization':
visible: Optional[bool] = __d_visible
events: Optional[List[str]] = __d_events
interactions: Optional[List[str]] = __d_interactions
+ animate: Optional[bool] = __d_animate
return Visualization(
plot,
data,
@@ -5706,6 +5715,7 @@ def load(__d: Dict) -> 'Visualization':
visible,
events,
interactions,
+ animate,
)
@@ -10620,6 +10630,7 @@ def __init__(
script: Optional[InlineScript] = None,
stylesheet: Optional[InlineStylesheet] = None,
stylesheets: Optional[List[Stylesheet]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
):
_guard_scalar('MetaCard.box', box, (str,), False, False, False)
@@ -10639,6 +10650,7 @@ def __init__(
_guard_scalar('MetaCard.script', script, (InlineScript,), False, True, False)
_guard_scalar('MetaCard.stylesheet', stylesheet, (InlineStylesheet,), False, True, False)
_guard_vector('MetaCard.stylesheets', stylesheets, (Stylesheet,), False, True, False)
+ _guard_scalar('MetaCard.animate', animate, (bool,), False, True, False)
_guard_vector('MetaCard.commands', commands, (Command,), False, True, False)
self.box = box
"""A string indicating how to place this component on the page."""
@@ -10674,6 +10686,8 @@ def __init__(
"""CSS stylesheet to be applied to this page."""
self.stylesheets = stylesheets
"""External CSS files to load into the page."""
+ self.animate = animate
+ """EXPERIMENTAL: True to turn on the card animations. Defaults to False."""
self.commands = commands
"""Contextual menu commands for this component."""
@@ -10696,6 +10710,7 @@ def dump(self) -> Dict:
_guard_scalar('MetaCard.script', self.script, (InlineScript,), False, True, False)
_guard_scalar('MetaCard.stylesheet', self.stylesheet, (InlineStylesheet,), False, True, False)
_guard_vector('MetaCard.stylesheets', self.stylesheets, (Stylesheet,), False, True, False)
+ _guard_scalar('MetaCard.animate', self.animate, (bool,), False, True, False)
_guard_vector('MetaCard.commands', self.commands, (Command,), False, True, False)
return _dump(
view='meta',
@@ -10716,6 +10731,7 @@ def dump(self) -> Dict:
script=None if self.script is None else self.script.dump(),
stylesheet=None if self.stylesheet is None else self.stylesheet.dump(),
stylesheets=None if self.stylesheets is None else [__e.dump() for __e in self.stylesheets],
+ animate=self.animate,
commands=None if self.commands is None else [__e.dump() for __e in self.commands],
)
@@ -10756,6 +10772,8 @@ def load(__d: Dict) -> 'MetaCard':
_guard_scalar('MetaCard.stylesheet', __d_stylesheet, (dict,), False, True, False)
__d_stylesheets: Any = __d.get('stylesheets')
_guard_vector('MetaCard.stylesheets', __d_stylesheets, (dict,), False, True, False)
+ __d_animate: Any = __d.get('animate')
+ _guard_scalar('MetaCard.animate', __d_animate, (bool,), False, True, False)
__d_commands: Any = __d.get('commands')
_guard_vector('MetaCard.commands', __d_commands, (dict,), False, True, False)
box: str = __d_box
@@ -10775,6 +10793,7 @@ def load(__d: Dict) -> 'MetaCard':
script: Optional[InlineScript] = None if __d_script is None else InlineScript.load(__d_script)
stylesheet: Optional[InlineStylesheet] = None if __d_stylesheet is None else InlineStylesheet.load(__d_stylesheet)
stylesheets: Optional[List[Stylesheet]] = None if __d_stylesheets is None else [Stylesheet.load(__e) for __e in __d_stylesheets]
+ animate: Optional[bool] = __d_animate
commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands]
return MetaCard(
box,
@@ -10794,6 +10813,7 @@ def load(__d: Dict) -> 'MetaCard':
script,
stylesheet,
stylesheets,
+ animate,
commands,
)
@@ -11017,6 +11037,7 @@ def __init__(
plot: Plot,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
):
_guard_scalar('PlotCard.box', box, (str,), False, False, False)
@@ -11024,6 +11045,7 @@ def __init__(
_guard_scalar('PlotCard.plot', plot, (Plot,), False, False, False)
_guard_vector('PlotCard.events', events, (str,), False, True, False)
_guard_vector('PlotCard.interactions', interactions, (str,), False, True, False)
+ _guard_scalar('PlotCard.animate', animate, (bool,), False, True, False)
_guard_vector('PlotCard.commands', commands, (Command,), False, True, False)
self.box = box
"""A string indicating how to place this component on the page."""
@@ -11037,6 +11059,8 @@ def __init__(
"""The events to capture on this card. One of 'select_marks'."""
self.interactions = interactions
"""The interactions to be allowed for this card. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event."""
+ self.animate = animate
+ """EXPERIMENTAL: True to turn on the chart animations. Defaults to False."""
self.commands = commands
"""Contextual menu commands for this component."""
@@ -11047,6 +11071,7 @@ def dump(self) -> Dict:
_guard_scalar('PlotCard.plot', self.plot, (Plot,), False, False, False)
_guard_vector('PlotCard.events', self.events, (str,), False, True, False)
_guard_vector('PlotCard.interactions', self.interactions, (str,), False, True, False)
+ _guard_scalar('PlotCard.animate', self.animate, (bool,), False, True, False)
_guard_vector('PlotCard.commands', self.commands, (Command,), False, True, False)
return _dump(
view='plot',
@@ -11056,6 +11081,7 @@ def dump(self) -> Dict:
plot=self.plot.dump(),
events=self.events,
interactions=self.interactions,
+ animate=self.animate,
commands=None if self.commands is None else [__e.dump() for __e in self.commands],
)
@@ -11073,6 +11099,8 @@ def load(__d: Dict) -> 'PlotCard':
_guard_vector('PlotCard.events', __d_events, (str,), False, True, False)
__d_interactions: Any = __d.get('interactions')
_guard_vector('PlotCard.interactions', __d_interactions, (str,), False, True, False)
+ __d_animate: Any = __d.get('animate')
+ _guard_scalar('PlotCard.animate', __d_animate, (bool,), False, True, False)
__d_commands: Any = __d.get('commands')
_guard_vector('PlotCard.commands', __d_commands, (dict,), False, True, False)
box: str = __d_box
@@ -11081,6 +11109,7 @@ def load(__d: Dict) -> 'PlotCard':
plot: Plot = Plot.load(__d_plot)
events: Optional[List[str]] = __d_events
interactions: Optional[List[str]] = __d_interactions
+ animate: Optional[bool] = __d_animate
commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands]
return PlotCard(
box,
@@ -11089,6 +11118,7 @@ def load(__d: Dict) -> 'PlotCard':
plot,
events,
interactions,
+ animate,
commands,
)
diff --git a/py/h2o_lightwave/h2o_lightwave/ui.py b/py/h2o_lightwave/h2o_lightwave/ui.py
index f0457c546ce..ed0db0823d8 100644
--- a/py/h2o_lightwave/h2o_lightwave/ui.py
+++ b/py/h2o_lightwave/h2o_lightwave/ui.py
@@ -2087,6 +2087,7 @@ def visualization(
visible: Optional[bool] = None,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
) -> Component:
"""Create a visualization for display inside a form.
@@ -2099,6 +2100,7 @@ def visualization(
visible: True if the component should be visible. Defaults to True.
events: The events to capture on this visualization. One of 'select_marks'.
interactions: The interactions to be allowed for this plot. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event.
+ animate: EXPERIMENTAL: True to turn on the chart animations. Defaults to False.
Returns:
A `h2o_wave.types.Visualization` instance.
"""
@@ -2111,6 +2113,7 @@ def visualization(
visible,
events,
interactions,
+ animate,
))
@@ -3770,6 +3773,7 @@ def meta_card(
script: Optional[InlineScript] = None,
stylesheet: Optional[InlineStylesheet] = None,
stylesheets: Optional[List[Stylesheet]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
) -> MetaCard:
"""Represents page-global state.
@@ -3795,6 +3799,7 @@ def meta_card(
script: Javascript code to execute on this page.
stylesheet: CSS stylesheet to be applied to this page.
stylesheets: External CSS files to load into the page.
+ animate: EXPERIMENTAL: True to turn on the card animations. Defaults to False.
commands: Contextual menu commands for this component.
Returns:
A `h2o_wave.types.MetaCard` instance.
@@ -3817,6 +3822,7 @@ def meta_card(
script,
stylesheet,
stylesheets,
+ animate,
commands,
)
@@ -3903,6 +3909,7 @@ def plot_card(
plot: Plot,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
) -> PlotCard:
"""Create a card displaying a plot.
@@ -3914,6 +3921,7 @@ def plot_card(
plot: The plot to be displayed in this card.
events: The events to capture on this card. One of 'select_marks'.
interactions: The interactions to be allowed for this card. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event.
+ animate: EXPERIMENTAL: True to turn on the chart animations. Defaults to False.
commands: Contextual menu commands for this component.
Returns:
A `h2o_wave.types.PlotCard` instance.
@@ -3925,6 +3933,7 @@ def plot_card(
plot,
events,
interactions,
+ animate,
commands,
)
diff --git a/py/h2o_wave/h2o_wave/types.py b/py/h2o_wave/h2o_wave/types.py
index b98d6be9b76..aea7fa964b1 100644
--- a/py/h2o_wave/h2o_wave/types.py
+++ b/py/h2o_wave/h2o_wave/types.py
@@ -5626,6 +5626,7 @@ def __init__(
visible: Optional[bool] = None,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
):
_guard_scalar('Visualization.plot', plot, (Plot,), False, False, False)
_guard_scalar('Visualization.width', width, (str,), False, True, False)
@@ -5634,6 +5635,7 @@ def __init__(
_guard_scalar('Visualization.visible', visible, (bool,), False, True, False)
_guard_vector('Visualization.events', events, (str,), False, True, False)
_guard_vector('Visualization.interactions', interactions, (str,), False, True, False)
+ _guard_scalar('Visualization.animate', animate, (bool,), False, True, False)
self.plot = plot
"""The plot to be rendered in this visualization."""
self.data = data
@@ -5650,6 +5652,8 @@ def __init__(
"""The events to capture on this visualization. One of 'select_marks'."""
self.interactions = interactions
"""The interactions to be allowed for this plot. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event."""
+ self.animate = animate
+ """EXPERIMENTAL: True to turn on the chart animations. Defaults to False."""
def dump(self) -> Dict:
"""Returns the contents of this object as a dict."""
@@ -5660,6 +5664,7 @@ def dump(self) -> Dict:
_guard_scalar('Visualization.visible', self.visible, (bool,), False, True, False)
_guard_vector('Visualization.events', self.events, (str,), False, True, False)
_guard_vector('Visualization.interactions', self.interactions, (str,), False, True, False)
+ _guard_scalar('Visualization.animate', self.animate, (bool,), False, True, False)
return _dump(
plot=self.plot.dump(),
data=self.data,
@@ -5669,6 +5674,7 @@ def dump(self) -> Dict:
visible=self.visible,
events=self.events,
interactions=self.interactions,
+ animate=self.animate,
)
@staticmethod
@@ -5689,6 +5695,8 @@ def load(__d: Dict) -> 'Visualization':
_guard_vector('Visualization.events', __d_events, (str,), False, True, False)
__d_interactions: Any = __d.get('interactions')
_guard_vector('Visualization.interactions', __d_interactions, (str,), False, True, False)
+ __d_animate: Any = __d.get('animate')
+ _guard_scalar('Visualization.animate', __d_animate, (bool,), False, True, False)
plot: Plot = Plot.load(__d_plot)
data: PackedRecord = __d_data
width: Optional[str] = __d_width
@@ -5697,6 +5705,7 @@ def load(__d: Dict) -> 'Visualization':
visible: Optional[bool] = __d_visible
events: Optional[List[str]] = __d_events
interactions: Optional[List[str]] = __d_interactions
+ animate: Optional[bool] = __d_animate
return Visualization(
plot,
data,
@@ -5706,6 +5715,7 @@ def load(__d: Dict) -> 'Visualization':
visible,
events,
interactions,
+ animate,
)
@@ -10620,6 +10630,7 @@ def __init__(
script: Optional[InlineScript] = None,
stylesheet: Optional[InlineStylesheet] = None,
stylesheets: Optional[List[Stylesheet]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
):
_guard_scalar('MetaCard.box', box, (str,), False, False, False)
@@ -10639,6 +10650,7 @@ def __init__(
_guard_scalar('MetaCard.script', script, (InlineScript,), False, True, False)
_guard_scalar('MetaCard.stylesheet', stylesheet, (InlineStylesheet,), False, True, False)
_guard_vector('MetaCard.stylesheets', stylesheets, (Stylesheet,), False, True, False)
+ _guard_scalar('MetaCard.animate', animate, (bool,), False, True, False)
_guard_vector('MetaCard.commands', commands, (Command,), False, True, False)
self.box = box
"""A string indicating how to place this component on the page."""
@@ -10674,6 +10686,8 @@ def __init__(
"""CSS stylesheet to be applied to this page."""
self.stylesheets = stylesheets
"""External CSS files to load into the page."""
+ self.animate = animate
+ """EXPERIMENTAL: True to turn on the card animations. Defaults to False."""
self.commands = commands
"""Contextual menu commands for this component."""
@@ -10696,6 +10710,7 @@ def dump(self) -> Dict:
_guard_scalar('MetaCard.script', self.script, (InlineScript,), False, True, False)
_guard_scalar('MetaCard.stylesheet', self.stylesheet, (InlineStylesheet,), False, True, False)
_guard_vector('MetaCard.stylesheets', self.stylesheets, (Stylesheet,), False, True, False)
+ _guard_scalar('MetaCard.animate', self.animate, (bool,), False, True, False)
_guard_vector('MetaCard.commands', self.commands, (Command,), False, True, False)
return _dump(
view='meta',
@@ -10716,6 +10731,7 @@ def dump(self) -> Dict:
script=None if self.script is None else self.script.dump(),
stylesheet=None if self.stylesheet is None else self.stylesheet.dump(),
stylesheets=None if self.stylesheets is None else [__e.dump() for __e in self.stylesheets],
+ animate=self.animate,
commands=None if self.commands is None else [__e.dump() for __e in self.commands],
)
@@ -10756,6 +10772,8 @@ def load(__d: Dict) -> 'MetaCard':
_guard_scalar('MetaCard.stylesheet', __d_stylesheet, (dict,), False, True, False)
__d_stylesheets: Any = __d.get('stylesheets')
_guard_vector('MetaCard.stylesheets', __d_stylesheets, (dict,), False, True, False)
+ __d_animate: Any = __d.get('animate')
+ _guard_scalar('MetaCard.animate', __d_animate, (bool,), False, True, False)
__d_commands: Any = __d.get('commands')
_guard_vector('MetaCard.commands', __d_commands, (dict,), False, True, False)
box: str = __d_box
@@ -10775,6 +10793,7 @@ def load(__d: Dict) -> 'MetaCard':
script: Optional[InlineScript] = None if __d_script is None else InlineScript.load(__d_script)
stylesheet: Optional[InlineStylesheet] = None if __d_stylesheet is None else InlineStylesheet.load(__d_stylesheet)
stylesheets: Optional[List[Stylesheet]] = None if __d_stylesheets is None else [Stylesheet.load(__e) for __e in __d_stylesheets]
+ animate: Optional[bool] = __d_animate
commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands]
return MetaCard(
box,
@@ -10794,6 +10813,7 @@ def load(__d: Dict) -> 'MetaCard':
script,
stylesheet,
stylesheets,
+ animate,
commands,
)
@@ -11017,6 +11037,7 @@ def __init__(
plot: Plot,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
):
_guard_scalar('PlotCard.box', box, (str,), False, False, False)
@@ -11024,6 +11045,7 @@ def __init__(
_guard_scalar('PlotCard.plot', plot, (Plot,), False, False, False)
_guard_vector('PlotCard.events', events, (str,), False, True, False)
_guard_vector('PlotCard.interactions', interactions, (str,), False, True, False)
+ _guard_scalar('PlotCard.animate', animate, (bool,), False, True, False)
_guard_vector('PlotCard.commands', commands, (Command,), False, True, False)
self.box = box
"""A string indicating how to place this component on the page."""
@@ -11037,6 +11059,8 @@ def __init__(
"""The events to capture on this card. One of 'select_marks'."""
self.interactions = interactions
"""The interactions to be allowed for this card. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event."""
+ self.animate = animate
+ """EXPERIMENTAL: True to turn on the chart animations. Defaults to False."""
self.commands = commands
"""Contextual menu commands for this component."""
@@ -11047,6 +11071,7 @@ def dump(self) -> Dict:
_guard_scalar('PlotCard.plot', self.plot, (Plot,), False, False, False)
_guard_vector('PlotCard.events', self.events, (str,), False, True, False)
_guard_vector('PlotCard.interactions', self.interactions, (str,), False, True, False)
+ _guard_scalar('PlotCard.animate', self.animate, (bool,), False, True, False)
_guard_vector('PlotCard.commands', self.commands, (Command,), False, True, False)
return _dump(
view='plot',
@@ -11056,6 +11081,7 @@ def dump(self) -> Dict:
plot=self.plot.dump(),
events=self.events,
interactions=self.interactions,
+ animate=self.animate,
commands=None if self.commands is None else [__e.dump() for __e in self.commands],
)
@@ -11073,6 +11099,8 @@ def load(__d: Dict) -> 'PlotCard':
_guard_vector('PlotCard.events', __d_events, (str,), False, True, False)
__d_interactions: Any = __d.get('interactions')
_guard_vector('PlotCard.interactions', __d_interactions, (str,), False, True, False)
+ __d_animate: Any = __d.get('animate')
+ _guard_scalar('PlotCard.animate', __d_animate, (bool,), False, True, False)
__d_commands: Any = __d.get('commands')
_guard_vector('PlotCard.commands', __d_commands, (dict,), False, True, False)
box: str = __d_box
@@ -11081,6 +11109,7 @@ def load(__d: Dict) -> 'PlotCard':
plot: Plot = Plot.load(__d_plot)
events: Optional[List[str]] = __d_events
interactions: Optional[List[str]] = __d_interactions
+ animate: Optional[bool] = __d_animate
commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands]
return PlotCard(
box,
@@ -11089,6 +11118,7 @@ def load(__d: Dict) -> 'PlotCard':
plot,
events,
interactions,
+ animate,
commands,
)
diff --git a/py/h2o_wave/h2o_wave/ui.py b/py/h2o_wave/h2o_wave/ui.py
index f0457c546ce..ed0db0823d8 100644
--- a/py/h2o_wave/h2o_wave/ui.py
+++ b/py/h2o_wave/h2o_wave/ui.py
@@ -2087,6 +2087,7 @@ def visualization(
visible: Optional[bool] = None,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
) -> Component:
"""Create a visualization for display inside a form.
@@ -2099,6 +2100,7 @@ def visualization(
visible: True if the component should be visible. Defaults to True.
events: The events to capture on this visualization. One of 'select_marks'.
interactions: The interactions to be allowed for this plot. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event.
+ animate: EXPERIMENTAL: True to turn on the chart animations. Defaults to False.
Returns:
A `h2o_wave.types.Visualization` instance.
"""
@@ -2111,6 +2113,7 @@ def visualization(
visible,
events,
interactions,
+ animate,
))
@@ -3770,6 +3773,7 @@ def meta_card(
script: Optional[InlineScript] = None,
stylesheet: Optional[InlineStylesheet] = None,
stylesheets: Optional[List[Stylesheet]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
) -> MetaCard:
"""Represents page-global state.
@@ -3795,6 +3799,7 @@ def meta_card(
script: Javascript code to execute on this page.
stylesheet: CSS stylesheet to be applied to this page.
stylesheets: External CSS files to load into the page.
+ animate: EXPERIMENTAL: True to turn on the card animations. Defaults to False.
commands: Contextual menu commands for this component.
Returns:
A `h2o_wave.types.MetaCard` instance.
@@ -3817,6 +3822,7 @@ def meta_card(
script,
stylesheet,
stylesheets,
+ animate,
commands,
)
@@ -3903,6 +3909,7 @@ def plot_card(
plot: Plot,
events: Optional[List[str]] = None,
interactions: Optional[List[str]] = None,
+ animate: Optional[bool] = None,
commands: Optional[List[Command]] = None,
) -> PlotCard:
"""Create a card displaying a plot.
@@ -3914,6 +3921,7 @@ def plot_card(
plot: The plot to be displayed in this card.
events: The events to capture on this card. One of 'select_marks'.
interactions: The interactions to be allowed for this card. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event.
+ animate: EXPERIMENTAL: True to turn on the chart animations. Defaults to False.
commands: Contextual menu commands for this component.
Returns:
A `h2o_wave.types.PlotCard` instance.
@@ -3925,6 +3933,7 @@ def plot_card(
plot,
events,
interactions,
+ animate,
commands,
)
diff --git a/r/R/ui.R b/r/R/ui.R
index 8dd67bb1a6a..7d81a35fb39 100644
--- a/r/R/ui.R
+++ b/r/R/ui.R
@@ -2453,6 +2453,7 @@ ui_plot <- function(
#' @param visible True if the component should be visible. Defaults to True.
#' @param events The events to capture on this visualization. One of 'select_marks'.
#' @param interactions The interactions to be allowed for this plot. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event.
+#' @param animate EXPERIMENTAL: True to turn on the chart animations. Defaults to False.
#' @return A Visualization instance.
#' @export
ui_visualization <- function(
@@ -2463,7 +2464,8 @@ ui_visualization <- function(
name = NULL,
visible = NULL,
events = NULL,
- interactions = NULL) {
+ interactions = NULL,
+ animate = NULL) {
.guard_scalar("plot", "WavePlot", plot)
# TODO Validate data: Rec
.guard_scalar("width", "character", width)
@@ -2472,6 +2474,7 @@ ui_visualization <- function(
.guard_scalar("visible", "logical", visible)
.guard_vector("events", "character", events)
.guard_vector("interactions", "character", interactions)
+ .guard_scalar("animate", "logical", animate)
.o <- list(visualization=list(
plot=plot,
data=data,
@@ -2480,7 +2483,8 @@ ui_visualization <- function(
name=name,
visible=visible,
events=events,
- interactions=interactions))
+ interactions=interactions,
+ animate=animate))
class(.o) <- append(class(.o), c(.wave_obj, "WaveComponent"))
return(.o)
}
@@ -4388,6 +4392,7 @@ ui_stylesheet <- function(
#' @param script Javascript code to execute on this page.
#' @param stylesheet CSS stylesheet to be applied to this page.
#' @param stylesheets External CSS files to load into the page.
+#' @param animate EXPERIMENTAL: True to turn on the card animations. Defaults to False.
#' @param commands Contextual menu commands for this component.
#' @return A MetaCard instance.
#' @export
@@ -4409,6 +4414,7 @@ ui_meta_card <- function(
script = NULL,
stylesheet = NULL,
stylesheets = NULL,
+ animate = NULL,
commands = NULL) {
.guard_scalar("box", "character", box)
.guard_scalar("title", "character", title)
@@ -4427,6 +4433,7 @@ ui_meta_card <- function(
.guard_scalar("script", "WaveInlineScript", script)
.guard_scalar("stylesheet", "WaveInlineStylesheet", stylesheet)
.guard_vector("stylesheets", "WaveStylesheet", stylesheets)
+ .guard_scalar("animate", "logical", animate)
.guard_vector("commands", "WaveCommand", commands)
.o <- list(
box=box,
@@ -4446,6 +4453,7 @@ ui_meta_card <- function(
script=script,
stylesheet=stylesheet,
stylesheets=stylesheets,
+ animate=animate,
commands=commands,
view='meta')
class(.o) <- append(class(.o), c(.wave_obj, "WaveMetaCard"))
@@ -4550,6 +4558,7 @@ ui_pixel_art_card <- function(
#' @param plot The plot to be displayed in this card.
#' @param events The events to capture on this card. One of 'select_marks'.
#' @param interactions The interactions to be allowed for this card. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event.
+#' @param animate EXPERIMENTAL: True to turn on the chart animations. Defaults to False.
#' @param commands Contextual menu commands for this component.
#' @return A PlotCard instance.
#' @export
@@ -4560,6 +4569,7 @@ ui_plot_card <- function(
plot,
events = NULL,
interactions = NULL,
+ animate = NULL,
commands = NULL) {
.guard_scalar("box", "character", box)
.guard_scalar("title", "character", title)
@@ -4567,6 +4577,7 @@ ui_plot_card <- function(
.guard_scalar("plot", "WavePlot", plot)
.guard_vector("events", "character", events)
.guard_vector("interactions", "character", interactions)
+ .guard_scalar("animate", "logical", animate)
.guard_vector("commands", "WaveCommand", commands)
.o <- list(
box=box,
@@ -4575,6 +4586,7 @@ ui_plot_card <- function(
plot=plot,
events=events,
interactions=interactions,
+ animate=animate,
commands=commands,
view='plot')
class(.o) <- append(class(.o), c(.wave_obj, "WavePlotCard"))
diff --git a/tools/intellij-plugin/src/main/resources/templates/wave-components.xml b/tools/intellij-plugin/src/main/resources/templates/wave-components.xml
index d13ff24ec86..b24c294face 100644
--- a/tools/intellij-plugin/src/main/resources/templates/wave-components.xml
+++ b/tools/intellij-plugin/src/main/resources/templates/wave-components.xml
@@ -1782,7 +1782,7 @@
-
+
@@ -1796,6 +1796,7 @@
+
@@ -2013,24 +2014,26 @@
-
+
+
-
+
+
diff --git a/tools/vscode-extension/component-snippets.json b/tools/vscode-extension/component-snippets.json
index 2354f868c84..3170dd01823 100644
--- a/tools/vscode-extension/component-snippets.json
+++ b/tools/vscode-extension/component-snippets.json
@@ -1444,7 +1444,7 @@
"Wave Full MetaCard": {
"prefix": "w_full_meta_card",
"body": [
- "ui.meta_card(box='$1', title='$2', refresh=${3:None}, notification='$4', notification_bar=${5:None}, redirect='$6', icon='$7', dialog=${8:None}, side_panel=${9:None}, theme='$10', tracker=${11:None}, script=${12:None}, stylesheet=${13:None}, layouts=[\n\t\t$14\t\t\n], themes=[\n\t\t$15\t\t\n], scripts=[\n\t\t$16\t\t\n], stylesheets=[\n\t\t$17\t\t\n], commands=[\n\t\t$18\t\t\n])$0"
+ "ui.meta_card(box='$1', title='$2', refresh=${3:None}, notification='$4', notification_bar=${5:None}, redirect='$6', icon='$7', dialog=${8:None}, side_panel=${9:None}, theme='$10', tracker=${11:None}, script=${12:None}, stylesheet=${13:None}, animate=${14:False}, layouts=[\n\t\t$15\t\t\n], themes=[\n\t\t$16\t\t\n], scripts=[\n\t\t$17\t\t\n], stylesheets=[\n\t\t$18\t\t\n], commands=[\n\t\t$19\t\t\n])$0"
],
"description": "Create a full Wave MetaCard."
},
@@ -1528,14 +1528,14 @@
"Wave Full Visualization": {
"prefix": "w_full_visualization",
"body": [
- "ui.visualization(plot=$1, data=$2, width='${3:100%}', height='${4:300px}', name='$5', visible=${6:True}, events=[\n\t\t$7\t\t\n], interactions=[\n\t\t$8\t\t\n]),$0"
+ "ui.visualization(plot=$1, data=$2, width='${3:100%}', height='${4:300px}', name='$5', visible=${6:True}, animate=${7:False}, events=[\n\t\t$8\t\t\n], interactions=[\n\t\t$9\t\t\n]),$0"
],
"description": "Create a full Wave Visualization."
},
"Wave Full PlotCard": {
"prefix": "w_full_plot_card",
"body": [
- "ui.plot_card(box='$1', title='$2', data=$3, plot=$4, events=[\n\t\t$5\t\t\n], interactions=[\n\t\t$6\t\t\n], commands=[\n\t\t$7\t\t\n])$0"
+ "ui.plot_card(box='$1', title='$2', data=$3, plot=$4, animate=${5:False}, events=[\n\t\t$6\t\t\n], interactions=[\n\t\t$7\t\t\n], commands=[\n\t\t$8\t\t\n])$0"
],
"description": "Create a full Wave PlotCard."
},
diff --git a/ui/src/footer.tsx b/ui/src/footer.tsx
index f52207b4552..27bd6abc5ee 100644
--- a/ui/src/footer.tsx
+++ b/ui/src/footer.tsx
@@ -71,4 +71,4 @@ export const
return { render, changed }
})
-cards.register('footer', View, { effect: CardEffect.Transparent, marginless: true })
\ No newline at end of file
+cards.register('footer', View, { effect: CardEffect.Transparent, marginless: true, animate: false })
\ No newline at end of file
diff --git a/ui/src/header.tsx b/ui/src/header.tsx
index b340ff5412f..eec70ee9758 100644
--- a/ui/src/header.tsx
+++ b/ui/src/header.tsx
@@ -150,4 +150,4 @@ export const View = bond(({ name, state, changed }: Model {
- const { effect, marginless } = getCardStyle(c)
- return clas(css.slot, getEffectClass(effect), marginless ? css.marginless : '')
+ const { effect, marginless, animate = true } = getCardStyle(c)
+ return clas(css.slot, getEffectClass(effect), marginless ? css.marginless : '', animate ? 'wave-animate-card' : '')
},
toCardEffect = (color?: 'card' | 'transparent' | 'primary') => {
switch (color) {
diff --git a/ui/src/meta.tsx b/ui/src/meta.tsx
index 86c5aad9318..ea4f32fdb30 100644
--- a/ui/src/meta.tsx
+++ b/ui/src/meta.tsx
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { box, disconnect, Id, Model, on, S, U } from 'h2o-wave'
+import { B, box, disconnect, Id, Model, on, S, U } from 'h2o-wave'
import React from 'react'
import { NotificationBar, notificationBarB } from './notification_bar'
import { Dialog, dialogB } from './dialog'
@@ -162,6 +162,8 @@ interface State {
stylesheet?: InlineStylesheet
/** External CSS files to load into the page. */
stylesheets?: Stylesheet[]
+ /** EXPERIMENTAL: True to turn on the card animations. Defaults to False. */
+ animate?: B
}
const
@@ -197,7 +199,8 @@ export const
scripts,
script,
stylesheet,
- stylesheets
+ stylesheets,
+ animate
} = state
if (redirect) {
@@ -221,7 +224,7 @@ export const
// HACK: Since meta cards are processed within render, wait for React to finish the original render before proceeding.
setTimeout(() => notificationBarB(notification_bar ? { ...notification_bar } : null), 0)
-
+ if (animate) document.body.style.setProperty('--wave-animation-duration', '0.5s')
if (title) windowTitleB(title)
if (icon) windowIconB(icon)
if (typeof refresh === 'number' && refresh === 0) disconnect()
diff --git a/ui/src/nav.tsx b/ui/src/nav.tsx
index eb38d033194..6c40eff8157 100644
--- a/ui/src/nav.tsx
+++ b/ui/src/nav.tsx
@@ -183,4 +183,4 @@ export const
return { render, changed, update, valueB, dispose }
})
-cards.register('nav', View, { effect: CardEffect.Flat, marginless: true })
\ No newline at end of file
+cards.register('nav', View, { effect: CardEffect.Flat, marginless: true, animate: false })
\ No newline at end of file
diff --git a/ui/src/plot.tsx b/ui/src/plot.tsx
index 561501b3f40..0f358519821 100644
--- a/ui/src/plot.tsx
+++ b/ui/src/plot.tsx
@@ -966,7 +966,7 @@ const
return [geometries, annotations]
},
- makeChart = (el: HTMLElement, space: SpaceT, marks: Mark[], interactions: S[]): ChartCfg => {
+ makeChart = (el: HTMLElement, space: SpaceT, marks: Mark[], interactions: S[], animate = false): ChartCfg => {
// WARNING: makeCoord() must be called before other functions.
const
coordinate = makeCoord(space, marks), // WARNING: this call may transpose x/y in-place.
@@ -979,7 +979,7 @@ const
renderer: 'canvas',
theme: getPlotTheme(),
options: {
- animate: false,
+ animate,
coordinate,
scales,
axes,
@@ -1035,6 +1035,8 @@ export interface Visualization {
events?: S[]
/** The interactions to be allowed for this plot. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event. */
interactions?: S[]
+ /** EXPERIMENTAL: True to turn on the chart animations. Defaults to False. */
+ animate?: B
}
const tooltipContainer = document.createElement('div')
@@ -1052,13 +1054,10 @@ const PlotTooltip = ({ items, originalItems }: { items: TooltipItem[], originalI
{(item instanceof Date ? item.toISOString().split('T')[0] : item)}
- }
- )
- )}
+ }))
+ }
>
-
-
export const
XVisualization = ({ model }: { model: Visualization }) => {
const
@@ -1082,7 +1081,7 @@ export const
space = spaceTypeOf(raw_data, marks),
data = refactorData(raw_data, plot.marks),
{ Chart } = await import('@antv/g2'),
- chart = plot.marks ? new Chart(makeChart(el, space, plot.marks, model.interactions || [])) : null
+ chart = plot.marks ? new Chart(makeChart(el, space, plot.marks, model.interactions || [], model.animate)) : null
originalDataRef.current = unpack(model.data)
currentPlot.current = plot
if (chart) {
@@ -1173,23 +1172,23 @@ interface State {
events?: S[]
/** The interactions to be allowed for this card. One of 'drag_move' | 'scale_zoom' | 'brush'. Note: `brush` does not raise `select_marks` event. */
interactions?: S[]
+ /** EXPERIMENTAL: True to turn on the chart animations. Defaults to False. */
+ animate?: B
}
-export const
- View = bond(({ name, state, changed }: Model) => {
- const
- render = () => {
- const { title = 'Untitled', plot, data, events, interactions } = state
- return (
-
- )
- }
- return { render, changed }
- })
+export const View = bond(({ name, state, changed }: Model) => {
+ const render = () => {
+ const { title = 'Untitled', plot, data, events, interactions, animate } = state
+ return (
+
+ )
+ }
+ return { render, changed }
+})
cards.register('plot', View)
\ No newline at end of file
diff --git a/website/docs/assets/plot-animation.gif b/website/docs/assets/plot-animation.gif
new file mode 100644
index 00000000000..1f5c5d644b8
Binary files /dev/null and b/website/docs/assets/plot-animation.gif differ
diff --git a/website/docs/pages.md b/website/docs/pages.md
index f9972542fb1..6d4443b4be8 100644
--- a/website/docs/pages.md
+++ b/website/docs/pages.md
@@ -160,3 +160,41 @@ async def serve(q: Q):
page['bar'] = card
await page.save()
```
+
+## Animations (experimental)
+
+Cards can be animated during their creation by setting `animate=True` on the `ui.meta_card`.
+
+```py
+page['meta'] = ui.meta_card(box='', animate=True)
+```
+
+:::warning
+An animation is considered fluid when it is able to reach `60fps` (frames per second). To achieve such fps, one needs to make sure the browser has enough resources to paint the animation at such rate. Loading too many data or doing too much browser work may result in janky animations so use at your own risk.
+:::
+
+Default animation is a simple `fade in` animation (opacity 0 => 1) lasting for `0.5s`. if you are not happy with these defaults, it's possible to override these values via [custom CSS](/docs/custom-css/).
+
+```css
+:root {
+ /* Custom CSS properties to configure duration and animation. */
+ --wave-animation-duration: 0.5s;
+ --wave-card-animation: wave-fade-in
+}
+
+/* Override this class to get full control over animations. */
+.wave-animate-card {
+ animation: var(--wave-card-animation);
+ animation-duration: var(--wave-animation-duration);
+}
+
+@keyframes wave-fade-in {
+ from {
+ opacity: 0;
+ }
+
+ to {
+ opacity: 1;
+ }
+}
+```
diff --git a/website/docs/plotting.md b/website/docs/plotting.md
index b482965a106..ddf2bf288d0 100644
--- a/website/docs/plotting.md
+++ b/website/docs/plotting.md
@@ -223,6 +223,38 @@ q.page['example'] = ui.wide_plot_card(
)
```
+## Animations (experimental)
+
+Plots support basic animations when `animate=True`.
+
+:::warning
+An animation is considered fluid when it is able to reach `60fps` (frames per second). To achieve such fps, one needs to make sure the browser has enough resources to paint the animation at such rate. Loading too many data or doing too much browser work may result in janky animations so use at your own risk.
+:::
+
+
+
+```py {6}
+from h2o_wave import data
+
+q.page['example'] = ui.plot_card(
+ box='1 1 4 5',
+ title='Line',
+ animate=True,
+ data=data('year value', 8, rows=[
+ ('1991', 3),
+ ('1992', 4),
+ ('1993', 3.5),
+ ('1994', 5),
+ ('1995', 4.9),
+ ('1996', 6),
+ ('1997', 7),
+ ('1998', 9),
+ ('1999', 13),
+ ]),
+ plot=ui.plot([ui.mark(type='line', x_scale='time', x='=year', y='=value', y_min=0)])
+)
+```
+
## Point
- [Basic](/docs/examples/plot-point): Make a scatterplot.