Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java @ 9524:9dc6427059b2
Added more metadata to chart exports
author | gernotbelger |
---|---|
date | Mon, 01 Oct 2018 17:45:43 +0200 |
parents | 1cc7653ca84f |
children | ef5754ba5573 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.exports; import static org.dive4elements.river.exports.injector.InjectorConstants.CURRENT_KM; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Transparency; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.text.NumberFormat; import java.util.HashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import org.dive4elements.artifacts.CallContext; import org.dive4elements.artifacts.common.utils.XMLUtils; import org.dive4elements.river.java2d.NOPGraphics2D; import org.dive4elements.river.jfree.RiverAnnotation; import org.dive4elements.river.utils.Formatter; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.data.Range; import org.w3c.dom.Document; /** * Implementation of the OutGenerator interface for charts. * It should provide some basic things that equal in all chart types. * */ public abstract class ChartGenerator2 extends AbstractChartGenerator { private static final boolean USE_NOP_GRAPHICS = Boolean.getBoolean("info.rendering.nop.graphics"); /** Map of annotations to add at specific Y-axis. */ protected SortedMap<Integer, RiverAnnotation> yAnnotations = new TreeMap<>(); private Map<String, IdentifiableNumberAxis> axisNameToAxis = new HashMap<>(); public void addYAnnotation(RiverAnnotation annotation, int axisIndex) { yAnnotations.put(axisIndex, annotation); } @Override protected void doGenerate(final CallContext context, final OutputStream out, final String outName) throws IOException { log.debug("ChartGenerator2.generate"); if (outName.indexOf("chartinfo") > 0) generateInfo(context, out); else generateImage(context); } /** * Generate only meta infos */ private void generateInfo(final CallContext context, final OutputStream out) { log.debug("ChartInfoGenerator2.generateInfo"); JFreeChart chart = generateChart(context); int[] size = getSize(); if (size == null) { size = getDefaultSize(); } ChartRenderingInfo info = new ChartRenderingInfo(); long startTime = System.currentTimeMillis(); if (USE_NOP_GRAPHICS) { BufferedImage image = new BufferedImage(size[0], size[1], Transparency.BITMASK); Graphics2D g2d = image.createGraphics(); Graphics2D nop = new NOPGraphics2D(g2d); chart.draw( nop, new Rectangle2D.Double(0, 0, size[0], size[1]), null, info); nop.dispose(); } else { chart.createBufferedImage( size[0], size[1], Transparency.BITMASK, info); } long stopTime = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Rendering info took: " + (stopTime-startTime) + "ms"); } InfoGeneratorHelper2 helper = new InfoGeneratorHelper2(this); Document doc = helper.createInfoDocument(chart, info); XMLUtils.toStream(doc, out); } /** * Creates a new <i>ChartSection</i>. * * @return a new <i>ChartSection</i>. */ @Override protected ChartSection buildChartSection(final CallContext context) { ChartSection chartSection = new ChartSection(); chartSection.setTitle(getChartTitle(context)); chartSection.setSubtitle(getChartSubtitlePure(context)); chartSection.setDisplayGrid(isGridVisible()); chartSection.setDisplayLogo(showLogo()); chartSection.setLogoVPlacement(logoVPlace()); chartSection.setLogoHPlacement(logoHPlace()); return chartSection; } protected String interpolateVariables(final CallContext context, String s) { log.debug("Interpolate variables in string '" + s + "'"); Object radius = context.getContextValue("radius"); if (radius instanceof Double) { NumberFormat f = Formatter.getCSVFormatter(context); s = s.replace("$RADIUS", f.format(radius) + " km"); } else { s = s.replace("$RADIUS", "-"); } Object km = context.getContextValue(CURRENT_KM); if (km instanceof Number && s.contains("$KM")) { NumberFormat f = Formatter.getCalculationKm(context.getMeta()); s = s.replace("$KM", f.format(km)); } return s; } /** * Returns the subtitle of a chart. The return value depends on the * existence of ChartSettings: if there are ChartSettings set, this method * returns the chart title provided by those settings. Otherwise, this * method returns getDefaultChartSubtitle(). * @param context * * @return the subtitle of a chart. */ protected String getChartSubtitlePure(CallContext context) { ChartSettings chartSettings = getChartSettings(); String subTitle = chartSettings != null ? getChartSubtitle(chartSettings) : getDefaultChartSubtitle(context); String defSubTitle = getDefaultChartSubtitle(context); if (subTitle == null) { subTitle = defSubTitle != null ? defSubTitle : ""; } return subTitle; } @Override protected String getChartSubtitle(CallContext context) { return interpolateVariables(context, getChartSubtitlePure(context)); } /** * Glue between axis names and index. */ protected abstract String axisIndexToName(int index); /** * This method returns the font size for an Y axis. If the font size is * specified in ChartSettings (if <i>chartSettings</i> is set), this size is * returned. Otherwise the default font size 12 is returned. * * @return the font size for the x axis. */ protected int getYAxisFontSize(int index) { ChartSettings chartSettings = getChartSettings(); if (chartSettings == null) { return DEFAULT_FONT_SIZE; } AxisSection as = chartSettings.getAxisSection(axisIndexToName(index)); if (as == null) { return DEFAULT_FONT_SIZE; } Integer fontSize = as.getFontSize(); return fontSize != null ? fontSize : DEFAULT_FONT_SIZE; } protected abstract String getYAxisLabel(String axisName); /** * This method searches for a specific axis in the <i>settings</i> if * <i>settings</i> is set. If the axis was found, this method returns the * specified axis range if the axis range is fixed. Otherwise, this method * returns null. * * @param axisId The identifier of an axis. * * @return the specified axis range from <i>settings</i> if the axis is * fixed, otherwise null. */ public Range getRangeForAxisFromSettings(String axisId) { ChartSettings chartSettings = getChartSettings(); if (chartSettings == null) { return null; } AxisSection as = chartSettings.getAxisSection(axisId); if (as == null) { return null; } if (as.isFixed()) { Double upper = as.getUpperRange(); Double lower = as.getLowerRange(); if (upper != null && lower != null) { return lower < upper ? new Range(lower, upper) : new Range(upper, lower); } } return null; } /** * Creates a new instance of <i>IdentifiableNumberAxis</i>. * * @param idx The index of the new axis. * @param label The label of the new axis. * * @return an instance of IdentifiableNumberAxis. */ protected final NumberAxis createNumberAxis(int idx, String label) { return new IdentifiableNumberAxis(axisIndexToName(idx), label); } /** * Create Y (range) axis for given index. * Shall be overriden by subclasses. */ @Override protected NumberAxis createYAxis(int index) { Font labelFont = new Font( DEFAULT_FONT_NAME, Font.BOLD, getYAxisFontSize(index)); String axisName = axisIndexToName(index); IdentifiableNumberAxis axis = new IdentifiableNumberAxis(axisName, getYAxisLabel(axisName)); axis.setAutoRangeIncludesZero(false); axis.setLabelFont(labelFont); axis.setTickLabelFont(labelFont); // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. axis.setLowerMargin(0); axis.setUpperMargin(0); /* remember axis for lookup */ axisNameToAxis.put( axisName, axis ); return axis; } public final IdentifiableNumberAxis getAxis(final String axisName) { return axisNameToAxis.get(axisName); } /** Returns the number of registered y-axes */ public final int getNumYAxes() { return axisNameToAxis.size(); } protected final void addYAnnotationsToRenderer(final XYPlot plot) { final AnnotationRenderer annotationRenderer = new AnnotationRenderer(getChartSettings(), getDatasets(), DEFAULT_FONT_NAME); annotationRenderer.addYAnnotationsToRenderer(plot, this.yAnnotations); } }