Skip to content

Commit 6c28fce

Browse files
committed
chart interpolation
Signed-off-by: Mark Herwege <[email protected]>
1 parent 91940ef commit 6c28fce

File tree

6 files changed

+47
-18
lines changed

6 files changed

+47
-18
lines changed

bundles/org.openhab.core.model.sitemap/src/org/openhab/core/model/sitemap/Sitemap.xtext

+2-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ Chart:
8686
('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
8787
('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
8888
('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')? &
89-
('yAxisDecimalPattern=' yAxisDecimalPattern=(STRING))?);
89+
('yAxisDecimalPattern=' yAxisDecimalPattern=(STRING))?&
90+
('interpolation=' interpolation=(STRING))?);
9091

9192
Webview:
9293
'Webview' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &

bundles/org.openhab.core.model.sitemap/src/org/openhab/core/model/sitemap/validation/SitemapValidator.xtend

+11
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils
3838
class SitemapValidator extends AbstractSitemapValidator {
3939

4040
val ALLOWED_HINTS = #["text", "number", "date", "time", "datetime"]
41+
val ALLOWED_INTERPOLATION = #["linear", "step"]
4142

4243
@Check
4344
def void checkFramesInFrame(Frame frame) {
@@ -161,4 +162,14 @@ class SitemapValidator extends AbstractSitemapValidator {
161162
SitemapPackage.Literals.INPUT.getEStructuralFeature(SitemapPackage.INPUT__INPUT_HINT))
162163
}
163164
}
165+
166+
@Check
167+
def void checkInterpolationParameter(Input i) {
168+
if (i.interpolation !== null && !ALLOWED_INTERPOLATION.contains(i.interpolation)) {
169+
val node = NodeModelUtils.getNode(i)
170+
val line = node.getStartLine()
171+
error("Input on item '" + i.item + "' has invalid interpolation '" + i.interpolation + "' at line " + line,
172+
SitemapPackage.Literals.INPUT.getEStructuralFeature(SitemapPackage.CHART__INTERPOLATION))
173+
}
174+
}
164175
}

bundles/org.openhab.core.ui/src/main/java/org/openhab/core/ui/chart/ChartProvider.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public interface ChartProvider {
5454
* @param items The items to display on the chart
5555
* @param groups The groups to display on the chart
5656
* @param dpi The DPI (dots per inch) value, can be <code>null</code>
57+
* @param interpolation The interpolation between two datapoint (<code>linear</code> or <code>step</code>),
58+
* <code>null</code> defaults to <code>linear</code>)
5759
* @param legend Show the legend? If <code>null</code>, the ChartProvider should make his own decision.
5860
* @return BufferedImage object if the chart is rendered correctly,
5961
* otherwise null.
@@ -62,7 +64,8 @@ public interface ChartProvider {
6264
*/
6365
BufferedImage createChart(@Nullable String service, @Nullable String theme, ZonedDateTime startTime,
6466
ZonedDateTime endTime, int height, int width, @Nullable String items, @Nullable String groups,
65-
@Nullable Integer dpi, @Nullable Boolean legend) throws ItemNotFoundException;
67+
@Nullable Integer dpi, @Nullable String interpolation, @Nullable Boolean legend)
68+
throws ItemNotFoundException;
6669

6770
/**
6871
* Creates a chart object. This sets the initial parameters for the chart
@@ -82,6 +85,8 @@ BufferedImage createChart(@Nullable String service, @Nullable String theme, Zone
8285
* @param groups The groups to display on the chart
8386
* @param dpi The DPI (dots per inch) value, can be <code>null</code>
8487
* @param yAxisDecimalPattern The format pattern for the y-axis labels
88+
* @param interpolation The interpolation between two datapoint (<code>linear</code> or <code>step</code>),
89+
* <code>null</code> defaults to <code>linear</code>)
8590
* @param legend Show the legend? If <code>null</code>, the ChartProvider should make his own decision.
8691
* @return BufferedImage object if the chart is rendered correctly,
8792
* otherwise null.
@@ -90,9 +95,10 @@ BufferedImage createChart(@Nullable String service, @Nullable String theme, Zone
9095
*/
9196
default BufferedImage createChart(@Nullable String service, @Nullable String theme, ZonedDateTime startTime,
9297
ZonedDateTime endTime, int height, int width, @Nullable String items, @Nullable String groups,
93-
@Nullable Integer dpi, @Nullable String yAxisDecimalPattern, @Nullable Boolean legend)
94-
throws ItemNotFoundException {
95-
return createChart(service, theme, startTime, endTime, height, width, items, groups, dpi, legend);
98+
@Nullable Integer dpi, @Nullable String yAxisDecimalPattern, @Nullable String interpolation,
99+
@Nullable Boolean legend) throws ItemNotFoundException {
100+
return createChart(service, theme, startTime, endTime, height, width, items, groups, dpi, interpolation,
101+
legend);
96102
}
97103

98104
/**

bundles/org.openhab.core.ui/src/main/java/org/openhab/core/ui/internal/chart/ChartServlet.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res) throws Ser
285285
}
286286

287287
String yAxisDecimalPattern = req.getParameter("yAxisDecimalPattern");
288+
String interpolation = req.getParameter("interpolation");
288289

289290
// Read out parameter 'legend'
290291
String legendParam = req.getParameter("legend");
@@ -305,7 +306,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse res) throws Ser
305306
try {
306307
BufferedImage chart = provider.createChart(serviceName, req.getParameter("theme"), beginEnd.begin(),
307308
beginEnd.end(), height, width, req.getParameter("items"), req.getParameter("groups"), dpi,
308-
yAxisDecimalPattern, legend);
309+
yAxisDecimalPattern, interpolation, legend);
309310
// Set the content type to that provided by the chart provider
310311
res.setContentType("image/" + provider.getChartType());
311312
try (ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(res.getOutputStream())) {

bundles/org.openhab.core.ui/src/main/java/org/openhab/core/ui/internal/chart/defaultchartprovider/DefaultChartProvider.java

+18-12
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ private LegendPosition getLegendPosition() {
106106

107107
private static final int DPI_DEFAULT = 96;
108108

109+
private static final String INTERPOLATION_LINEAR = "linear";
110+
private static final String INTERPOLATION_STEP = "step";
111+
109112
private final Logger logger = LoggerFactory.getLogger(DefaultChartProvider.class);
110113

111114
private final ItemUIRegistry itemUIRegistry;
@@ -130,20 +133,21 @@ public String getName() {
130133
@Override
131134
public BufferedImage createChart(@Nullable String serviceId, @Nullable String theme, ZonedDateTime startTime,
132135
ZonedDateTime endTime, int height, int width, @Nullable String items, @Nullable String groups,
133-
@Nullable Integer dpiValue, @Nullable Boolean legend)
136+
@Nullable Integer dpiValue, @Nullable String interpolation, @Nullable Boolean legend)
134137
throws ItemNotFoundException, IllegalArgumentException {
135-
return createChart(serviceId, theme, startTime, endTime, height, width, items, groups, dpiValue, null, legend);
138+
return createChart(serviceId, theme, startTime, endTime, height, width, items, groups, dpiValue, null,
139+
interpolation, legend);
136140
}
137141

138142
@Override
139143
public BufferedImage createChart(@Nullable String serviceId, @Nullable String theme, ZonedDateTime startTime,
140144
ZonedDateTime endTime, int height, int width, @Nullable String items, @Nullable String groups,
141-
@Nullable Integer dpiValue, @Nullable String yAxisDecimalPattern, @Nullable Boolean legend)
142-
throws ItemNotFoundException, IllegalArgumentException {
145+
@Nullable Integer dpiValue, @Nullable String yAxisDecimalPattern, @Nullable String interpolation,
146+
@Nullable Boolean legend) throws ItemNotFoundException, IllegalArgumentException {
143147
logger.debug(
144-
"Rendering chart: service: '{}', theme: '{}', startTime: '{}', endTime: '{}', width: '{}', height: '{}', items: '{}', groups: '{}', dpi: '{}', yAxisDecimalPattern: '{}', legend: '{}'",
148+
"Rendering chart: service: '{}', theme: '{}', startTime: '{}', endTime: '{}', width: '{}', height: '{}', items: '{}', groups: '{}', dpi: '{}', yAxisDecimalPattern: '{}', interpolation: '{}', legend: '{}'",
145149
serviceId, theme, startTime, endTime, width, height, items, groups, dpiValue, yAxisDecimalPattern,
146-
legend);
150+
interpolation, legend);
147151

148152
// If a persistence service is specified, find the provider, or use the default provider
149153
PersistenceService service = (serviceId == null) ? persistenceServiceRegistry.getDefault()
@@ -188,8 +192,8 @@ public BufferedImage createChart(@Nullable String serviceId, @Nullable String th
188192
// axis
189193
styler.setAxisTickLabelsFont(chartTheme.getAxisTickLabelsFont(dpi));
190194
styler.setAxisTickLabelsColor(chartTheme.getAxisTickLabelsColor());
191-
styler.setXAxisMin((double) startTime.toInstant().toEpochMilli());
192-
styler.setXAxisMax((double) endTime.toInstant().toEpochMilli());
195+
styler.setXAxisMin(startTime.toInstant().toEpochMilli());
196+
styler.setXAxisMax(endTime.toInstant().toEpochMilli());
193197
int yAxisSpacing = Math.max(height / 10, chartTheme.getAxisTickLabelsFont(dpi).getSize());
194198
if (yAxisDecimalPattern != null) {
195199
styler.setYAxisDecimalPattern(yAxisDecimalPattern);
@@ -219,7 +223,7 @@ public BufferedImage createChart(@Nullable String serviceId, @Nullable String th
219223
for (String itemName : itemNames) {
220224
Item item = itemUIRegistry.getItem(itemName);
221225
if (addItem(chart, persistenceService, startTime, endTime, item, seriesCounter, chartTheme, dpi,
222-
legendPositionDecider)) {
226+
interpolation, legendPositionDecider)) {
223227
seriesCounter++;
224228
}
225229
}
@@ -233,7 +237,7 @@ public BufferedImage createChart(@Nullable String serviceId, @Nullable String th
233237
if (item instanceof GroupItem groupItem) {
234238
for (Item member : groupItem.getMembers()) {
235239
if (addItem(chart, persistenceService, startTime, endTime, member, seriesCounter, chartTheme,
236-
dpi, legendPositionDecider)) {
240+
dpi, interpolation, legendPositionDecider)) {
237241
seriesCounter++;
238242
}
239243
}
@@ -307,7 +311,7 @@ private double convertData(State state) {
307311

308312
private boolean addItem(XYChart chart, QueryablePersistenceService service, ZonedDateTime timeBegin,
309313
ZonedDateTime timeEnd, Item item, int seriesCounter, ChartTheme chartTheme, int dpi,
310-
LegendPositionDecider legendPositionDecider) {
314+
@Nullable String interpolation, LegendPositionDecider legendPositionDecider) {
311315
Color color = chartTheme.getLineColor(seriesCounter);
312316

313317
// Get the item label
@@ -358,7 +362,9 @@ private boolean addItem(XYChart chart, QueryablePersistenceService service, Zone
358362
for (HistoricItem historicItem : result) {
359363
// For 'binary' states, we need to replicate the data
360364
// to avoid diagonal lines
361-
if (state instanceof OnOffType || state instanceof OpenClosedType) {
365+
if (state != null && INTERPOLATION_STEP.equals(interpolation)
366+
|| ((state instanceof OnOffType || state instanceof OpenClosedType)
367+
&& !INTERPOLATION_LINEAR.equals(interpolation))) {
362368
xData.add(Date.from(historicItem.getInstant().minus(1, ChronoUnit.MILLIS)));
363369
yData.add(convertData(state));
364370
}

bundles/org.openhab.core.ui/src/main/java/org/openhab/core/ui/internal/components/UIComponentSitemapProvider.java

+4
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ protected Sitemap buildSitemap(RootUIComponent rootComponent) {
220220
setWidgetPropertyFromComponentConfig(widget, component, "legend", SitemapPackage.CHART__LEGEND);
221221
setWidgetPropertyFromComponentConfig(widget, component, "forceAsItem",
222222
SitemapPackage.CHART__FORCE_AS_ITEM);
223+
setWidgetPropertyFromComponentConfig(widget, component, "yAxisDecimalPattern",
224+
SitemapPackage.CHART__YAXIS_DECIMAL_PATTERN);
225+
setWidgetPropertyFromComponentConfig(widget, component, "interpolation",
226+
SitemapPackage.CHART__INTERPOLATION);
223227
break;
224228
case "Webview":
225229
WebviewImpl webviewWidget = (WebviewImpl) SitemapFactory.eINSTANCE.createWebview();

0 commit comments

Comments
 (0)