/******************************************************************************* * Copyright (c) 2015, Daniel Ludin * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Daniel Ludin (ludin@hispeed.ch) - initial implementation *******************************************************************************/ package ch.gpb.elexis.cst.widget; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import ch.gpb.elexis.cst.data.ValuePairTimeline; import ch.gpb.elexis.cst.service.CstService; public class ValuePairTimelineCanvas extends Canvas { Font fontSmall; Font fontBig; Color ORANGE; Color BRIGHTGREEN; Color WHITE; Color GREY; Color BLACK; Color BLUE; int iPixX = 700; // Anzeigebreite in pix int iPixY = 120; // Anzeigeh�he in pix int xoffBase = 4; // x offset int yoffBase = 140; // y offset //int werteBereich = 500; // Wertebereich der in iPixY/X angezeigt werden soll int werteBereich = 1200; // Wertebereich der in iPixY/X angezeigt werden soll String einheit = new String(); String befundArt = new String(); List<ValuePairTimeline> findings = new ArrayList<ValuePairTimeline>(); double valueRangeOfInput; double distBetweenLines; double nrOfScaleLines; int scaleStepWidth = 0; public ValuePairTimelineCanvas(Composite parent, int style, String befundArt, String einheit) { super(parent, style); this.befundArt = befundArt; this.einheit = einheit; WHITE = new Color(null, 255, 255, 255); ORANGE = new Color(getDisplay(), 255, 104, 0); BRIGHTGREEN = new Color(getDisplay(), 104, 255, 0); BLACK = new Color(getDisplay(), 0, 0, 0); GREY = new Color(getDisplay(), 200, 200, 200); BLUE = new Color(getDisplay(), 30, 30, 255); fontSmall = createFontofSize(7); fontBig = createFontofSize(12); setBackground(WHITE); setSize(440, 500); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { WHITE.dispose(); BLACK.dispose(); ORANGE.dispose(); BRIGHTGREEN.dispose(); BLUE.dispose(); GREY.dispose(); fontSmall.dispose(); } }); addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { ValuePairTimelineCanvas.this.paintControl(e); } }); } private Font createFontofSize(int sizeOfFont) { Font initialFont = getDisplay().getSystemFont(); FontData[] fontData = initialFont.getFontData(); for (int i = 0; i < fontData.length; i++) { fontData[i].setHeight(sizeOfFont); } Font newFont = new Font(getDisplay(), fontData); return newFont; } void paintControl(PaintEvent e) { GC gc = e.gc; gc.setFont(fontSmall); gc.setBackground(ORANGE); // draw the x base line gc.setForeground(GREY); gc.drawRectangle(xoffBase, yoffBase, iPixX, 1); // draw a title gc.setFont(fontBig); gc.drawText(String.valueOf(befundArt), 2, 0, true); if (findings == null || findings.size() == 0) { gc.drawText("no Findings set", 20, 20); return; } // compute nr of days between lowest and highest date Date dStart = CstService.getDateFromCompact(findings.get(0).getDate()); Date dEnd = CstService.getDateFromCompact(findings.get(findings.size() - 1).getDate()); long totalSpan = CstService.getNrOfDaysBetween(dStart, dEnd); // gc.setBackground(ORANGE); // // draw the x base line // gc.setForeground(GREY); // gc.drawRectangle(xoffBase, yoffBase, iPixX, 1); // // // draw a title // gc.setFont(fontBig); // gc.drawText(String.valueOf(befundArt), 2, 0, true); if (findings == null || findings.size() == 0) { return; } // y-axis: Display range is 0 - 160 double yFactor = new Double(iPixY) / new Double(werteBereich).doubleValue(); // System.out.println("yFactor: " + yFactor); // System.out.println("iPixX: " + iPixX); // System.out.println("totalSpan: " + totalSpan); // 20er Linie gc.setFont(fontSmall); gc.setForeground(BLUE); int lineValue = 0; gc.drawText(String.valueOf(einheit), iPixX + 25, yoffBase - new Double(lineValue * yFactor).intValue() - 6, true); gc.setForeground(GREY); for (int i = 1; i < nrOfScaleLines + 1; i++) { gc.drawLine(xoffBase, yoffBase - new Double((i * scaleStepWidth) * yFactor).intValue(), iPixX, yoffBase - new Double((i * scaleStepWidth) * yFactor).intValue()); gc.drawText(String.valueOf(i * scaleStepWidth), iPixX + 25, yoffBase - new Double((i * scaleStepWidth) * yFactor).intValue() - 6, true); } gc.setBackground(GREY); int xoff = 0; double xFactor = new Double(iPixX).doubleValue() / new Double(totalSpan).doubleValue(); gc.setForeground(BLACK); if (findings.size() == 1) { String date = CstService.getReadableFromCompact(findings.get(0).getDate()); gc.drawText(date, xoffBase + new Double(iPixX / 2).intValue(), yoffBase, true); gc.setForeground(BLUE); gc.drawLine(xoff, yoffBase - new Double(findings.get(0).getWert1() * yFactor).intValue(), xoff + iPixX, yoffBase - new Double(findings.get(0).getWert1() * yFactor).intValue()); gc.drawText(String.valueOf(findings.get(0).getWert1()), xoffBase + new Double(iPixX / 2).intValue(), yoffBase - new Double(findings.get(0).getWert1() * yFactor).intValue(), true); gc.drawText(String.valueOf(findings.get(0).getWert2()), xoffBase + new Double(iPixX / 2).intValue(), yoffBase - new Double(findings.get(0).getWert2() * yFactor).intValue(), true); gc.setForeground(ORANGE); } else { for (int x = 0; x < findings.size(); x++) { ValuePairTimeline finding = findings.get(x); int yoff = 0; if (x % 2 == 0) { yoff = 8; } String date = CstService.getReadableFromCompact(finding.getDate()); gc.drawText(date, xoffBase + new Double(xoff * xFactor).intValue(), yoffBase + yoff + 4, true); // je gr�sser corrY desto h�her wandert der Text int corrY = 10; // print syst gc.setForeground(BLUE); gc.drawText(String.valueOf(finding.getWert1()), xoffBase + new Double(xoff * xFactor).intValue(), yoffBase - new Double(finding.getWert1() * yFactor).intValue() - corrY, true); gc.setForeground(ORANGE); gc.drawText(String.valueOf(finding.getWert2()), xoffBase + new Double(xoff * xFactor).intValue(), yoffBase - new Double(finding.getWert2() * yFactor).intValue() - corrY, true); gc.setForeground(BLACK); if (x < findings.size() - 1) { long lSpan = CstService.getNrOfDaysBetween( CstService.getDateFromCompact(findings.get(0).getDate()), CstService.getDateFromCompact(findings.get(x + 1).getDate())); xoff = new Long(lSpan).intValue(); } } } gc.dispose(); } private double getHighestValueInFindings() { if (findings.size() == 0) { return 0; } double highest = 0; for (int x = 0; x < findings.size(); x++) { if (findings.get(x).getWert1() > highest) { highest = findings.get(x).getWert1(); } if (findings.get(x).getWert2() > highest) { highest = findings.get(x).getWert2(); } } return highest; } private double getLowestValueInFindings() { if (findings.size() == 0) { return 0; } double lowest = findings.get(0).getWert1(); for (int x = 1; x < findings.size(); x++) { if (findings.get(x).getWert1() < lowest) { lowest = findings.get(x).getWert1(); } if (findings.get(x).getWert2() < lowest) { lowest = findings.get(x).getWert2(); } } return lowest; } public Point computeSize(int wHint, int hHint, boolean changed) { return new Point(iPixX + 70, 30 + yoffBase); } public List<ValuePairTimeline> getFindings() { return findings; } public void setFindings(List<ValuePairTimeline> findings) { this.findings = findings; Collections.sort(this.findings, new FindingsComparable()); /* for (ValuePairTimeline finding : findings) { System.out.println("BdValue: " + finding.getDate() + "syst/diast:" +finding.getWeightKg()); }*/ double lowest = getLowestValueInFindings(); double highest = getHighestValueInFindings(); // System.out.println("lowest: " + lowest); // System.out.println("highest: " + highest); valueRangeOfInput = highest - lowest; // 20 px is the distance between scale lines distBetweenLines = 20d; //nrOfScaleLines = iPixY / distBetweenLines; nrOfScaleLines = 10; int num = new Double(getHighestValueInFindings()).intValue(); int rounded = ((num + 99) / 100) * 100; scaleStepWidth = rounded / 10; // the formula doesn't work for very small values, so we correct: if (highest > 0 && highest < 10) { rounded = ((num + 9) / 10) * 10; scaleStepWidth = 1; } /* if (highest > 0 && highest < 10) { rounded = ((num + 9) / 10) * 10; scaleStepWidth = 1; } else if (highest > 10 && highest < 100) { rounded = ((num + 99) / 100) * 100; scaleStepWidth = 10; } else if (highest > 100 && highest < 5000) { rounded = ((num + 499) / 5000) * 5000; scaleStepWidth = 200; } else if (highest > 100 && highest < 1000) { rounded = ((num + 990) / 1000) * 1000; scaleStepWidth = 100; } else if (highest > 1000 && highest < 10000) { rounded = ((num + 9999) / 10000) * 10000; scaleStepWidth = 1000; }*/ this.werteBereich = rounded; // System.out.println("rounded: " + lowest); // System.out.println("highest: " + highest); // System.out.println("valueRangeOfInput: " + valueRangeOfInput); // System.out.println("distBetweenLines: " + distBetweenLines); // System.out.println("nrOfScaleLines: " + nrOfScaleLines); // System.out.println("scaleStepWidth: " + scaleStepWidth); } public class FindingsComparable implements Comparator<ValuePairTimeline> { @Override public int compare(ValuePairTimeline o1, ValuePairTimeline o2) { return o1.getDate().compareTo(o2.getDate()); } } }