ingo@359: package de.intevation.flys.exports;
ingo@359:
felix@2183: import java.util.ArrayList;
felix@2183: import java.util.List;
ingo@1690:
ingo@359: import org.apache.log4j.Logger;
ingo@359:
ingo@375: import org.jfree.chart.JFreeChart;
ingo@375: import org.jfree.chart.axis.NumberAxis;
felix@1719: import org.jfree.chart.title.TextTitle;
ingo@422: import org.jfree.chart.axis.ValueAxis;
ingo@375: import org.jfree.chart.plot.XYPlot;
ingo@369: import org.jfree.data.xy.XYSeries;
ingo@364:
ingo@359: import org.w3c.dom.Document;
ingo@359:
felix@2183: import org.jfree.chart.annotations.XYTextAnnotation;
felix@2183:
felix@1953: import de.intevation.artifactdatabase.state.ArtifactAndFacet;
ingo@695: import de.intevation.artifactdatabase.state.Facet;
ingo@695:
ingo@422: import de.intevation.flys.artifacts.FLYSArtifact;
sascha@706:
felix@2104: import de.intevation.flys.artifacts.model.AreaFacet;
ingo@696: import de.intevation.flys.artifacts.model.FacetTypes;
felix@1769: import de.intevation.flys.artifacts.model.WKms;
ingo@364: import de.intevation.flys.artifacts.model.WQKms;
ingo@364:
felix@2183: import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
ingo@1677: import de.intevation.flys.jfree.FLYSAnnotation;
ingo@2074: import de.intevation.flys.jfree.StyledAreaSeriesCollection;
ingo@2074: import de.intevation.flys.jfree.StyledXYSeries;
sascha@1688:
ingo@1667: import de.intevation.flys.utils.FLYSUtils;
sascha@1688: import de.intevation.flys.utils.DataUtil;
ingo@359:
felix@2175: import org.json.JSONArray;
felix@2175: import org.json.JSONException;
felix@1035:
felix@1035: /**
ingo@359: * An OutGenerator that generates discharge curves.
ingo@359: *
ingo@359: * @author Ingo Weinzierl
ingo@359: */
ingo@696: public class LongitudinalSectionGenerator
ingo@696: extends XYChartGenerator
ingo@696: implements FacetTypes
ingo@696: {
felix@1953: public enum YAXIS {
felix@1931: W(0),
felix@1931: Q(1),
felix@1931: D(2);
felix@1931: protected int idx;
felix@1931: private YAXIS(int c) {
felix@1931: idx = c;
felix@1931: }
felix@1931: }
felix@1931:
felix@1037: /** The logger that is used in this generator. */
ingo@359: private static Logger logger =
ingo@359: Logger.getLogger(LongitudinalSectionGenerator.class);
ingo@359:
felix@1700: /** Key to look up internationalized String for annotations label. */
felix@1041: public static final String I18N_ANNOTATIONS_LABEL =
felix@1041: "chart.longitudinal.annotations.label";
felix@1041:
felix@1701: /**
felix@1701: * Key to look up internationalized String for LongitudinalSection diagrams
felix@1701: * titles.
felix@1701: */
felix@1701: public static final String I18N_CHART_TITLE =
felix@1701: "chart.longitudinal.section.title";
felix@1701:
felix@1701: /**
felix@1701: * Key to look up internationalized String for LongitudinalSection diagrams
felix@1701: * subtitles.
felix@1701: */
felix@1701: public static final String I18N_CHART_SUBTITLE =
felix@1701: "chart.longitudinal.section.subtitle";
felix@1701:
raimund@2159: /**
raimund@2159: * Key to look up internationalized String for LongitudinalSection diagrams
raimund@2159: * short subtitles.
raimund@2159: */
raimund@2159: public static final String I18N_CHART_SHORT_SUBTITLE =
raimund@2159: "chart.longitudinal.section.shortsubtitle";
raimund@2159:
felix@1701: public static final String I18N_XAXIS_LABEL =
felix@1701: "chart.longitudinal.section.xaxis.label";
felix@1701:
felix@1701: public static final String I18N_YAXIS_LABEL =
felix@1701: "chart.longitudinal.section.yaxis.label";
felix@1701:
felix@1701: public static final String I18N_2YAXIS_LABEL =
felix@1701: "chart.longitudinal.section.yaxis.second.label";
felix@1701:
felix@1701: public static final String I18N_CHART_TITLE_DEFAULT = "W-L\u00e4ngsschnitt";
felix@1701: public static final String I18N_XAXIS_LABEL_DEFAULT = "km";
felix@1701: public static final String I18N_YAXIS_LABEL_DEFAULT = "W [NN + m]";
felix@1701: public static final String I18N_2YAXIS_LABEL_DEFAULT = "Q [m\u00b3/s]";
felix@1701:
felix@1953: public final static String I18N_WDIFF_YAXIS_LABEL =
felix@1953: "chart.w_differences.yaxis.label";
felix@1953:
felix@1953: public final static String I18N_WDIFF_YAXIS_LABEL_DEFAULT = "m";
felix@1953:
felix@1700: /** Whether or not the plot is inverted (left-right). */
sascha@745: protected boolean inverted;
sascha@745:
felix@1041:
ingo@359: public LongitudinalSectionGenerator() {
ingo@359: super();
ingo@369: }
ingo@369:
ingo@369:
ingo@2000: @Override
ingo@2000: protected YAxisWalker getYAxisWalker() {
ingo@2000: return new YAxisWalker() {
ingo@2000: @Override
ingo@2000: public int length() {
ingo@2000: return YAXIS.values().length;
ingo@2000: }
ingo@2000:
ingo@2000: @Override
ingo@2000: public String getId(int idx) {
ingo@2000: YAXIS[] yaxes = YAXIS.values();
ingo@2000: return yaxes[idx].toString();
ingo@2000: }
ingo@2000: };
ingo@2000: }
ingo@2000:
ingo@2000:
sascha@745: public boolean isInverted() {
sascha@745: return inverted;
sascha@745: }
sascha@745:
felix@1700:
sascha@745: public void setInverted(boolean inverted) {
sascha@745: this.inverted = inverted;
sascha@745: }
ingo@369:
felix@1700:
felix@1700: /**
ingo@2048: * Returns the default title for this chart.
ingo@2047: *
ingo@2048: * @return the default title for this chart.
felix@1700: */
ingo@2047: @Override
ingo@2048: public String getDefaultChartTitle() {
felix@1701: return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
felix@1700: }
felix@1700:
felix@1700:
ingo@2047: /**
ingo@2048: * Returns the default subtitle for this chart.
ingo@2047: *
ingo@2048: * @return the default subtitle for this chart.
ingo@2047: */
ingo@1989: @Override
ingo@2048: protected String getDefaultChartSubtitle() {
ingo@1989: double[] dist = getRange();
ingo@1989:
raimund@2154: Object[] args = null;
raimund@2154: if (dist == null) {
raimund@2154: args = new Object[] {getRiverName()};
raimund@2159: return msg(getChartShortSubtitleKey(), "", args);
raimund@2154: }
raimund@2159: args = new Object[] {
raimund@2159: getRiverName(),
raimund@2159: dist[0],
raimund@2159: dist[1]
raimund@2159: };
ingo@1989: return msg(getChartSubtitleKey(), "", args);
ingo@1989: }
ingo@1989:
ingo@1989:
felix@1700: /**
felix@1700: * Gets key to look up internationalized String for the charts subtitle.
felix@1700: * @return key to look up translated subtitle.
felix@1700: */
felix@1700: protected String getChartSubtitleKey() {
felix@1701: return I18N_CHART_SUBTITLE;
felix@1700: }
felix@1700:
felix@1700:
felix@1700: /**
raimund@2159: * Gets key to look up internationalized String for the charts short
raimund@2159: * subtitle.
raimund@2159: * @return key to look up translated subtitle.
raimund@2159: */
raimund@2159: protected String getChartShortSubtitleKey() {
raimund@2159: return I18N_CHART_SHORT_SUBTITLE;
raimund@2159: }
raimund@2159:
raimund@2159:
raimund@2159: /**
felix@1700: * Add (internationalized) subtitle to chart.
felix@1700: * @see getChartSubtitleKey
felix@1700: */
ingo@414: @Override
ingo@414: protected void addSubtitles(JFreeChart chart) {
ingo@1989: String subtitle = getChartSubtitle();
ingo@2048:
ingo@2048: if (subtitle != null && subtitle.length() > 0) {
ingo@2048: chart.addSubtitle(new TextTitle(subtitle));
ingo@2048: }
ingo@414: }
ingo@414:
ingo@414:
felix@1700: /**
felix@1700: * Get internationalized label for the x axis.
felix@1700: */
ingo@2051: @Override
ingo@2051: protected String getDefaultXAxisLabel() {
ingo@1667: FLYSArtifact flys = (FLYSArtifact) master;
ingo@1667:
ingo@1667: return msg(
felix@1701: I18N_XAXIS_LABEL,
felix@1701: I18N_XAXIS_LABEL_DEFAULT,
ingo@1667: new Object[] { FLYSUtils.getRiver(flys).getName() });
ingo@369: }
ingo@369:
ingo@369:
felix@1953: @Override
ingo@2051: protected String getDefaultYAxisLabel(int index) {
ingo@2051: String label = "default";
ingo@2051:
ingo@2051: if (index == YAXIS.W.idx) {
ingo@2051: label = getWAxisLabel();
ingo@2051: }
ingo@2051: else if (index == YAXIS.Q.idx) {
ingo@2051: label = msg(getQAxisLabelKey(), getQAxisDefaultLabel());
ingo@2051: }
ingo@2051: else if (index == YAXIS.D.idx) {
ingo@2051: label = msg(I18N_WDIFF_YAXIS_LABEL, I18N_WDIFF_YAXIS_LABEL_DEFAULT);
ingo@2051: }
ingo@2051:
ingo@2051: return label;
felix@1953: }
felix@1953:
ingo@2051:
felix@1700: /**
felix@1700: * Get internationalized label for the y axis.
felix@1700: */
felix@1953: protected String getWAxisLabel() {
ingo@1667: FLYSArtifact flys = (FLYSArtifact) master;
ingo@1667:
ingo@1673: String unit = FLYSUtils.getRiver(flys).getWstUnit().getName();
ingo@1667:
ingo@1667: return msg(
felix@1701: I18N_YAXIS_LABEL,
felix@1701: I18N_YAXIS_LABEL_DEFAULT,
ingo@1667: new Object[] { unit });
ingo@369: }
ingo@369:
ingo@369:
felix@1700: /**
felix@1931: * Create Axis for given index.
felix@1931: * @return axis with according internationalized label.
felix@1931: */
felix@1931: @Override
felix@1931: protected NumberAxis createYAxis(int index) {
ingo@2053: NumberAxis axis = super.createYAxis(index);
ingo@1991:
felix@1941: // "Q" Axis shall include 0.
felix@1941: if (index == YAXIS.Q.idx) {
felix@1941: axis.setAutoRangeIncludesZero(true);
felix@1941: }
felix@1941: else {
felix@1941: axis.setAutoRangeIncludesZero(false);
felix@1941: }
ingo@2053:
felix@1931: return axis;
felix@1931: }
felix@1931:
ingo@1991:
felix@1931: /**
felix@1700: * Get default value for the second Y-Axis' label (if no translation was
felix@1700: * found).
felix@1700: */
felix@1953: protected String getQAxisDefaultLabel() {
felix@1701: return I18N_2YAXIS_LABEL_DEFAULT;
felix@1700: }
felix@1700:
felix@1700:
felix@1700: /**
felix@1700: * Get key for internationalization of the second Y-Axis' label.
felix@1700: */
felix@1953: protected String getQAxisLabelKey() {
felix@1701: return I18N_2YAXIS_LABEL;
felix@1700: }
felix@1700:
felix@1700:
felix@1700: /**
felix@1931: * Trigger inversion.
felix@1700: */
felix@1700: @Override
ingo@375: protected void adjustAxes(XYPlot plot) {
ingo@375: super.adjustAxes(plot);
ingo@422: invertXAxis(plot.getDomainAxis());
ingo@422: }
ingo@422:
ingo@422:
ingo@422: /**
ingo@422: * This method inverts the x-axis based on the kilometer information of the
ingo@422: * selected river. If the head of the river is at kilometer 0, the axis is
ingo@422: * not inverted, otherwise it is.
ingo@422: *
ingo@422: * @param xaxis The domain axis.
ingo@422: */
ingo@422: protected void invertXAxis(ValueAxis xaxis) {
sascha@745: if (inverted) {
ingo@1692: logger.debug("X-Axis.setInverted(true)");
ingo@422: xaxis.setInverted(true);
ingo@422: }
ingo@359: }
ingo@359:
ingo@359:
felix@1769: /**
felix@1769: * Produce output.
felix@1769: * @param facet current facet.
felix@1769: * @param attr theme for facet
felix@1769: */
ingo@1684: public void doOut(
felix@1944: ArtifactAndFacet artifactAndFacet,
felix@1944: Document attr,
felix@1944: boolean visible
ingo@1684: ) {
felix@1944: String name = artifactAndFacet.getFacetName();
ingo@359:
ingo@695: logger.debug("LongitudinalSectionGenerator.doOut: " + name);
ingo@695:
ingo@695: if (name == null) {
ingo@369: logger.error("No facet name for doOut(). No output generated!");
ingo@369: return;
ingo@369: }
ingo@369:
felix@1944: Facet facet = artifactAndFacet.getFacet();
ingo@696:
felix@1944: if (facet == null) {
ingo@696: return;
ingo@369: }
ingo@696:
ingo@696: if (name.equals(LONGITUDINAL_W)) {
felix@1944: doWOut((WQKms) artifactAndFacet.getData(context), facet, attr, visible);
ingo@696: }
ingo@696: else if (name.equals(LONGITUDINAL_Q)) {
felix@1944: doQOut((WQKms) artifactAndFacet.getData(context), facet, attr, visible);
ingo@369: }
felix@1028: else if (name.equals(LONGITUDINAL_ANNOTATION)) {
felix@1944: doAnnotations((FLYSAnnotation) artifactAndFacet.getData(context),
felix@1861: facet, attr, visible);
felix@1028: }
felix@1861: else if (name.equals(STATIC_WKMS)
felix@1861: || name.equals(HEIGHTMARKS_POINTS)
felix@1861: || name.equals(STATIC_WQKMS)) {
felix@1944: doWOut((WKms) artifactAndFacet.getData(context), facet, attr, visible);
felix@1769: }
felix@2104: else if (name.equals(STATIC_WQKMS_W)) {
felix@2104: doWOut((WQKms) artifactAndFacet.getData(context), facet, attr, visible);
felix@2104: }
felix@2104: else if (name.equals(STATIC_WQKMS_Q)) {
felix@2104: doQOut((WQKms) artifactAndFacet.getData(context), facet, attr, visible);
felix@2104: }
felix@1769: else if (name.equals(W_DIFFERENCES)) {
felix@1769: doWDifferencesOut(
felix@1944: (WKms) artifactAndFacet.getData(context),
felix@1769: facet,
felix@1769: attr,
felix@1769: visible);
felix@1769: }
felix@2029: else if (FacetTypes.IS.AREA(name)) {
felix@2029: doArea(artifactAndFacet.getData(context),
felix@2029: artifactAndFacet.getFacetDescription(),
felix@2029: attr,
felix@2029: visible);
felix@2029:
felix@2029: }
felix@2175: else if (FacetTypes.MANUALPOINTS.equals(name)) {
felix@2175: doPoints(artifactAndFacet.getData(context),
felix@2175: artifactAndFacet.getFacetDescription(),
felix@2175: attr, visible);
felix@2175: }
ingo@369: else {
ingo@695: logger.warn("Unknown facet name: " + name);
ingo@369: return;
ingo@369: }
ingo@369: }
ingo@369:
ingo@369:
felix@1037: /**
ingo@369: * Process the output for W facets in a longitudinal section curve.
ingo@369: *
ingo@369: * @param wqkms An array of WQKms values.
ingo@1712: * @param facet The facet. This facet does NOT support any data objects. Use
ingo@1712: * FLYSArtifact.getNativeFacet() instead to retrieve a Facet which supports
ingo@1712: * data.
ingo@924: * @param theme The theme that contains styling information.
ingo@1712: * @param visible The visibility of the curve.
ingo@369: */
ingo@1712: protected void doWOut(
felix@1769: WKms wkms,
ingo@1712: Facet facet,
ingo@1712: Document theme,
ingo@1712: boolean visible
ingo@1712: ) {
ingo@369: logger.debug("LongitudinalSectionGenerator.doWOut");
ingo@359:
ingo@1712: XYSeries series = new StyledXYSeries(facet.getDescription(), theme);
ingo@369:
felix@1791: StyledSeriesBuilder.addPoints(series, wkms);
ingo@696:
felix@1931: addAxisSeries(series, YAXIS.W.idx, visible);
sascha@745:
felix@1769: if (wkms instanceof WQKms) {
felix@1769: if (needInvertAxis((WQKms) wkms)) {
felix@1769: setInverted(true);
felix@1769: }
felix@1769: }
felix@1769: }
felix@1769:
felix@1769:
felix@1769: /**
felix@1769: * Add items to dataseries which describes the differences.
felix@1769: */
felix@1769: protected void doWDifferencesOut(
felix@1769: WKms wkms,
felix@1769: Facet facet,
felix@1769: Document theme,
felix@1769: boolean visible
felix@1769: ) {
felix@1769: logger.debug("WDifferencesCurveGenerator.doWDifferencesOut");
felix@1769: if (wkms == null) {
felix@1769: logger.warn("No data to add to WDifferencesChart.");
felix@1769: return;
felix@1769: }
felix@1769:
felix@1769: XYSeries series = new StyledXYSeries(facet.getDescription(), theme);
felix@1769:
felix@1769: if (logger.isDebugEnabled()) {
felix@1769: if (wkms.size() > 0) {
felix@1769: logger.debug("Generate series: " + series.getKey());
felix@1769: logger.debug("Start km: " + wkms.getKm(0));
felix@1791: logger.debug("End km: " + wkms.getKm(wkms.size() - 1));
felix@1791: logger.debug("Values : " + wkms.size());
felix@1769: }
felix@1769: }
felix@1769:
felix@1791: StyledSeriesBuilder.addPoints(series, wkms);
felix@1769:
felix@1931: addAxisSeries(series, YAXIS.D.idx, visible);
felix@1769: if (DataUtil.guessWaterIncreasing(wkms.allWs())) {
sascha@745: setInverted(true);
sascha@745: }
ingo@369: }
ingo@369:
ingo@369:
felix@1769:
ingo@369: /**
ingo@369: * Process the output for Q facets in a longitudinal section curve.
ingo@369: *
ingo@369: * @param wqkms An array of WQKms values.
ingo@1712: * @param facet The facet. This facet does NOT support any data objects. Use
ingo@1712: * FLYSArtifact.getNativeFacet() instead to retrieve a Facet which supports
ingo@1712: * data.
ingo@924: * @param theme The theme that contains styling information.
ingo@1712: * @param visible The visibility of the curve.
ingo@369: */
ingo@1712: protected void doQOut(
ingo@1712: WQKms wqkms,
ingo@1712: Facet facet,
ingo@1712: Document theme,
ingo@1712: boolean visible
ingo@1712: ) {
ingo@369: logger.debug("LongitudinalSectionGenerator.doQOut");
ingo@369:
ingo@1712: XYSeries series = new StyledXYSeries(facet.getDescription(), theme);
ingo@369:
felix@1936: StyledSeriesBuilder.addPointsKmQ(series, wqkms);
ingo@696:
felix@1931: addAxisSeries(series, YAXIS.Q.idx, visible);
sascha@745:
ingo@1692: if (needInvertAxis(wqkms)) {
ingo@1692: setInverted(true);
ingo@1692: }
ingo@1692: }
ingo@1692:
ingo@1692:
ingo@1692: /**
ingo@1692: * This method determines - taking JFreeCharts auto x value ordering into
ingo@1692: * account - if the x axis need to be inverted. Waterlines in these charts
ingo@1692: * should decrease.
ingo@1692: *
ingo@1692: * @param wqkms The data object that stores the x and y values used for this
ingo@1692: * chart.
ingo@1692: */
ingo@1692: public boolean needInvertAxis(WQKms wqkms) {
ingo@1692: boolean wsUp = wqkms.guessWaterIncreasing();
ingo@1692: boolean kmUp = DataUtil.guessWaterIncreasing(wqkms.allKms());
ingo@1692: boolean inv = (wsUp && kmUp) || (!wsUp && !kmUp);
ingo@1692:
ingo@1692: int size = wqkms.size();
ingo@1692:
ingo@1692: if (logger.isDebugEnabled()) {
ingo@1692: logger.debug("Values : " + size);
ingo@1692: if (size > 0) {
ingo@1692: logger.debug("Start km: " + wqkms.getKm(0));
ingo@1692: logger.debug("End km: " + wqkms.getKm(size-1));
ingo@1692: }
ingo@1692: logger.debug("wsUp: " + wsUp);
ingo@1692: logger.debug("kmUp: " + kmUp);
ingo@1692: logger.debug("inv: " + inv);
ingo@1692: }
ingo@1692:
ingo@1692: return inv;
ingo@369: }
ingo@369:
ingo@369:
felix@1041: /**
felix@1041: * Get name of series (displayed in legend).
felix@1041: * @return name of the series.
felix@1041: */
ingo@448: protected String getSeriesName(WQKms wqkms, String mode) {
ingo@448: String name = wqkms.getName();
ingo@448: String prefix = name != null && name.indexOf(mode) >= 0 ? null : mode;
ingo@448:
ingo@448: return prefix != null && prefix.length() > 0
ingo@448: ? prefix + "(" + name +")"
ingo@448: : name;
ingo@359: }
felix@2029:
felix@2029:
felix@2104: /** Look up the axis identifier for a given facet type. */
felix@2104: public int axisIdxForFacet(String facetName) {
felix@2104: if (FacetTypes.IS.W(facetName)) {
felix@2104: return YAXIS.W.idx;
felix@2104: }
felix@2104: else if (FacetTypes.IS.Q(facetName)) {
felix@2104: return YAXIS.Q.idx;
felix@2104: }
felix@2104: else {
felix@2104: logger.warn("Could not find axis for facet " + facetName);
felix@2104: return YAXIS.W.idx;
felix@2104: }
felix@2104: }
felix@2104:
felix@2175:
felix@2029: /**
felix@2029: * Do Area out.
felix@2029: */
felix@2029: protected void doArea(
felix@2029: Object o,
felix@2029: String seriesName,
felix@2029: Document theme,
felix@2029: boolean visible
felix@2029: ) {
felix@2029: logger.debug("LongitudinalSectionGenerator.doArea");
felix@2029: StyledAreaSeriesCollection area = new StyledAreaSeriesCollection(theme);
felix@2029:
felix@2104: AreaFacet.Data data = (AreaFacet.Data) o;
felix@2104:
felix@2029: XYSeries up = null;
felix@2029: XYSeries down = null;
felix@2029:
felix@2104: if (data.getUpperData() != null) {
felix@2029: up = new StyledXYSeries(seriesName, false, theme);
felix@2104: if (data.getUpperData() instanceof WQKms) {
felix@2104: if (FacetTypes.IS.Q(data.getRootFacetName())) {
felix@2104: StyledSeriesBuilder.addPointsKmQ(up, (WQKms) data.getUpperData());
felix@2104: }
felix@2104: else {
felix@2104: StyledSeriesBuilder.addPoints(up, (WKms) data.getUpperData());
felix@2104: }
felix@2029: }
felix@2104: else if (data.getUpperData() instanceof double[][]) {
felix@2104: StyledSeriesBuilder.addPoints(up, (double [][]) data.getUpperData());
felix@2029: }
felix@2029: else {
felix@2029: logger.error("Do not know how to deal with (up) area info from: "
felix@2104: + data.getUpperData());
felix@2029: }
felix@2029: }
felix@2029:
felix@2104: if (data.getLowerData() != null) {
felix@2029: // TODO: Sort this out: when the two series have the same name,
felix@2029: // the renderer (or anything in between) will not work correctly.
felix@2029: down = new StyledXYSeries(seriesName + " ", false, theme);
felix@2104: if (data.getLowerData() instanceof WQKms) {
felix@2104: if (FacetTypes.IS.Q(data.getRootFacetName())) {
felix@2104: StyledSeriesBuilder.addPointsKmQ(down, (WQKms) data.getLowerData());
felix@2104: }
felix@2104: else {
felix@2104: StyledSeriesBuilder.addPoints(down, (WQKms) data.getLowerData());
felix@2104: }
felix@2029: }
felix@2104: else if (data.getLowerData() instanceof double[][]) {
felix@2104: StyledSeriesBuilder.addPoints(down, (double[][]) data.getLowerData());
felix@2029: }
felix@2029: else {
felix@2029: logger.error("Do not know how to deal with (down) area info from: "
felix@2104: + data.getLowerData());
felix@2029: }
felix@2029: }
felix@2029:
felix@2029: if (up == null && down != null) {
felix@2029: area.setMode(StyledAreaSeriesCollection.FILL_MODE.ABOVE);
felix@2029: down.setKey(seriesName);
felix@2029: area.addSeries(down);
felix@2029: }
felix@2029: else if (up != null && down == null) {
felix@2029: area.setMode(StyledAreaSeriesCollection.FILL_MODE.UNDER);
felix@2029: area.addSeries(up);
felix@2029: }
felix@2029: else if (up != null && down != null) {
felix@2104: if (data.doPaintBetween()) {
felix@2104: area.setMode(StyledAreaSeriesCollection.FILL_MODE.BETWEEN);
felix@2104: }
felix@2104: else {
felix@2104: area.setMode(StyledAreaSeriesCollection.FILL_MODE.ABOVE);
felix@2104: }
felix@2029: area.addSeries(up);
felix@2029: area.addSeries(down);
felix@2029: }
felix@2104: // Add area to the respective axis.
felix@2104: addAreaSeries(area, axisIdxForFacet(data.getRootFacetName()), visible);
felix@2029: }
felix@2175:
felix@2175:
felix@2175: /**
felix@2175: * Do Points out.
felix@2175: */
felix@2175: protected void doPoints(
felix@2175: Object o,
felix@2175: String seriesName,
felix@2175: Document theme,
felix@2175: boolean visible
felix@2175: ) {
felix@2175: XYSeries series = new StyledXYSeries(seriesName, theme);
felix@2175:
felix@2183: // Add text annotations for single points.
felix@2183: List xy = new ArrayList();
felix@2183:
felix@2175: try {
felix@2175: JSONArray points = new JSONArray((String) o);
felix@2175: for (int i = 0; i < points.length(); i++) {
felix@2175: JSONArray array = points.getJSONArray(i);
felix@2183: double x = array.getDouble(0);
felix@2183: double y = array.getDouble(1);
felix@2183: String name = array.getString(2);
felix@2175: //logger.debug(" x " + x + " y " + y );
felix@2175: series.add(x, y, false);
felix@2183: xy.add(new CollisionFreeXYTextAnnotation(name, x, y));
felix@2175: }
felix@2175: }
felix@2175: catch(JSONException e){
felix@2175: logger.error("Could not decode json.");
felix@2175: }
felix@2183:
felix@2183: FLYSAnnotation annotations = new FLYSAnnotation(seriesName, null, null, theme);
felix@2183: annotations.setTextAnnotations(xy);
felix@2175:
felix@2183: doAnnotations(annotations, null, theme, visible);
felix@2175: addAxisSeries(series, YAXIS.W.idx, visible);
felix@2175: }
ingo@359: }
ingo@359: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :