Skip to content

Commit 02ce7fd

Browse files
authored
Merge pull request #7 from xdev-software/develop
Release
2 parents 56ba349 + fe669d2 commit 02ce7fd

File tree

4 files changed

+107
-67
lines changed

4 files changed

+107
-67
lines changed

README.md

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,64 @@
44
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_vaadin-chartjs-wrapper&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_vaadin-chartjs-wrapper)
55
![Vaadin 24+](https://img.shields.io/badge/Vaadin%20Platform/Flow-24+-00b4f0)
66

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

99
A Chart.js 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.
1516
1. Define a custom chart or use the ``showChart``-method directly.<br/>Example:
16-
17-
```java
18-
public class ExampleChartContainer extends ChartContainer
19-
{
20-
public void show(Data data)
17+
```java
18+
public class ExampleChartContainer extends ChartContainer
2119
{
22-
BarData data = ...; // Build the bar chart data from the handed over data
23-
this.showChart(new BarChart(data)
24-
.setOptions(new BarOptions()
25-
.setResponsive(true)
26-
.setMaintainAspectRatio(false)
27-
.setPlugins(new Plugins()
28-
.setTitle(new Title()
29-
.setText("Age")
30-
.setDisplay(true))))
31-
.toJson());
20+
public void show(Data data)
21+
{
22+
BarData data = ...; // Build the bar chart data from the handed over data
23+
this.showChart(new BarChart(data)
24+
.setOptions(new BarOptions()
25+
.setResponsive(true)
26+
.setMaintainAspectRatio(false)
27+
.setPlugins(new Plugins()
28+
.setTitle(new Title()
29+
.setText("Age")
30+
.setDisplay(true))))
31+
.toJson());
32+
}
3233
}
33-
}
34-
```
35-
34+
```
3635
2. Add the chart to your view/component:
37-
38-
```java
39-
public class ExampleView extends VerticalLayout
40-
{
41-
private final ExampleChartContainer chart = new ExampleChartContainer();
42-
43-
public ExampleView()
36+
```java
37+
public class ExampleView extends VerticalLayout
4438
{
45-
this.add(this.chart);
46-
// ...
47-
}
48-
49-
private void loadDataAndShowChart()
50-
{
51-
this.chart.showLoading();
39+
private final ExampleChartContainer chart = new ExampleChartContainer();
40+
41+
public ExampleView()
42+
{
43+
this.add(this.chart);
44+
// ...
45+
}
5246

53-
UI ui = UI.getCurrent();
54-
CompletableFuture.runAsync(() -> {
55-
try {
56-
var data = ...; // Load some data from the backend
57-
// You may also convert the data here and call showChart
58-
ui.access(() -> this.chart.show(data));
59-
} catch (Exception ex) {
60-
// Display the error message when loading fails
61-
ui.access(() -> this.chart.showFailed(ex.getMessage()));
62-
}
63-
});
64-
}
65-
}
66-
```
47+
private void loadDataAndShowChart()
48+
{
49+
this.chart.showLoading();
50+
51+
UI ui = UI.getCurrent();
52+
CompletableFuture.runAsync(() -> {
53+
try {
54+
var data = ...; // Load some data from the backend
55+
// You may also convert the data here and call showChart
56+
ui.access(() -> this.chart.show(data));
57+
} catch (Exception ex) {
58+
// Display the error message when loading fails
59+
ui.access(() -> this.chart.showFailed(ex.getMessage()));
60+
}
61+
});
62+
}
63+
}
64+
```
6765

6866
For more usage examples please have a look at [the demo](./vaadin-chartjs-wrapper-demo/src/main/java/software/xdev/vaadin/chartjs/demo/).
6967

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package software.xdev.vaadin.chartjs;
1717

18+
/**
19+
* Interface for communicating with charts.
20+
*/
1821
public interface ChartCom
1922
{
2023
void showLoading();

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

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
import java.util.Objects;
1919
import java.util.UUID;
20+
import java.util.function.BiConsumer;
21+
import java.util.function.BiFunction;
2022

2123
import com.vaadin.flow.component.Component;
2224
import com.vaadin.flow.component.dependency.CssImport;
2325
import com.vaadin.flow.component.dependency.JsModule;
2426
import com.vaadin.flow.component.html.Div;
25-
import com.vaadin.flow.component.icon.Icon;
2627
import com.vaadin.flow.component.icon.VaadinIcon;
2728
import com.vaadin.flow.component.shared.Tooltip;
2829
import com.vaadin.flow.theme.lumo.LumoUtility;
@@ -39,19 +40,26 @@
3940
@JsModule(ChartThemeManager.LOCATION)
4041
@JsModule(ChartControlFunc.LOCATION)
4142
@CssImport(ChartContainerStyles.LOCATION)
43+
@SuppressWarnings("java:S1948") // UI classes will never be serialized due to security
4244
public abstract class ChartContainer extends Div implements ChartCom
4345
{
4446
protected Component loading = new DefaultLoadingLoadComponent();
4547
protected Component error = new DefaultLoadingErrorComponent();
4648
protected Div chartJSDiv = new Div();
4749

48-
protected Icon icoProblemsIndicator = VaadinIcon.WARNING.create();
50+
protected Component problemsIndicator = VaadinIcon.WARNING.create();
51+
52+
protected BiConsumer<Component, String> problemsIndicatorToolTipFunc =
53+
(comp, msg) -> Tooltip.forComponent(comp).withText(msg);
54+
protected BiFunction<ChartContainer, String, String> wrapJsFunc = (self, js) -> js;
55+
protected BiConsumer<ChartContainer, String> executeJsFunc =
56+
(self, js) -> self.getElement().executeJs(js);
4957

5058
protected ChartContainer()
5159
{
5260
this.loading.addClassName(ChartContainerStyles.LOADING_COMPONENT_CLASS);
5361
this.error.addClassName(ChartContainerStyles.ERROR_COMPONENT_CLASS);
54-
this.icoProblemsIndicator.addClassName(ChartContainerStyles.PROBLEM_INDICATOR_CLASS);
62+
this.problemsIndicator.addClassName(ChartContainerStyles.PROBLEM_INDICATOR_CLASS);
5563

5664
this.chartJSDiv.addClassNames(
5765
ChartContainerStyles.DIV_CLASS,
@@ -67,7 +75,7 @@ protected ChartContainer()
6775

6876
protected String createChartJSDivId()
6977
{
70-
return "chartjsdiv" + UUID.randomUUID();
78+
return "chartjsdiv-" + UUID.randomUUID();
7179
}
7280

7381
public String getChartJSDivId()
@@ -115,9 +123,11 @@ protected void clear(final boolean forDisplayingChart)
115123

116124
public void showProblemsIndicator(final String problemsText)
117125
{
118-
this.add(this.icoProblemsIndicator);
119-
Tooltip.forComponent(this.icoProblemsIndicator)
120-
.withText(problemsText);
126+
this.add(this.problemsIndicator);
127+
if(this.problemsIndicatorToolTipFunc != null)
128+
{
129+
this.problemsIndicatorToolTipFunc.accept(this.problemsIndicator, problemsText);
130+
}
121131
}
122132

123133
public void showChart(final String payloadJson)
@@ -139,7 +149,7 @@ protected void tryDestroyChart()
139149

140150
protected void executeJS(final String js)
141151
{
142-
this.getElement().executeJs(js);
152+
this.executeJsFunc.accept(this, this.wrapJsFunc.apply(this, js));
143153
}
144154

145155
// region Getter + Setter
@@ -173,14 +183,45 @@ public void setChartJSDiv(final Div chartJSDiv)
173183
this.chartJSDiv = chartJSDiv;
174184
}
175185

176-
public Icon getIcoProblemsIndicator()
186+
public Component getProblemsIndicator()
187+
{
188+
return this.problemsIndicator;
189+
}
190+
191+
public void setProblemsIndicator(final Component problemsIndicator)
192+
{
193+
this.problemsIndicator = problemsIndicator;
194+
}
195+
196+
public BiConsumer<Component, String> getProblemsIndicatorToolTipFunc()
197+
{
198+
return this.problemsIndicatorToolTipFunc;
199+
}
200+
201+
public void setProblemsIndicatorToolTipFunc(final BiConsumer<Component, String> problemsIndicatorToolTipFunc)
202+
{
203+
this.problemsIndicatorToolTipFunc = problemsIndicatorToolTipFunc;
204+
}
205+
206+
public BiFunction<ChartContainer, String, String> getWrapJsFunc()
177207
{
178-
return this.icoProblemsIndicator;
208+
return this.wrapJsFunc;
179209
}
180210

181-
public void setIcoProblemsIndicator(final Icon icoProblemsIndicator)
211+
public void setWrapJsFunc(final BiFunction<ChartContainer, String, String> wrapJsFunc)
182212
{
183-
this.icoProblemsIndicator = icoProblemsIndicator;
213+
this.wrapJsFunc = Objects.requireNonNull(wrapJsFunc);
184214
}
215+
216+
public BiConsumer<ChartContainer, String> getExecuteJsFunc()
217+
{
218+
return this.executeJsFunc;
219+
}
220+
221+
public void setExecuteJsFunc(final BiConsumer<ChartContainer, String> executeJsFunc)
222+
{
223+
this.executeJsFunc = Objects.requireNonNull(executeJsFunc);
224+
}
225+
185226
// endregion
186227
}

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
* @implNote internal/original: TIMELINE-709/2020-09-01
3232
*/
3333
@JsModule(ChartClientToServerUpdater.LOCATION)
34+
@SuppressWarnings("java:S110") // Tell that to Vaadin, not me
3435
public abstract class ClientToServerUpdateableChartContainer extends ChartContainer
3536
{
3637
@ClientCallable
@@ -39,11 +40,6 @@ public void updateFromClient()
3940
this.update();
4041
}
4142

42-
protected String maybeWrapForErrorFeedback(final String js)
43-
{
44-
return js;
45-
}
46-
4743
/**
4844
* Tries to run a client-side update via a script-tag.
4945
* <p>
@@ -52,9 +48,11 @@ protected String maybeWrapForErrorFeedback(final String js)
5248
*/
5349
public ClientToServerUpdateableChartContainer scheduleUpdateViaScript()
5450
{
55-
final String js = this.maybeWrapForErrorFeedback(String.format(
56-
ChartClientToServerUpdater.CHECK_IF_EXISTS_ON_CLIENT_AND_UPDATE_SERVER,
57-
this.getChartJSDivId()));
51+
final String js = this.wrapJsFunc.apply(
52+
this,
53+
String.format(
54+
ChartClientToServerUpdater.CHECK_IF_EXISTS_ON_CLIENT_AND_UPDATE_SERVER,
55+
this.getChartJSDivId()));
5856

5957
final Element el = new Element("script");
6058
el.setAttribute("type", "text/javascript");

0 commit comments

Comments
 (0)