X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.trend%2Fsrc%2Forg%2Fsimantics%2Ftrend%2Fimpl%2FHorizRuler.java;h=708a32efcde55d6022b27675264762e31050ca65;hp=0c0daee8aad4c2dfebb592080e70a4c7b8df2fb0;hb=d9d830062a16b727c65d9bbd04f519235c5ece01;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java b/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java index 0c0daee8a..708a32efc 100644 --- a/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java +++ b/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java @@ -1,299 +1,307 @@ -/******************************************************************************* - * Copyright (c) 2007, 2011 Association for Decentralized Information Management in - * Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.trend.impl; - -import java.awt.Color; -import java.awt.Graphics2D; -import java.text.Format; -import java.text.NumberFormat; - -import org.simantics.g2d.utils.GridSpacing; -import org.simantics.g2d.utils.GridUtil; -import org.simantics.trend.configuration.TimeWindow; -import org.simantics.trend.configuration.TrendSpec; -import org.simantics.utils.format.TimeFormat; - -public class HorizRuler extends TrendGraphicalNode { - - private static final long serialVersionUID = 7155812928124259094L; - - GridSpacing spacing = GridSpacing.SOME_SPACING; - public double from = 0; - public double end = 100; - public boolean autoscroll = true; // Determines if auto-scroll is on/off - boolean manualscale = false; // Locked in trend spec - TimeFormat timeFormat = new TimeFormat(0, 0); - private Format f = timeFormat; - double iFrom = Double.MAX_VALUE; - double iEnd = -Double.MAX_VALUE; - public double basetime = 0; - public TimeWindowListener listener; - public static final Color AUTOSCROLL_ON = new Color(0, 225, 34); - public static final Color AUTOSCROLL_OFF = new Color(255, 115, 115); - - - public boolean setWidth(double width) { - if (getWidth()==width) return false; - this.setSize(width, 20); - return true; - } - - public boolean setFromEnd(double from, double end) { - if (this.from!=from || this.end!=end) { - this.from = from; - this.end = end; - getTrend().shapedirty = true; - return true; - } - return false; - } - - public boolean setFromScale(double from, double scaleX) { - double end = getWidth() * scaleX + from; - return setFromEnd(from, end); - } - - - public void fireListener() { - if (listener != null) { - double wid = getWidth(); - if ( wid == 0.0 ) wid = 0.1; - double sx = (end-from) / wid; - listener.onNewWindow(from, end, sx); - } - } - - /** - * Set grid spacing and text formatter; - */ - public void layout() { - TrendNode trend = getTrend(); - if (trend.timeFormat == org.simantics.trend.configuration.TimeFormat.Time) { - // Figure out how many decimals are needed - timeFormat.setMaxValue(end); - timeFormat.setDecimals(1); - - double labelWidth = 0; - double maxLabelWidth = 0; - for (int i=0; i<2; i++) { - labelWidth = GridUtil.calcLabelWidth(from - basetime, end - basetime, timeFormat, spacing); - maxLabelWidth = Math.max(labelWidth, maxLabelWidth); - spacing = GridSpacing.makeGridSpacing(end-from, getWidth(), labelWidth+10); - timeFormat.setDecimals((int) -spacing.segmentExp); - } - - if (maxLabelWidth>labelWidth) { - spacing = GridSpacing.makeGridSpacing(end-from, getWidth(), maxLabelWidth+10); - timeFormat.setDecimals((int) -spacing.segmentExp); - } - - f = timeFormat; - - } else { - f = NumberFormat.getInstance(); - double labelWidth = GridUtil.calcLabelWidth(from - basetime, end, f, spacing); - this.spacing = GridSpacing.makeGridSpacing(end-from, getWidth(), labelWidth+10); - } - } - - @Override - protected void doRender(Graphics2D g2d) { - TrendNode trend = getTrend(); - - // Draw little "Frozen" - if ( !trend.printing ) - { -// g2d.setColor( Color.LIGHT_GRAY ); - g2d.setColor( autoscroll ? AUTOSCROLL_ON : AUTOSCROLL_OFF ); - g2d.setFont( GridUtil.RULER_FONT ); - String txt = !autoscroll ? (manualscale ? "*" : "Auto-scroll off") : (manualscale ? "" : "Auto-scroll on"); - // Draw at bottom -// g2d.drawString(txt, 0.f, (float)getHeight() + 12.f ); - // Draw to right - g2d.drawString(txt, (float) getWidth()+20, 20.f ); - } - - g2d.setPaint(Color.GRAY); - g2d.setStroke( GridUtil.RULER_LINE_STROKE ); - GridUtil.paintHorizontalRuler( - spacing, - g2d, - from - basetime, - getWidth(), - f); - } - - /** - * This method sets iFrom and iEnd values. - * Read reads values from ItemNodes. - * So it is good idea to call {@link ItemNode#readMinMaxFromEnd()} first. - */ - public void setKnownFromEnd() { - TrendNode trendNode = (TrendNode) getParent(); - - iFrom = Double.MAX_VALUE; - iEnd = -Double.MAX_VALUE; - for (ItemNode item : trendNode.allItems) { - if ( !Double.isNaN(item.from) ) iFrom = Math.min(iFrom, item.from); - if ( !Double.isNaN(item.end ) ) iEnd = Math.max(iEnd , item.end ); - } - // Scale to 0..10 if there is no data - if (iFrom == Double.MAX_VALUE && iEnd == -Double.MAX_VALUE) { - iFrom = 0.; - iEnd = 10.; - } - } - - /** - * If zoomed, do nothing. - * If not zoomed, set from and end according to TrendSpec's time window settings. - */ - public boolean autoscale() { - if (!autoscroll) return false; - - setKnownFromEnd(); - TrendNode trendNode = (TrendNode) getParent(); - TrendSpec spec = trendNode.spec; - - double nFrom = from; - double nEnd = end; - - TimeWindow timeWindow = spec.viewProfile.timeWindow; - double len = timeWindow.timeWindowLength != null ? timeWindow.timeWindowLength : iEnd-iFrom; - - if (timeWindow.timeWindowStart != null) { - - if (timeWindow.timeWindowIncrement != null && timeWindow.timeWindowLength==null) { - nFrom = timeWindow.timeWindowStart + basetime; - if (nFrom>iEnd) { - nEnd = nFrom + 1.0; - } else { - len = Math.max(0, iEnd-nFrom); - double f = (100-timeWindow.timeWindowIncrement) / 100; - double b = 1/f; - double x = Math.log( len ) / Math.log( b ); - x = Math.ceil( x ); - x = Math.pow(b, x); - nEnd = nFrom + x; - } - } else { - nFrom = timeWindow.timeWindowStart + basetime; - nEnd = nFrom + len; - } - } else - { - if (timeWindow.timeWindowIncrement == null) { - nFrom = iEnd - len; - nEnd = iEnd; - // Marginal - nEnd += len * 0.02; - } - else - { - if (timeWindow.timeWindowLength != null) { - double f = timeWindow.timeWindowIncrement / 100; - double fraction = len * f; - - nEnd = Math.floor( (iEnd +fraction)/ fraction ) * fraction; - nFrom = nEnd - len; - if (nFromnEnd) nFrom = nEnd; - } - - return setFromEnd(nFrom, nEnd); - } - - public void translate(double dx) { - from += dx; - end += dx; - autoscroll = false; - fireListener(); - } - - /** - * Convert x position in rulers coordinate space to time value. - * This function does not apply basetime. To apply basetime deduct it from - * the result. - * - * @param x - * @return time - */ - public double toTime( double x ) { - double sx = (end-from) / getWidth(); - return from + x*sx; - } - - public double toX( double time ) { - double sx = (end-from) / getWidth(); - return (time-from) / sx; - } - - public void zoomIn(double x, double width) { - autoscroll = false; - - double sx = (end-from) / getWidth(); - double newFrom = from + x*sx; - double newEnd = from + (x+width)*sx; - - from = newFrom; - end = newEnd; - fireListener(); - } - - public void zoomOut() { - autoscroll = true; - autoscale(); - layout(); - fireListener(); - } - - public double unitsPerPixel() { - return (end-from) / getWidth(); - } - - /** - * @return the current ending sample time calculated from all visible chart - * items. - */ - public double getItemEndTime() { - return iEnd; - } - - public interface TimeWindowListener { - void onNewWindow(double from, double end, double sx); - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.trend.impl; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.text.Format; +import java.text.NumberFormat; + +import org.simantics.g2d.utils.GridSpacing; +import org.simantics.g2d.utils.GridUtil; +import org.simantics.trend.configuration.TimeWindow; +import org.simantics.trend.configuration.TrendSpec; +import org.simantics.utils.format.TimeFormat; + +public class HorizRuler extends TrendGraphicalNode { + + private static final long serialVersionUID = 7155812928124259094L; + + GridSpacing spacing = GridSpacing.SOME_SPACING; + public double from = 0; + public double end = 100; + public boolean autoscroll = true; // Determines if auto-scroll is on/off + boolean manualscale = false; // Locked in trend spec + TimeFormat timeFormat = new TimeFormat(0, 0); + private Format f = timeFormat; + double iFrom = Double.MAX_VALUE; + double iEnd = -Double.MAX_VALUE; + public double basetime = 0; + public TimeWindowListener listener; + public static final Color AUTOSCROLL_ON = new Color(0, 225, 34); + public static final Color AUTOSCROLL_OFF = new Color(255, 115, 115); + + + public boolean setWidth(double width) { + if (getWidth()==width) return false; + this.setSize(width, 20); + return true; + } + + public boolean setFromEnd(double from, double end) { + if (this.from!=from || this.end!=end) { + this.from = from; + this.end = end; + getTrend().shapedirty = true; + return true; + } + return false; + } + + public boolean setFromScale(double from, double scaleX) { + double end = getWidth() * scaleX + from; + return setFromEnd(from, end); + } + + + public void fireListener() { + if (listener != null) { + double wid = getWidth(); + if ( wid == 0.0 ) wid = 0.1; + double sx = (end-from) / wid; + listener.onNewWindow(from, end, sx); + } + } + + /** + * Set grid spacing and text formatter; + */ + public void layout() { + TrendNode trend = getTrend(); + if (trend.timeFormat == org.simantics.trend.configuration.TimeFormat.Time) { + // Figure out how many decimals are needed + timeFormat.setMaxValue(end); + timeFormat.setDecimals(1); + + double labelWidth = 0; + double maxLabelWidth = 0; + for (int i=0; i<2; i++) { + labelWidth = GridUtil.calcLabelWidth(from - basetime, end - basetime, timeFormat, spacing); + maxLabelWidth = Math.max(labelWidth, maxLabelWidth); + spacing = GridSpacing.makeGridSpacing(end-from, getWidth(), labelWidth+10); + timeFormat.setDecimals((int) -spacing.segmentExp); + } + + if (maxLabelWidth>labelWidth) { + spacing = GridSpacing.makeGridSpacing(end-from, getWidth(), maxLabelWidth+10); + timeFormat.setDecimals((int) -spacing.segmentExp); + } + + f = timeFormat; + + } else { + f = NumberFormat.getInstance(); + double labelWidth = GridUtil.calcLabelWidth(from - basetime, end, f, spacing); + this.spacing = GridSpacing.makeGridSpacing(end-from, getWidth(), labelWidth+10); + } + } + + @Override + protected void doRender(Graphics2D g2d) { + TrendNode trend = getTrend(); + + // Draw little "Frozen" + if ( !trend.printing ) + { +// g2d.setColor( Color.LIGHT_GRAY ); + g2d.setColor( autoscroll ? AUTOSCROLL_ON : AUTOSCROLL_OFF ); + g2d.setFont( GridUtil.RULER_FONT ); + String txt = !autoscroll ? (manualscale ? "*" : "Auto-scroll off") : (manualscale ? "" : "Auto-scroll on"); + // Draw at bottom +// g2d.drawString(txt, 0.f, (float)getHeight() + 12.f ); + // Draw to right + g2d.drawString(txt, (float) getWidth()+20, 20.f ); + } + + g2d.setPaint(Color.GRAY); + g2d.setStroke( GridUtil.RULER_LINE_STROKE ); + GridUtil.paintHorizontalRuler( + spacing, + g2d, + from - basetime, + getWidth(), + f); + } + + /** + * This method sets iFrom and iEnd values. + * Read reads values from ItemNodes. + * So it is good idea to call {@link ItemNode#readMinMaxFromEnd()} first. + */ + public void setKnownFromEnd() { + TrendNode trendNode = (TrendNode) getParent(); + + iFrom = Double.MAX_VALUE; + iEnd = -Double.MAX_VALUE; + for (ItemNode item : trendNode.allItems) { + if ( !Double.isNaN(item.from) ) iFrom = Math.min(iFrom, item.from); + if ( !Double.isNaN(item.end ) ) iEnd = Math.max(iEnd , item.end ); + } + // Scale to 0..10 if there is no data + if (iFrom == Double.MAX_VALUE && iEnd == -Double.MAX_VALUE) { + iFrom = 0.; + iEnd = 10.; + } + } + + /** + * If zoomed, do nothing. + * If not zoomed, set from and end according to TrendSpec's time window settings. + */ + public boolean autoscale() { + if (!autoscroll) return false; + + setKnownFromEnd(); + TrendNode trendNode = (TrendNode) getParent(); + TrendSpec spec = trendNode.spec; + + double nFrom = from; + double nEnd = end; + + TimeWindow timeWindow = spec.viewProfile.timeWindow; + double len = timeWindow.timeWindowLength != null ? timeWindow.timeWindowLength : iEnd-iFrom; + + if (timeWindow.timeWindowStart != null) { + + if (timeWindow.timeWindowIncrement != null && timeWindow.timeWindowLength==null) { + nFrom = timeWindow.timeWindowStart + basetime; + if (nFrom>iEnd) { + nEnd = nFrom + 1.0; + } else { + len = Math.max(0, iEnd-nFrom); + double f = (100-timeWindow.timeWindowIncrement) / 100; + double b = 1/f; + double x = Math.log( len ) / Math.log( b ); + x = Math.ceil( x ); + x = Math.pow(b, x); + nEnd = nFrom + x; + } + } else { + nFrom = timeWindow.timeWindowStart + basetime; + nEnd = nFrom + len; + } + } else + { + if (timeWindow.timeWindowIncrement == null) { + nFrom = iEnd - len; + nEnd = iEnd; + // Marginal + nEnd += len * 0.02; + } + else + { + if (timeWindow.timeWindowLength != null) { + double f = timeWindow.timeWindowIncrement / 100; + double fraction = len * f; + + nEnd = Math.floor( (iEnd +fraction)/ fraction ) * fraction; + nFrom = nEnd - len; + if (nFromnEnd) nFrom = nEnd; + } + + return setFromEnd(nFrom, nEnd); + } + + public void translate(double dx) { + from += dx; + end += dx; + autoscroll = false; + fireListener(); + } + + /** + * Convert x position in rulers coordinate space to time value. + * This function does not apply basetime. To apply basetime deduct it from + * the result. + * + * @param x + * @return time + */ + public double toTime( double x ) { + double sx = (end-from) / getWidth(); + return from + x*sx; + } + + public double toX( double time ) { + double sx = (end-from) / getWidth(); + return (time-from) / sx; + } + + public void zoomIn(double x, double width) { + autoscroll = false; + + double sx = (end-from) / getWidth(); + double newFrom = from + x*sx; + double newEnd = from + (x+width)*sx; + + from = newFrom; + end = newEnd; + fireListener(); + } + + public void zoomOut() { + autoscroll = true; + autoscale(); + layout(); + fireListener(); + } + + public double unitsPerPixel() { + return (end-from) / getWidth(); + } + + /** + * @return the current starting sample time calculated from all visible chart + * items. + */ + public double getItemFromTime() { + return iFrom; + } + + /** + * @return the current ending sample time calculated from all visible chart + * items. + */ + public double getItemEndTime() { + return iEnd; + } + + public interface TimeWindowListener { + void onNewWindow(double from, double end, double sx); + } + +}