/* * This file is part of the OpenSCADA project * Copyright (C) 2006-2010 TH4 SYSTEMS GmbH (http://th4-systems.com) * * OpenSCADA is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenSCADA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenSCADA. If not, see * <http://opensource.org/licenses/lgpl-3.0.html> for a copy of the LGPLv3 License. */ package org.openscada.hd.ui.printing; import java.util.Calendar; import java.util.Map; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.printing.Printer; import org.openscada.hd.Value; import org.openscada.hd.ValueInformation; public class PrintProcessor { private final ValueInformation[] valueInformation; private final Map<String, Value[]> values; public PrintProcessor ( final ValueInformation[] vis, final Map<String, Value[]> values ) { this.valueInformation = vis; this.values = values; } public void print ( final Printer printer ) { // generate min/max for X double maxX = Double.NEGATIVE_INFINITY; double minX = Double.POSITIVE_INFINITY; for ( final Value[] vs : this.values.values () ) { for ( final Value v : vs ) { final double d = v.toDouble (); if ( d > maxX ) { maxX = d; } if ( d < minX ) { minX = d; } } } minX = 0; maxX = maxX * 1.5; // get min/max Y Calendar startTimestamp = null; Calendar endTimestamp = null; for ( final ValueInformation vi : this.valueInformation ) { if ( startTimestamp == null || startTimestamp.after ( vi.getStartTimestamp () ) ) { startTimestamp = vi.getStartTimestamp (); } if ( endTimestamp == null || endTimestamp.before ( vi.getEndTimestamp () ) ) { endTimestamp = vi.getEndTimestamp (); } } GC gc = null; try { printer.startJob ( "Chart" ); printer.startPage (); gc = new GC ( printer ); drawChart ( printer, gc, minX, maxX, startTimestamp, endTimestamp ); gc.dispose (); gc = null; printer.endPage (); printer.endJob (); } finally { if ( gc != null ) { gc.dispose (); } } } private void drawChart ( final Device device, final GC gc, final double minX, final double maxX, final Calendar startTimestamp, final Calendar endTimestamp ) { final Rectangle bounds = device.getBounds (); final Color color = new Color ( device, new RGB ( 0, 0, 0 ) ); final Rectangle drawBounds = new Rectangle ( bounds.x + 10, bounds.y + 10, bounds.width - 20, bounds.height - 20 ); gc.setForeground ( color ); gc.drawRectangle ( drawBounds ); for ( final Map.Entry<String, Value[]> row : this.values.entrySet () ) { drawRow ( device, gc, row.getKey (), row.getValue (), drawBounds, minX, maxX ); } } private void drawRow ( final Device device, final GC gc, final String label, final Value[] data, final Rectangle bounds, final double minX, final double maxX ) { final Rectangle deviceBounds = device.getBounds (); gc.setLineWidth ( 1 ); final int size = data.length; final double diff = maxX - minX; Point lastPoint = null; for ( int i = 0; i < size; i++ ) { // final Value v = data[i]; final ValueInformation info = this.valueInformation[i]; if ( info.getQuality () > 0.75 ) { final double posX = (double)bounds.width / (double)size * i; final double posY = data[i].toDouble () / diff * bounds.height; final Point point = new Point ( (int)posX + bounds.x, (int)posY + bounds.y ); if ( lastPoint != null ) { gc.drawLine ( lastPoint.x, deviceBounds.height - lastPoint.y, point.x, deviceBounds.height - lastPoint.y ); gc.drawLine ( point.x, deviceBounds.height - lastPoint.y, point.x, deviceBounds.height - point.y ); } lastPoint = point; } else { lastPoint = null; } } } }