Skip to content

Commit 560d32c

Browse files
committed
Merge branch 'main' of https://github.com/vizzuhq/vizzu-lib into main
2 parents 9b185f6 + 66d6802 commit 560d32c

File tree

12 files changed

+311
-83
lines changed

12 files changed

+311
-83
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ You can find information about how to work on the project in the following guide
88

99
* [Building the project](project/build.md)
1010
* [Testing the project](test/test.md)
11+
* [Generating documentation](docs/build.md)
1112

1213
Feel free to fork the project and send us a pull request. Any contribution you make is greatly appreciated.
1314

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414

1515
Vizzu is a free, open-source Javascript/C++ library utilizing a generic dataviz engine
1616
that generates many types of charts and seamlessly animates between them.
17-
It is designed for building animated data stories and interactive explorers
18-
as Vizzu enables showing different perspectives of the data that the viewers can
17+
It can be used to create static charts but more importantly it is designed for building animated data stories
18+
and interactive explorers as Vizzu enables showing different perspectives of the data that the viewers can
1919
easily follow due to the animation.
2020

2121
Main features:
2222
- Designed with animation in focus;
2323
- Defaults based on data visualization guidelines;
24-
- Automatic data aggregation, data filtering;
24+
- Automatic data aggregation & data filtering;
2525
- HTML5 canvas rendering;
2626
- Written in C++ compiled to WebAssembly;
2727
- Dependency-free.
@@ -90,7 +90,9 @@ We welcome contributions to the project, visit our [Contributing](CONTRIBUTING.m
9090

9191
# Contact
9292

93-
Our Slack workspace: [vizzu-community.slack.com](https://join.slack.com/t/vizzu-community/shared_invite/zt-w2nqhq44-2CCWL4o7qn2Ns1EFSf9kEg)
93+
* Join our Slack: [vizzu-community.slack.com](https://join.slack.com/t/vizzu-community/shared_invite/zt-w2nqhq44-2CCWL4o7qn2Ns1EFSf9kEg)
94+
* Drop us a line at [email protected]
95+
* Follow us on twitter: [https://twitter.com/VizzuHQ](https://twitter.com/VizzuHQ)
9496

9597
# License
9698

docs/build.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Building the Documentation Site
2+
3+
In vizzu-lib repo:
4+
5+
* Generate static thumbnails using integration test runner
6+
7+
cd <repo>/test/integration
8+
node vizzutest.js test_cases/web_content/sample_static/*/*
9+
10+
* Generate video thumbnails
11+
12+
cd <repo>/test/integration/modules/videorecorder
13+
node generate.js ../../test_cases/web_content/templates/*
14+
rm -rf resized # remove output folder from previous run
15+
node resize.js
16+
17+
* Generate reference doc
18+
19+
cd <repo>/tools/refgen
20+
node typedoc --out ../../docs/reference ../../src/apps/weblib/js-api/vizzu.d.ts
21+
22+
* Generate documentation site
23+
24+
cd <repo>/docs/generator
25+
node gendoc.js
26+
27+
# Publishing the Documentation Site
28+
29+
In vizzu-lib-doc repo:
30+
31+
* Copy generated site
32+
33+
cd <repo>/docs/<version>
34+
cp -r <vizzu-lib>/docs/* .
35+
rm -rf generator
36+
git commit -a -m '<version>'
37+
git push
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Vizzu JS Library Reference
2+
3+
This is the API reference documentation of the Vizzu JS library.
4+
The intention of this documentation is to provide information about
5+
every details of the API for user with understanding of the basics of the
6+
Vizzu Library.
7+
8+
For a getting started introduction to the library please visit our
9+
[Tutorial](https://lib.vizzuhq.com/0.3.0).
10+
11+
## Library Overview
12+
13+
The main entry point of the library is the [Vizzu](classes/default.html) class,
14+
and it's most important method controlling the basic functionality of the
15+
library is the [animate()](classes/default.html#animate) method:
16+
17+
* [Vizzu](classes/default.html) class
18+
* [constructor()](classes/default.html#constructor)
19+
* [animate](classes/default.html#animate) ( [AnimTarget](interfaces/AnimTarget.html) , [Anim.Options](interfaces/Anim.Options.html) )
20+
21+
The animate() method's main parameter is the [AnimTarget](interfaces/AnimTarget.html)
22+
interface which contains the definition of the chart, the underlying data and the chart's styling:
23+
24+
* [AnimTarget](interfaces/AnimTarget.html)
25+
* [Data.Set](modules/Data.html#Set)
26+
* [Config.Chart](interfaces/Config.Chart.html)
27+
* [Config.Channels](interfaces/Config.Channels.html)
28+
* [Styles.Chart](interfaces/Styles.Chart.html)
29+
* [Styles.Plot](interfaces/Styles.Plot.html)
30+
* [Styles.Marker](interfaces/Styles.Marker.html)
31+
* [Styles.Axis](interfaces/Styles.Axis.html)
32+
* [Styles.Legend](interfaces/Styles.Legend.html)
33+
* [Styles.Title](interfaces/Styles.Title.html)
34+
* [Styles.Tooltip](interfaces/Styles.Tooltip.html)
35+
36+
37+
## Details:
38+
39+
You can find all interface declarations and types under these namespaces.
40+
41+
### Namespaces:
42+
43+
* [Data](modules/Data.html)
44+
* [Config](modules/Config.html)
45+
* [Style](modules/Styles.html)
46+
* [Anim](modules/Anim.html)
47+
* [Events](modules/Event.html)

docs/generator/example-list.js

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,60 +18,66 @@ const exampleList =
1818
{
1919
sample_static:
2020
{
21-
'cartesian/marimekko_rectangle_2dis_2con.mjs': { tags: [m(2), d(2), Co, Di, PW, Ra, r,] },
22-
'cartesian/stacked_mekko_rectangle_2dis_2con.mjs': { tags: [m(1), d(2), Co, Di, PW, Ra, r,] },
23-
'cartesian/scatterplot_circle_negative_2dis_3con.mjs': { tags: [m(3), d(2), Re, Di, N, c,] },
24-
'cartesian/stream_stacked_area_3dis_1con.mjs': { tags: [m(1), d(3), Co, PW, CT, De, OD, a,] },
25-
'cartesian/area_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, CT, De, N, OD, a,] },
26-
'cartesian/stacked_area_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, a,] },
27-
// 'cartesian/waterfall_rectangle_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r,] },
28-
'cartesian/column_grouped_rectangle_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, Ra, CT, De, N, OD, r,] },
29-
'cartesian/bar_rectangle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, Ra, CT, De, N, OD, r,] },
30-
'cartesian/line_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, CT, De, N, OD, l,] },
31-
'cartesian/scatterplot_circle_negative_1dis_2con.mjs': { tags: [m(2), d(1), Re, Di, N, c,] },
32-
'cartesian/dotplot_circle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Di, N, c,] },
33-
'cartesian/column_stacked_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Di, PW, Ra, r,] },
34-
'cartesian/line_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, CT, De, N, OD, l,] },
35-
'cartesian/column_stacked_rectangle_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, OD, r,] },
36-
'cartesian/histogram_rectangle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, Ra, CT, De, N, OD,] },
37-
'polar/donut_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), PW, Ra, r,] },
38-
'polar/radial_stacked_rectangle_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, r,] },
39-
'polar/radial_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Co, Ra, r,] },
40-
'polar/coxcomb_stacked_rectangle_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, OD, r,] },
41-
'polar/pie_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Co, PW, Ra, r,] },
42-
'without/treemap_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Co, PW, r,] },
43-
'without/bubble_circle_2dis_2con.mjs': { tags: [m(2), d(2), Co, PW, c,] },
44-
'without/bubble_circle_1dis_2con.mjs': { tags: [m(2), d(1), Co, PW, c,] },
45-
'without/treemap_rectangle_2dis_2con.mjs': { tags: [m(2), d(2), Co, PW, r,] },
21+
'cartesian/histogram_rectangle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, Ra, CT, De, N, OD, ] },
22+
'cartesian/column_grouped_rectangle_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, Ra, CT, De, N, OD, r, ] },
23+
'cartesian/waterfall_rectangle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, PW, CT, De, N, OD, r, ] },
24+
'cartesian/column_stacked_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Di, PW, Ra, r, ] },
25+
'cartesian/column_stacked_rectangle_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, OD, r, ] },
26+
'cartesian/bar_rectangle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, Ra, CT, De, N, OD, r, ] },
27+
'cartesian/stacked_mekko_rectangle_2dis_2con.mjs': { tags: [m(1), d(2), Co, Di, PW, Ra, r, ] },
28+
'cartesian/mekko_rectangle_1dis_2con.mjs': { tags: [m(2), d(1), Co, PW, ] },
29+
'cartesian/marimekko_rectangle_2dis_2con.mjs': { tags: [m(2), d(2), Co, Di, PW, Ra, r, ] },
30+
'polar/pie_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Co, PW, Ra, r, ] },
31+
'polar/donut_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), PW, Ra, r, ] },
32+
'polar/coxcomb_stacked_rectangle_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, OD, r, ] },
33+
'polar/radial_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Co, Ra, r, ] },
34+
'polar/radial_stacked_rectangle_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, r, ] },
35+
'without/treemap_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), Co, PW, r, ] },
36+
'without/treemap_rectangle_2dis_2con.mjs': { tags: [m(2), d(2), Co, PW, r, ] },
37+
'cartesian/line_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, CT, De, N, OD, l, ] },
38+
'cartesian/line_negative_2dis_1con.mjs': { tags: [m(1), d(2), Co, CT, De, N, OD, l, ] },
39+
'polar/spiderweb_line_1dis_1con.mjs': { tags: [m(1), d(1), Co, CT, N, OD, l, ] },
40+
'polar/NO_spiderweb_line_2dis_1con.mjs': { tags: [m(1), d(2), Co, CT, N, OD, l, ] },
41+
'cartesian/area_negative_1dis_1con.mjs': { tags: [m(1), d(1), Co, CT, De, N, OD, a, ] },
42+
'cartesian/stacked_area_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, a, ] },
43+
'cartesian/stream_stacked_area_3dis_1con.mjs': { tags: [m(1), d(3), Co, PW, CT, De, OD, a, ] },
44+
'cartesian/stream_stacked_area_3dis_1con.mjs': { tags: [m(1), d(3), Co, PW, CT, OD, a, ] },
45+
'cartesian/dotplot_circle_negative_1dis_1con.mjs': { tags: [m(1), d(1), Di, N, c, ] },
46+
'cartesian/scatterplot_circle_negative_1dis_2con.mjs': { tags: [m(2), d(1), Re, Di, N, c, ] },
47+
'cartesian/scatterplot_circle_negative_2dis_3con.mjs': { tags: [m(3), d(2), Re, Di, N, c, ] },
48+
'without/bubble_circle_1dis_2con.mjs': { tags: [m(2), d(1), Co, PW, c, ] },
49+
'without/bubble_circle_2dis_2con.mjs': { tags: [m(2), d(2), Co, PW, c, ] },
4650
},
4751
templates:
4852
{
49-
'composition_comparison_pie_coxcomb_column_2dis_2con.mjs': { tags: [m(2), d(2), Co, PW, Ra, r,] },
50-
'composition_comparison_waterfall_column_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, De, N, r,] },
51-
'composition_percentage_area_stream_3dis_1con.mjs': { tags: [m(1), d(2), Co, Di, PW, CT, OD, a,] },
52-
'composition_percentage_column_stream_3dis_1con.mjs': { tags: [m(1), d(2), Co, Di, PW, CT, OD, r,] },
53-
'distribution_relationship_dotplot_dotplot.mjs': { tags: [m(2), d(2), Re, Di, N, c,] },
54-
'drilldown_aggregate_line.mjs': { tags: [m(1), d(2), Co, PW, Ra, N, l,] },
55-
'merge_split_area_stream_3dis_1con.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, a,] },
56-
'merge_split_bar.mjs': { tags: [m(1), d(2), Co, PW, r,] },
57-
'merge_split_radial_stacked_rectangle_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, r,] },
58-
'orientation_dot_circle.mjs': { tags: [m(2), d(2), Di, CT, N, OD, c,] },
59-
'orientation_circle.mjs': { tags: [m(2), d(2), Re, Di, CT, N, OD, c,] },
60-
'orientation_marimekko_rectangle_2dis_2con.mjs': { tags: [m(2), d(2), Di, PW, r,] },
61-
'orientation_rectangle.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r,] },
62-
'pie_donut2_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), PW,] },
63-
'relationship_comparison_circle_2_bubble_plot.mjs': { tags: [m(2), d(2), Re, Co, Di, N, c,] },
64-
'relationship_total_bubble_plot_column.mjs': { tags: [m(2), d(2), Re, Di, CT, N, OD, r, c,] },
65-
'stack_group_area_line.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, N, OD, a, l,] },
66-
'stack_group_circle.mjs': { tags: [m(1), d(2), Co, PW, c,] },
67-
'stack_group_treemap.mjs': { tags: [m(1), d(2), Co, PW, r,] },
68-
'total_element_bubble_2_bar.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, r, c,] },
69-
'total_element_bubble_column.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, r, c,] },
70-
'total_time_area_bar.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r, a,] },
71-
'total_time_area_column.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r, a,] },
72-
'treemap_radial.mjs': { tags: [m(1), d(2), Co, PW,] },
73-
'zoom_area.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, a,] },
74-
'zoom_line.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, N, OD, l,] },
53+
'composition_comparison_pie_coxcomb_column_2dis_2con.mjs': { tags: [m(2), d(2), Co, PW, Ra, r, ] },
54+
'composition_comparison_waterfall_column_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, De, N, r, ] },
55+
'composition_percentage_area_stream_3dis_1con.mjs': { tags: [m(1), d(2), Co, Di, PW, CT, OD, a, ] },
56+
'composition_percentage_column_stream_3dis_1con.mjs': { tags: [m(1), d(2), Co, Di, PW, CT, OD, r, ] },
57+
'distribution_relationship_dotplot_dotplot.mjs': { tags: [m(2), d(2), Re, Di, N, c, ] },
58+
'drilldown_aggregate_line.mjs': { tags: [m(1), d(2), Co, PW, Ra, N, l, ] },
59+
'merge_split_area_stream_3dis_1con.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, a, ] },
60+
'total_element_bubble_2_bar.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, r, c, ] },
61+
'merge_split_bar.mjs': { tags: [m(1), d(2), Co, PW, r, ] },
62+
'merge_split_radial_stacked_rectangle_2dis_1con.mjs': { tags: [m(1), d(2), Co, PW, r, ] },
63+
'orientation_circle.mjs': { tags: [m(2), d(2), Re, Di, CT, N, OD, c, ] },
64+
'orientation_marimekko_rectangle_2dis_2con.mjs': { tags: [m(2), d(2), Di, PW, r, ] },
65+
'orientation_rectangle.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r, ] },
66+
'pie_donut2_rectangle_1dis_1con.mjs': { tags: [m(1), d(1), PW, ] },
67+
'relationship_comparison_circle_2_bubble_plot.mjs': { tags: [m(2), d(2), Re, Co, Di, N, c, ] },
68+
'relationship_total_bubble_plot_column.mjs': { tags: [m(2), d(2), Re, Di, CT, N, OD, r, c, ] },
69+
'stack_group_area_line.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, N, OD, a, l, ] },
70+
'stack_group_circle.mjs': { tags: [m(1), d(2), Co, PW, c, ] },
71+
'stack_group_treemap.mjs': { tags: [m(1), d(2), Co, PW, r, ] },
72+
'total_element_bubble_column.mjs': { tags: [m(1), d(2), Co, PW, CT, OD, r, c, ] },
73+
'total_time_area_bar.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r, a, ] },
74+
'total_time_area_column.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, r, a, ] },
75+
'treemap_radial.mjs': { tags: [m(1), d(2), Co, PW, ] },
76+
'orientation_dot_circle.mjs': { tags: [m(2), d(2), Di, CT, N, OD, c, ] },
77+
'zoom_area.mjs': { tags: [m(1), d(2), Co, PW, CT, N, OD, a, ] },
78+
'zoom_line.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, N, OD, l, ] },
79+
'composition_percentage_column_3dis_1con.mjs': { tags: [m(1), d(2), Co, PW, Ra, CT, OD, r, ] },
80+
'total_time_bar_line.mjs': { tags: [m(1), d(2), Co, Ra, CT, OD, r, l, ] },
7581
}
7682
};
7783

docs/generator/genroot.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
"use strict";
2+
3+
const fs = require('fs');
4+
const jsdom = require('jsdom');
5+
const marked = require('marked');
6+
const { JSDOM } = jsdom;
7+
8+
class Generator
9+
{
10+
constructor()
11+
{
12+
this.loadHTML().then(dom => {
13+
this.generate(dom);
14+
this.saveHTML(dom);
15+
});
16+
}
17+
18+
loadHTML()
19+
{
20+
return JSDOM.fromFile("index.root.in.html");
21+
}
22+
23+
generate(dom)
24+
{
25+
const readmeFile = '../../README.md';
26+
27+
marked.setOptions({
28+
highlight: function(code, lang) {
29+
const hljs = require('highlight.js');
30+
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
31+
return hljs.highlight(code, { language }).value;
32+
}
33+
});
34+
35+
let defaultRender = new marked.Renderer();
36+
37+
marked.use({
38+
renderer: {
39+
link: function (href, title, string) {
40+
if (!href.startsWith('http'))
41+
href = 'https://github.com/vizzuhq/vizzu-lib/blob/main/'+href;
42+
return defaultRender.link(href, title, string);
43+
}
44+
}
45+
});
46+
47+
let markedContent = fs.readFileSync(readmeFile, 'utf-8');
48+
let html = marked(markedContent);
49+
50+
let content = dom.window.document.getElementById('content');
51+
content.innerHTML = html;
52+
}
53+
54+
saveHTML(dom)
55+
{
56+
fs.writeFile('../../index.html', dom.serialize(), console.error);
57+
}
58+
}
59+
60+
let run = new Generator();

docs/generator/index.root.in.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset='utf-8'>
5+
<title>Vizzu Library</title>
6+
<link rel="icon" href="0.3.0/images/favicon.svg">
7+
<meta name='viewport' content='width=device-width, initial-scale=1'>
8+
<link rel='stylesheet' type='text/css' media='screen' href='docs/style/root.css'>
9+
<link rel='stylesheet' type='text/css' media='screen' href='docs/style/highlight.css'>
10+
</head>
11+
<body>
12+
<div id="content"></div>
13+
</body>
14+
</html>

docs/style/root.css

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
#content {
3+
font-family: Roboto;
4+
margin: auto;
5+
width: 100%;
6+
max-width: 800px;
7+
color: #666;
8+
font-weight: 400;
9+
font-size: 15px;
10+
line-height: 1.5em;
11+
}
12+
13+
h1 {
14+
padding-top: 2em;
15+
padding-left: 1.2em;
16+
color: #666;
17+
font-weight: 100;
18+
font-size: 25px;
19+
}
20+
21+
h2 {
22+
padding-top: 2em;
23+
padding-left: 1.5em;
24+
color: #666;
25+
font-weight: 100;
26+
font-size: 20px;
27+
}
28+
29+
p {
30+
color: #666;
31+
font-weight: 400;
32+
font-size: 15px;
33+
line-height: 1.5em;
34+
padding-top: .8em;
35+
padding-left: 2em;
36+
padding-right: 1em;
37+
}
38+
39+
pre {
40+
line-height: 1.35em;
41+
color: #666;
42+
font-weight: normal;
43+
font-size: 13px;
44+
padding-top: 5px;
45+
padding-bottom: 5px;
46+
padding-left: 3em;
47+
padding-right: 1em;
48+
}
49+
50+
a {
51+
color: #4171cd;
52+
text-decoration: none;
53+
}
54+
55+
a:hover {
56+
text-decoration: underline;
57+
}

src/base/anim/control.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ void Control::seekProgress(double value)
3838

3939
double Control::getProgress() const
4040
{
41-
return (double)position / (double)controlled.getDuration();
41+
auto duration = (double)controlled.getDuration();
42+
return duration == 0 ? 0 : (double)position / duration;
4243
}
4344

4445
void Control::seekTime(Duration pos)

0 commit comments

Comments
 (0)