Skip to content

Commit 806ecf5

Browse files
Changes from Feedback
Co-Authored-By: Johannes Rabauer <8188460+JohannesRabauer@users.noreply.github.com>
1 parent d1cd7fb commit 806ecf5

7 files changed

Lines changed: 157 additions & 105 deletions

File tree

README.md

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,35 @@
66

77
# <img src="https://www.chartjs.org/media/logo.svg" height="38" /> Chart.js Wrapper for Vaadin
88

9-
A Chart.js 4+ Wrapper for Vaadin
9+
A [Chart.js](https://www.chartjs.org/) 4+ Wrapper for Vaadin
1010

1111
![demo](assets/demo.png)
1212

1313
## Usage
1414

15-
0. You may want to use a Java model of Chart.js's configuration, like [XDEV's chartjs-java-model](https://github.com/xdev-software/chartjs-java-model).<br/>Otherwise you have to write the JSON yourself.
15+
For more and detailed usage examples please have a look at [the demo](./vaadin-chartjs-wrapper-demo/src/main/java/software/xdev/vaadin/chartjs/demo/).
16+
17+
### Minimal
18+
19+
```java
20+
// Assumes that this code is in some kind of Vaadin component
21+
22+
ChartContainer chart = new ChartContainer();
23+
this.add(chart);
24+
25+
chart.showChart(
26+
"{\"data\":{\"labels\":[\"A\",\"B\"],\"datasets\":[{\"data\":[1,2],\"label\":\"X\"}]},\"type\":\"bar\"}");
27+
```
28+
29+
### Recommended
30+
31+
Recommended actions:
32+
1. Use a Java model of Java model of Chart.js's configuration, like [XDEV's chartjs-java-model](https://github.com/xdev-software/chartjs-java-model).<br/>
33+
Otherwise you have to write the JSON yourself.
34+
2. Optionally derive classes for your charts (from e.g. ``ChartContainer``) that also handle the data-to-JSON conversion logic.<br/>
35+
Therefore you can encapsulate the components properly, for example like this: ``FetchFromBackendService.class → Model for chart → ChartContainer.class → Build JSON and show chart``
36+
37+
How the code could look:
1638
1. Define a custom chart or use the ``showChart``-method directly.<br/>Example:
1739
```java
1840
public class ExampleChartContainer extends ChartContainer
@@ -63,8 +85,6 @@ A Chart.js 4+ Wrapper for Vaadin
6385
}
6486
```
6587

66-
For more usage examples please have a look at [the demo](./vaadin-chartjs-wrapper-demo/src/main/java/software/xdev/vaadin/chartjs/demo/).
67-
6888
## Installation
6989
[Installation guide for the latest release](https://github.com/xdev-software/vaadin-chartjs-wrapper/releases/latest#Installation)
7090

vaadin-chartjs-wrapper-demo/src/main/java/software/xdev/vaadin/chartjs/DemoView.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.vaadin.flow.router.Route;
1515

1616
import software.xdev.vaadin.chartjs.demo.ClientToServerUpdateableDemo;
17+
import software.xdev.vaadin.chartjs.demo.FunctionalityShowcaseDemo;
1718
import software.xdev.vaadin.chartjs.demo.MinimalisticDemo;
1819

1920

@@ -53,7 +54,13 @@ protected void onAttach(final AttachEvent attachEvent)
5354
new Example(
5455
MinimalisticDemo.NAV,
5556
"Minimalistic",
56-
"Showcasing the simplest form of using ChartJS"
57+
"Showcasing the simplest form of using Chart.js"
58+
),
59+
new Example(
60+
FunctionalityShowcaseDemo.NAV,
61+
"Functionality showcase",
62+
"Showcases most functionality, including lazy-loaded data, displaying errors & problems "
63+
+ "and the dark mode 🌙"
5764
),
5865
new Example(
5966
ClientToServerUpdateableDemo.NAV,

vaadin-chartjs-wrapper-demo/src/main/java/software/xdev/vaadin/chartjs/demo/ClientToServerUpdateableDemo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static String buildChartPayload(final int value, final int max)
8686
.toJson();
8787
}
8888

89-
@SuppressWarnings("java:S110") // Not caused by us!
89+
@SuppressWarnings("java:S110")
9090
static class BrokenChartContainer extends ChartContainer
9191
{
9292
public BrokenChartContainer(final int value, final int max)
@@ -96,7 +96,7 @@ public BrokenChartContainer(final int value, final int max)
9696
}
9797

9898

99-
@SuppressWarnings("java:S110") // Not caused by us!
99+
@SuppressWarnings("java:S110")
100100
static class WorkingChartContainer extends ClientToServerUpdateableChartContainer
101101
{
102102
private final String payload;
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package software.xdev.vaadin.chartjs.demo;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
5+
import com.vaadin.flow.component.AttachEvent;
6+
import com.vaadin.flow.component.UI;
7+
import com.vaadin.flow.component.button.Button;
8+
import com.vaadin.flow.component.checkbox.Checkbox;
9+
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
10+
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
11+
import com.vaadin.flow.router.Route;
12+
import com.vaadin.flow.theme.lumo.Lumo;
13+
14+
import software.xdev.chartjs.model.charts.BarChart;
15+
import software.xdev.chartjs.model.data.BarData;
16+
import software.xdev.chartjs.model.dataset.BarDataset;
17+
import software.xdev.chartjs.model.options.BarOptions;
18+
import software.xdev.chartjs.model.options.Plugins;
19+
import software.xdev.chartjs.model.options.Title;
20+
import software.xdev.vaadin.chartjs.ChartContainer;
21+
import software.xdev.vaadin.chartjs.resources.js.src.ChartThemeManager;
22+
23+
24+
@Route(FunctionalityShowcaseDemo.NAV)
25+
public class FunctionalityShowcaseDemo extends VerticalLayout
26+
{
27+
public static final String NAV = "/functionality";
28+
29+
private final DummyChartContainer chart = new DummyChartContainer();
30+
31+
public FunctionalityShowcaseDemo()
32+
{
33+
this.setSizeFull();
34+
this.chart.setHeight("50%");
35+
36+
this.add(
37+
this.chart,
38+
new Button("Run dummy load", ev -> this.runDummyLoad()),
39+
new HorizontalLayout(
40+
new Button("Load", ev -> this.chart.showLoading()),
41+
new Button("Show data", ev -> this.chart.show()),
42+
new Button(
43+
"Show data with problem indicator", ev -> {
44+
this.chart.show();
45+
this.chart.showProblemsIndicator("Failed to load some data because ...");
46+
}),
47+
new Button("Error", ev -> this.chart.showFailed("Something went wrong"))
48+
),
49+
new Checkbox(
50+
"DarkMode (requires chart rebuild)", ev -> {
51+
this.getElement().executeJs(
52+
"document.documentElement.setAttribute('theme', $0)",
53+
Boolean.TRUE.equals(ev.getValue()) ? Lumo.DARK : Lumo.LIGHT);
54+
this.getElement().executeJs(ChartThemeManager.TRY_UPDATE_CHART_JS_THEMING.formatted(true));
55+
}));
56+
}
57+
58+
private void runDummyLoad()
59+
{
60+
this.chart.showLoading();
61+
62+
final UI ui = UI.getCurrent();
63+
CompletableFuture.runAsync(() -> {
64+
try
65+
{
66+
Thread.sleep(1000);
67+
}
68+
catch(final InterruptedException iex)
69+
{
70+
Thread.currentThread().interrupt();
71+
}
72+
ui.access(this.chart::show);
73+
});
74+
}
75+
76+
@Override
77+
protected void onAttach(final AttachEvent attachEvent)
78+
{
79+
this.runDummyLoad();
80+
}
81+
82+
@SuppressWarnings("java:S110")
83+
public static class DummyChartContainer extends ChartContainer
84+
{
85+
public void show()
86+
{
87+
this.showChart(new BarChart(new BarData()
88+
.addLabels("2020", "2021", "2022", "2023")
89+
.addDataset(new BarDataset()
90+
.setBackgroundColor("#c02222")
91+
.setLabel("Hans")
92+
.addData(1)
93+
.addData(2)
94+
.addData(3)
95+
.addData(4))
96+
.addDataset(new BarDataset()
97+
.setBackgroundColor("orange")
98+
.setLabel("Franz")
99+
.addData(2)
100+
.addData(3)
101+
.addData(4)
102+
.addData(5)))
103+
.setOptions(new BarOptions()
104+
.setResponsive(true)
105+
.setMaintainAspectRatio(false)
106+
.setPlugins(new Plugins()
107+
.setTitle(new Title()
108+
.setText("Age")
109+
.setDisplay(true))))
110+
.toJson());
111+
}
112+
}
113+
}
Lines changed: 5 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,25 @@
11
package software.xdev.vaadin.chartjs.demo;
22

3-
import java.util.concurrent.CompletableFuture;
4-
5-
import com.vaadin.flow.component.AttachEvent;
6-
import com.vaadin.flow.component.UI;
7-
import com.vaadin.flow.component.button.Button;
8-
import com.vaadin.flow.component.checkbox.Checkbox;
9-
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
103
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
114
import com.vaadin.flow.router.Route;
12-
import com.vaadin.flow.theme.lumo.Lumo;
135

14-
import software.xdev.chartjs.model.charts.BarChart;
15-
import software.xdev.chartjs.model.data.BarData;
16-
import software.xdev.chartjs.model.dataset.BarDataset;
17-
import software.xdev.chartjs.model.options.BarOptions;
18-
import software.xdev.chartjs.model.options.Plugins;
19-
import software.xdev.chartjs.model.options.Title;
206
import software.xdev.vaadin.chartjs.ChartContainer;
21-
import software.xdev.vaadin.chartjs.resources.js.src.ChartThemeManager;
227

238

249
@Route(MinimalisticDemo.NAV)
2510
public class MinimalisticDemo extends VerticalLayout
2611
{
2712
public static final String NAV = "/minimalistic";
2813

29-
private final DummyChartContainer chart = new DummyChartContainer();
30-
3114
public MinimalisticDemo()
3215
{
3316
this.setSizeFull();
34-
this.chart.setHeight("50%");
17+
final ChartContainer chart = new ChartContainer();
18+
chart.setHeight("50%");
3519

36-
this.add(
37-
this.chart,
38-
new Button("Run dummy load", ev -> this.runDummyLoad()),
39-
new HorizontalLayout(
40-
new Button("Load", ev -> this.chart.showLoading()),
41-
new Button("Show data", ev -> this.chart.show()),
42-
new Button(
43-
"Show data with problem indicator", ev -> {
44-
this.chart.show();
45-
this.chart.showProblemsIndicator("Failed to load some data because ...");
46-
}),
47-
new Button("Error", ev -> this.chart.showFailed("Something went wrong"))
48-
),
49-
new Checkbox(
50-
"DarkMode (requires chart rebuild)", ev -> {
51-
this.getElement().executeJs(
52-
"document.documentElement.setAttribute('theme', $0)",
53-
Boolean.TRUE.equals(ev.getValue()) ? Lumo.DARK : Lumo.LIGHT);
54-
this.getElement().executeJs(ChartThemeManager.TRY_UPDATE_CHART_JS_THEMING.formatted(true));
55-
}));
56-
}
57-
58-
private void runDummyLoad()
59-
{
60-
this.chart.showLoading();
20+
this.add(chart);
6121

62-
final UI ui = UI.getCurrent();
63-
CompletableFuture.runAsync(() -> {
64-
try
65-
{
66-
Thread.sleep(1000);
67-
}
68-
catch(final InterruptedException iex)
69-
{
70-
Thread.currentThread().interrupt();
71-
}
72-
ui.access(this.chart::show);
73-
});
74-
}
75-
76-
@Override
77-
protected void onAttach(final AttachEvent attachEvent)
78-
{
79-
this.runDummyLoad();
80-
}
81-
82-
@SuppressWarnings("java:S110") // Not caused by us!
83-
public static class DummyChartContainer extends ChartContainer
84-
{
85-
public void show()
86-
{
87-
this.showChart(new BarChart(new BarData()
88-
.addLabels("2020", "2021", "2022", "2023")
89-
.addDataset(new BarDataset()
90-
.setBackgroundColor("#c02222")
91-
.setLabel("Hans")
92-
.addData(1)
93-
.addData(2)
94-
.addData(3)
95-
.addData(4))
96-
.addDataset(new BarDataset()
97-
.setBackgroundColor("orange")
98-
.setLabel("Franz")
99-
.addData(2)
100-
.addData(3)
101-
.addData(4)
102-
.addData(5)))
103-
.setOptions(new BarOptions()
104-
.setResponsive(true)
105-
.setMaintainAspectRatio(false)
106-
.setPlugins(new Plugins()
107-
.setTitle(new Title()
108-
.setText("Age")
109-
.setDisplay(true))))
110-
.toJson());
111-
}
22+
chart.showChart(
23+
"{\"data\":{\"labels\":[\"A\",\"B\"],\"datasets\":[{\"data\":[1,2],\"label\":\"X\"}]},\"type\":\"bar\"}");
11224
}
11325
}

vaadin-chartjs-wrapper/src/main/java/software/xdev/vaadin/chartjs/ChartContainer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
@JsModule(ChartControlFunc.LOCATION)
4242
@CssImport(ChartContainerStyles.LOCATION)
4343
@SuppressWarnings("java:S1948") // UI classes will never be serialized due to security
44-
public abstract class ChartContainer extends Div implements ChartCom
44+
public class ChartContainer extends Div implements ChartCom
4545
{
4646
protected Component loading = new DefaultLoadingLoadComponent();
4747
protected Component error = new DefaultLoadingErrorComponent();
@@ -55,7 +55,7 @@ public abstract class ChartContainer extends Div implements ChartCom
5555
protected BiConsumer<ChartContainer, String> executeJsFunc =
5656
(self, js) -> self.getElement().executeJs(js);
5757

58-
protected ChartContainer()
58+
public ChartContainer()
5959
{
6060
this.loading.addClassName(ChartContainerStyles.LOADING_COMPONENT_CLASS);
6161
this.error.addClassName(ChartContainerStyles.ERROR_COMPONENT_CLASS);

vaadin-chartjs-wrapper/src/main/java/software/xdev/vaadin/chartjs/ClientToServerUpdateableChartContainer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@
2323

2424

2525
/**
26-
* Diagram that is updated by the client side when it becomes visible.
26+
* Diagram that is updated by the client/browser side when it becomes visible/added to the DOM.
2727
* <p>
28-
* This can be used in e.g. Grids with renderers where not every Chart might be rendered instantly
28+
* This can be used in e.g. Grids with renderers where not every Chart might be rendered instantly due to lazy loading.
2929
* </p>
3030
*
3131
* @implNote internal/original: TIMELINE-709/2020-09-01
3232
*/
3333
@JsModule(ChartClientToServerUpdater.LOCATION)
34-
@SuppressWarnings("java:S110") // Tell that to Vaadin, not me
34+
@SuppressWarnings("java:S110") // Caused by Vaadin design
3535
public abstract class ClientToServerUpdateableChartContainer extends ChartContainer
3636
{
3737
@ClientCallable

0 commit comments

Comments
 (0)