Search in sources :

Example 1 with XYStyler

use of org.knowm.xchart.style.XYStyler in project openhab-core by openhab.

the class DefaultChartProvider method createChart.

@Override
public BufferedImage createChart(@Nullable String serviceId, @Nullable String theme, ZonedDateTime startTime, ZonedDateTime endTime, int height, int width, @Nullable String items, @Nullable String groups, @Nullable Integer dpiValue, @Nullable String yAxisDecimalPattern, @Nullable Boolean legend) throws ItemNotFoundException, IllegalArgumentException {
    logger.debug("Rendering chart: service: '{}', theme: '{}', startTime: '{}', endTime: '{}', width: '{}', height: '{}', items: '{}', groups: '{}', dpi: '{}', yAxisDecimalPattern: '{}', legend: '{}'", serviceId, theme, startTime, endTime, width, height, items, groups, dpiValue, yAxisDecimalPattern, legend);
    // If a persistence service is specified, find the provider, or use the default provider
    PersistenceService service = (serviceId == null) ? persistenceServiceRegistry.getDefault() : persistenceServiceRegistry.get(serviceId);
    // Did we find a service?
    QueryablePersistenceService persistenceService = (service instanceof QueryablePersistenceService) ? (QueryablePersistenceService) service : (QueryablePersistenceService) // 
    persistenceServiceRegistry.getAll().stream().filter(// 
    it -> it instanceof QueryablePersistenceService).findFirst().orElseThrow(() -> new IllegalArgumentException("No Persistence service found."));
    int seriesCounter = 0;
    // get theme
    ChartTheme chartTheme = theme == null ? CHART_THEME_DEFAULT : CHART_THEMES.getOrDefault(theme, CHART_THEME_DEFAULT);
    // get DPI
    int dpi = dpiValue != null && dpiValue > 0 ? dpiValue : DPI_DEFAULT;
    // Create Chart
    XYChart chart = new XYChartBuilder().width(width).height(height).build();
    // Define the time axis - the defaults are not very nice
    Duration period = Duration.between(startTime, endTime);
    String pattern;
    if (period.compareTo(TEN_MINUTES) <= 0) {
        pattern = "mm:ss";
    } else if (period.compareTo(ONE_DAY) <= 0) {
        pattern = "HH:mm";
    } else if (period.compareTo(ONE_WEEK) <= 0) {
        pattern = "EEE d";
    } else {
        pattern = "d MMM";
    }
    XYStyler styler = chart.getStyler();
    styler.setDatePattern(pattern);
    // axis
    styler.setAxisTickLabelsFont(chartTheme.getAxisTickLabelsFont(dpi));
    styler.setAxisTickLabelsColor(chartTheme.getAxisTickLabelsColor());
    styler.setXAxisMin((double) startTime.toInstant().toEpochMilli());
    styler.setXAxisMax((double) endTime.toInstant().toEpochMilli());
    int yAxisSpacing = Math.max(height / 10, chartTheme.getAxisTickLabelsFont(dpi).getSize());
    if (yAxisDecimalPattern != null) {
        styler.setYAxisDecimalPattern(yAxisDecimalPattern);
    }
    styler.setYAxisTickMarkSpacingHint(yAxisSpacing);
    styler.setYAxisLabelAlignment(Styler.TextAlignment.Right);
    // chart
    styler.setChartBackgroundColor(chartTheme.getChartBackgroundColor());
    styler.setChartFontColor(chartTheme.getChartFontColor());
    styler.setChartPadding(chartTheme.getChartPadding(dpi));
    styler.setPlotBackgroundColor(chartTheme.getPlotBackgroundColor());
    float plotGridLinesDash = (float) chartTheme.getPlotGridLinesDash(dpi);
    float[] plotGridLinesDashArray = { plotGridLinesDash, plotGridLinesDash };
    styler.setPlotGridLinesStroke(new BasicStroke((float) chartTheme.getPlotGridLinesWidth(dpi), BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10, plotGridLinesDashArray, 0));
    styler.setPlotGridLinesColor(chartTheme.getPlotGridLinesColor());
    // legend
    styler.setLegendBackgroundColor(chartTheme.getLegendBackgroundColor());
    styler.setLegendFont(chartTheme.getLegendFont(dpi));
    styler.setLegendSeriesLineLength(chartTheme.getLegendSeriesLineLength(dpi));
    LegendPositionDecider legendPositionDecider = new LegendPositionDecider();
    // Loop through all the items
    if (items != null) {
        String[] itemNames = items.split(",");
        for (String itemName : itemNames) {
            Item item = itemUIRegistry.getItem(itemName);
            if (addItem(chart, persistenceService, startTime, endTime, item, seriesCounter, chartTheme, dpi, legendPositionDecider)) {
                seriesCounter++;
            }
        }
    }
    // Loop through all the groups and add each item from each group
    if (groups != null) {
        String[] groupNames = groups.split(",");
        for (String groupName : groupNames) {
            Item item = itemUIRegistry.getItem(groupName);
            if (item instanceof GroupItem) {
                GroupItem groupItem = (GroupItem) item;
                for (Item member : groupItem.getMembers()) {
                    if (addItem(chart, persistenceService, startTime, endTime, member, seriesCounter, chartTheme, dpi, legendPositionDecider)) {
                        seriesCounter++;
                    }
                }
            } else {
                throw new ItemNotFoundException("Item '" + item.getName() + "' defined in groups is not a group.");
            }
        }
    }
    Boolean showLegend = null;
    // If there are no series, render a blank chart
    if (seriesCounter == 0) {
        // always hide the legend
        showLegend = false;
        List<Date> xData = new ArrayList<>();
        List<Number> yData = new ArrayList<>();
        xData.add(Date.from(startTime.toInstant()));
        yData.add(0);
        xData.add(Date.from(endTime.toInstant()));
        yData.add(0);
        XYSeries series = chart.addSeries("NONE", xData, yData);
        series.setMarker(new None());
        series.setLineStyle(new BasicStroke(0f));
    }
    // if the legend is not already hidden, check if legend parameter is supplied, or calculate a sensible value
    if (showLegend == null) {
        if (legend == null) {
            // more than one series, show the legend. otherwise hide it.
            showLegend = seriesCounter > 1;
        } else {
            // take value from supplied legend parameter
            showLegend = legend;
        }
    }
    // This won't be perfect, but it's a good compromise
    if (showLegend) {
        styler.setLegendPosition(legendPositionDecider.getLegendPosition());
    } else {
        // hide the whole legend
        styler.setLegendVisible(false);
    }
    // Write the chart as a PNG image
    BufferedImage lBufferedImage = new BufferedImage(chart.getWidth(), chart.getHeight(), BufferedImage.TYPE_INT_ARGB);
    Graphics2D lGraphics2D = lBufferedImage.createGraphics();
    chart.paint(lGraphics2D, chart.getWidth(), chart.getHeight());
    return lBufferedImage;
}
Also used : BasicStroke(java.awt.BasicStroke) XYSeries(org.knowm.xchart.XYSeries) ArrayList(java.util.ArrayList) BufferedImage(java.awt.image.BufferedImage) QueryablePersistenceService(org.openhab.core.persistence.QueryablePersistenceService) HistoricItem(org.openhab.core.persistence.HistoricItem) GroupItem(org.openhab.core.items.GroupItem) Item(org.openhab.core.items.Item) GroupItem(org.openhab.core.items.GroupItem) Duration(java.time.Duration) XYStyler(org.knowm.xchart.style.XYStyler) Date(java.util.Date) Graphics2D(java.awt.Graphics2D) QueryablePersistenceService(org.openhab.core.persistence.QueryablePersistenceService) PersistenceService(org.openhab.core.persistence.PersistenceService) XYChart(org.knowm.xchart.XYChart) XYChartBuilder(org.knowm.xchart.XYChartBuilder) None(org.knowm.xchart.style.markers.None) ItemNotFoundException(org.openhab.core.items.ItemNotFoundException)

Aggregations

BasicStroke (java.awt.BasicStroke)1 Graphics2D (java.awt.Graphics2D)1 BufferedImage (java.awt.image.BufferedImage)1 Duration (java.time.Duration)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 XYChart (org.knowm.xchart.XYChart)1 XYChartBuilder (org.knowm.xchart.XYChartBuilder)1 XYSeries (org.knowm.xchart.XYSeries)1 XYStyler (org.knowm.xchart.style.XYStyler)1 None (org.knowm.xchart.style.markers.None)1 GroupItem (org.openhab.core.items.GroupItem)1 Item (org.openhab.core.items.Item)1 ItemNotFoundException (org.openhab.core.items.ItemNotFoundException)1 HistoricItem (org.openhab.core.persistence.HistoricItem)1 PersistenceService (org.openhab.core.persistence.PersistenceService)1 QueryablePersistenceService (org.openhab.core.persistence.QueryablePersistenceService)1