Skip to content

Commit

Permalink
Merge pull request #92 from vizzuhq/plugin
Browse files Browse the repository at this point in the history
Added: `Story.add_plugin` method
  • Loading branch information
veghdev authored Dec 21, 2023
2 parents 202695c + bda264a commit 03aee42
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 6 deletions.
25 changes: 25 additions & 0 deletions src/ipyvizzustory/storylib/story.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ def __init__(self, data: Data, style: Optional[Style] = None):

self._features: List[str] = []
self._events: List[str] = []
self._plugins: List[str] = []

if not data or type(data) != Data: # pylint: disable=unidiomatic-typecheck
raise TypeError("Type must be Data.")
Expand Down Expand Up @@ -502,6 +503,29 @@ def add_event(self, event: str, handler: str) -> None:
f"chart.on('{event}', event => {{{' '.join(handler.split())}}});"
)

def add_plugin(
self, plugin: str, options: Optional[dict] = None, name: str = "default"
) -> None:
"""
A method for register plugins of the chart.
Args:
plugin: The package name or the url of the plugin.
options: The plugin constructor options.
name: The name of the plugin (default `default`).
"""

if options is None:
options = {}

self._plugins.append(
"plugins.push({"
+ f"plugin: '{plugin}', "
+ f"options: {json.dumps(options, cls=RawJavaScriptEncoder)}, "
+ f"name: '{name}'"
+ "})"
)

def set_size(
self,
width: Optional[Union[int, float, str]] = None,
Expand Down Expand Up @@ -549,6 +573,7 @@ def to_html(self) -> str:
chart_size=self._size.style,
chart_features=f"\n{DISPLAY_INDENT * 3}".join(self._features),
chart_events=f"\n{DISPLAY_INDENT * 3}".join(self._events),
chart_plugins=f"\n{DISPLAY_INDENT * 3}".join(self._plugins),
)

def export_to_html(self, filename: PathLike) -> None:
Expand Down
49 changes: 43 additions & 6 deletions src/ipyvizzustory/storylib/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,57 @@ class IpyvizzuStory {{
window.IpyvizzuStory?.changeAnalyticsTo({analytics});
class Plugins {{
static _resolveVizzuVersion(vp) {{
const url = vp.vizzuUrl;
const versionMatch = url.match(/vizzu@([^\\/]+)\\//);
return versionMatch[1];
}}
static _resolveUrl(plugin, tag) {{
if (!plugin.includes('/')) {{
const jsdelivr = "https://cdn.jsdelivr.net/npm/@vizzu";
return `${{jsdelivr}}/${{plugin}}@${{tag}}/dist/mjs/index.min.js`;
}}
return plugin;
}}
static register(vp, chart, plugins) {{
const tag = `vizzu-${{Plugins._resolveVizzuVersion(vp)}}`;
const pluginsRegistered = [];
for (const plugin of plugins) {{
const pluginUrl = Plugins._resolveUrl(plugin.plugin, tag);
const pluginRegistered = import(pluginUrl).then(pluginModule => {{
const pluginInstance = new pluginModule[plugin.name](plugin.options);
chart.feature(pluginInstance, true);
}}).catch((error) => {{
console.error('Error importing plugin:', pluginUrl, error)
}});
pluginsRegistered.push(pluginRegistered);
}}
return Promise.all(pluginsRegistered);
}}
}}
const vp = document.getElementById("{id}");
vp.initializing.then(chart => {{
const lib = vp.Vizzu;
// story.set_size()
{chart_size}
// story.set_feature()
{chart_features}
// story.add_event()
{chart_events}
// story.add_plugin()
const plugins = [];
{chart_plugins}
Plugins.register(vp, chart, plugins).then(() => {{
// story.set_feature()
{chart_features}
// story.add_event()
{chart_events}
const vizzuPlayerData = {vizzu_player_data};
vp.slides = vizzuPlayerData;
const vizzuPlayerData = {vizzu_player_data};
vp.slides = vizzuPlayerData;
}});
}});
</script>
</div>
Expand Down
41 changes: 41 additions & 0 deletions tests/test_storylib.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def get_html(
chart_size="",
chart_features="",
chart_events="",
chart_plugins="",
) -> str:
# pylint: disable=too-many-arguments
return DISPLAY_TEMPLATE.format(
Expand All @@ -65,6 +66,7 @@ def get_html(
chart_size=chart_size,
chart_features=chart_features,
chart_events=chart_events,
chart_plugins=chart_plugins,
)


Expand Down Expand Up @@ -383,6 +385,45 @@ def test_to_html_with_event(self) -> None:
),
)

def test_to_html_with_plugins(self) -> None:
with unittest.mock.patch(
"ipyvizzustory.storylib.story.uuid.uuid4", return_value=self
):
story = self.get_story()

plugin1_url = "marker-dropshadow"
story.add_plugin(
plugin1_url, options={"debug": True}, name="MarkerDropshadow"
)
plugin1 = (
"plugins.push({"
+ f"plugin: '{plugin1_url}', "
+ 'options: {"debug": true}, '
+ "name: 'MarkerDropshadow'"
+ "})"
)

plugin2_url = (
"https://cdn.jsdelivr.net/npm/@vizzu/"
+ plugin1_url
+ "@vizzu-0.9/dist/mjs/index.min.js"
)
story.add_plugin(plugin2_url)
plugin2 = (
"plugins.push({"
+ f"plugin: '{plugin2_url}', "
+ "options: {}, "
+ "name: 'default'"
+ "})"
)

self.assertEqual(
story.to_html(),
self.get_html(
chart_plugins=f"\n{DISPLAY_INDENT * 3}".join([plugin1, plugin2])
),
)

def test_to_html_analytics(self) -> None:
with unittest.mock.patch(
"ipyvizzustory.storylib.story.uuid.uuid4", return_value=self
Expand Down

0 comments on commit 03aee42

Please sign in to comment.