JDiagram: Komplette Überarbeitung (Diagramm entfernt)

thobaben_diagram
Harald Wolff 2016-04-29 02:38:55 +02:00
parent 33377971b9
commit 817d0c867b
13 changed files with 889 additions and 468 deletions

View File

@ -5,79 +5,531 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.hwo.ui.diagram.Diagram;
import org.hwo.ui.diagram.LinePlotPainter;
import org.hwo.ui.diagram.LinearScaler;
import org.hwo.ui.diagram.PlotLabeler;
import org.hwo.ui.diagram.PlotPainter;
import org.hwo.ui.diagram.PlotProvider2;
import org.hwo.ui.diagram.Scaler;
import org.hwo.ui.diagram.SimplePlotLabeler;
import org.hwo.ui.diagram.SimplePlotProvider;
public class JDiagram extends JPanel {
private Diagram diagram;
public class JDiagram extends JComponent {
private PlotProvider2
plotProvider;
private PlotLabeler
defaultLabeler;
// Innenabstand zu Zeichnungselementen
private int bTop,
bBottom,
bLeft,
bRight;
// Länge der Achsenmarkierungen
private int axMarkerLength;
// Anzahl der Achsenmarkierungen - 1
private int nOrdinateLabels,
nAbszissLabels;
// Layout Merker
private int plotHeight,
plotWidth;
private double abszissMinimum,
abszissMaximum,
abszissWindow;
private int screenDPI;
private int fontLineHeight;
private boolean autoOrdinateLabeling;
private boolean drawHorizontalGrid;
private boolean drawVerticalGrid;
private boolean logarithmic;
private boolean preferLabelHints;
private boolean autoScale;
private boolean autoScaleMargins;
private Color verticalGridColor;
private OrdinateView[]
ordinateViews;
private PlotPainter[]
plotPainters;
public JDiagram(){
setMinimumSize(new Dimension(80, 80));
getDiagram();
diagram.setFont( getFont() );
setDoubleBuffered(true);
defaultLabeler = new SimplePlotLabeler();
bTop = bBottom = bLeft = 10;
bRight = 30;
axMarkerLength = 3;
nOrdinateLabels = 11;
nAbszissLabels = 0;
drawHorizontalGrid = true;
verticalGridColor = new Color(192, 192, 192);
setPlotProvider(new SimplePlotProvider(1, 0));
}
public void setPlotProvider(PlotProvider2 plotProvider) {
this.plotProvider = plotProvider;
fundamentalsChanged();
}
public PlotProvider2 getPlotProvider() {
return plotProvider;
}
public boolean isAutoOrdinateLabeling() {
return autoOrdinateLabeling;
}
public void setAutoOrdinateLabeling(boolean autoOrdinateLabeling) {
this.autoOrdinateLabeling = autoOrdinateLabeling;
}
public boolean isDrawHorizontalGrid() {
return drawHorizontalGrid;
}
public void setDrawHorizontalGrid(boolean drawHorizontalGrid) {
this.drawHorizontalGrid = drawHorizontalGrid;
}
public boolean isDrawVerticalGrid() {
return drawVerticalGrid;
}
public void setDrawVerticalGrid(boolean drawVerticalGrid) {
this.drawVerticalGrid = drawVerticalGrid;
}
private void fundamentalsChanged(){
ordinateViews = new OrdinateView[ plotProvider.getMaxOrdinate() + 1 ];
for (int n=0; n < plotProvider.getMaxOrdinate() + 1; n++)
ordinateViews[n] = new OrdinateView(n);
PlotPainter pp = new LinePlotPainter();
plotPainters = new PlotPainter[plotProvider.getNumGraphs()];
for (int n=0;n<plotProvider.getNumGraphs();n++)
plotPainters[n] = pp;
}
public Scaler getScaler(int ordinate){
return this.ordinateViews[ordinate].scaler;
}
public void setScaler(int ordinate,Scaler scaler){
this.ordinateViews[ordinate].scaler = scaler;
}
public PlotPainter getPlotPainter(int graph){
return this.plotPainters[graph];
}
public void setPlotPainter(int graph,PlotPainter plotPainter){
this.plotPainters[graph] = plotPainter;
}
public int getAbszissLabels() {
return nAbszissLabels;
}
public void setAbszissLabels(int nAbszissLabels) {
this.nAbszissLabels = nAbszissLabels;
}
public int getOrdinateLabels() {
return nOrdinateLabels;
}
public void setOrdinateLabels(int nOrdinateLabels) {
this.nOrdinateLabels = nOrdinateLabels;
}
public Color getOrdinateColor(int ordinate){
return this.ordinateViews[ ordinate ].colDraw;
}
public void setOrdinateColor(int ordinate,Color color){
int r,g,b;
this.ordinateViews[ ordinate ].colDraw = color;
r = (color.getRed() + 768)/4;
g = (color.getGreen() + 768)/4;
b = (color.getBlue() + 768)/4;
this.ordinateViews[ ordinate ].colGrid = new Color(r,g,b);
}
public boolean isPreferLabelHints() {
return preferLabelHints;
}
public void setPreferLabelHints(boolean preferLabelHints) {
this.preferLabelHints = preferLabelHints;
}
public boolean isAutoScale() {
return autoScale;
}
public void setAutoScale(boolean autoScale) {
this.autoScale = autoScale;
}
public boolean isAutoScaleMargins() {
return autoScaleMargins;
}
public void setAutoScaleMargins(boolean autoScaleMargins) {
this.autoScaleMargins = autoScaleMargins;
}
public void autoscale(){
int ordinate;
Double[] max,min;
System.err.println("AutoScale...");
max = new Double[this.plotProvider.getMaxOrdinate()+1];
min = new Double[this.plotProvider.getMaxOrdinate()+1];
for (int graph=0; graph < this.plotProvider.getNumGraphs(); graph++){
ordinate = this.plotProvider.getOrdinate(graph);
for (int n=0;n<this.plotProvider.getLength(); n++){
Float value = this.plotProvider.getValue(n, graph);
if (value != null)
{
if ((min[ordinate] == null) || (value < min[ordinate]))
min[ordinate] = value.doubleValue();
if ((max[ordinate] == null) || (value > max[ordinate]))
max[ordinate] = value.doubleValue();
};
}
}
for (int i=0;i<this.plotProvider.getMaxOrdinate()+1;i++){
if (min[i] == null)
min[i] = 0.0;
if (max[i] == null)
max[i] = 1.0;
System.err.format("MIN: %f Max: %f\n", min[i], max[i]);
this.ordinateViews[i].scaler.scale(min[i], max[i], autoScaleMargins);
}
}
@Override
public void paint(Graphics g) {
this.diagram.plot((Graphics2D)g, this.getWidth(), this.getHeight());
screenDPI = Toolkit.getDefaultToolkit().getScreenResolution();
fontLineHeight = getFont().getSize() * screenDPI / 72;
plotHeight = getHeight() - bTop - bBottom - fontLineHeight - axMarkerLength;
plotWidth = getWidth() - bLeft - bRight;
g.setFont( getFont() );
// Hintergrund zeichnen
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
if (autoScale)
this.autoscale();
paintOrdinates ((Graphics2D) g);
paintAbszisse ((Graphics2D) g);
paintGraphs ((Graphics2D) g);
}
public double[] getordinateLabelHints(int ordinate){
double[] scalerHints = this.ordinateViews[ordinate].scaler.getMarkerHints();
double[] hints = null;
int nHints = autoOrdinateLabeling ? plotHeight / (fontLineHeight * 2) : nOrdinateLabels;
int n;
if ((nHints > 0) && ((scalerHints == null) || (!preferLabelHints))) {
if (nHints < 2)
nHints = 2;
hints = new double[nHints];
for (n = 0; n < hints.length; n++){
hints[n] = this.ordinateViews[ordinate].scaler.getMinValue() + (this.ordinateViews[ordinate].scaler.getWindow() * n / (hints.length-1));
}
} else {
hints = scalerHints;
}
return hints;
}
public void paintOrdinates(Graphics2D g){
double[][] labelValues = new double[ ordinateViews.length ][];
for (int ordinate=0; ordinate < ordinateViews.length; ordinate++){
labelValues[ ordinate ] = getordinateLabelHints(ordinate);
int nMarkers = labelValues[ ordinate ].length - 1;
int maxWidth = 0;
String[] labels = new String[ nMarkers + 1 ];
int[] labelWidths = new int[ nMarkers + 1 ];
this.ordinateViews[ ordinate ].scaler.setHeight( plotHeight );
g.setColor( this.ordinateViews[ ordinate ].colDraw );
for (int i=0;i<=nMarkers;i++){
labels[i] = this.defaultLabeler.getOrdinateLabel(
this,
labelValues[ordinate][i]
);
labelWidths[i] = g.getFontMetrics().stringWidth(labels[i]);
if (labelWidths[i] > maxWidth)
maxWidth = labelWidths[i];
}
plotWidth -= maxWidth + 5;
for (int i=0; i<=nMarkers ;i++){
g.drawString(
labels[i],
getWidth() - bRight - plotWidth - labelWidths[i],
bTop + plotHeight - this.ordinateViews[ ordinate ].scaler.getPosition(labelValues[ordinate][i]) + (fontLineHeight/4)
);
}
plotWidth -= axMarkerLength;
};
g.drawLine(
getWidth() - bRight - plotWidth,
bTop,
getWidth() - bRight - plotWidth,
bTop + plotHeight
);
for (int ordinate=0; ordinate < ordinateViews.length; ordinate++){
int nMarkers = labelValues[ ordinate ].length - 1;
for (int i=0;i<=nMarkers;i++){
int yp = bTop + plotHeight - this.ordinateViews[ ordinate ].scaler.getPosition(labelValues[ordinate][i]);
g.drawLine(
getWidth() - bRight - plotWidth,
yp,
getWidth() - bRight - plotWidth - axMarkerLength,
yp
);
if (drawHorizontalGrid){
g.setColor( this.ordinateViews[ ordinate ].colGrid );
g.drawLine(
getWidth() - bRight - plotWidth + 1,
yp,
getWidth() - bRight,
yp
);
g.setColor( this.ordinateViews[ ordinate ].colDraw );
}
}
}
}
void paintAbszisse(Graphics2D g){
int nMarker = nAbszissLabels;
if (nMarker == 0){
int w = g.getFontMetrics().stringWidth( this.defaultLabeler.getAbzisseLabel(this, (double)this.plotProvider.getPositionMaximum()));
nMarker = plotWidth / (w*2);
}
abszissMinimum = this.plotProvider.getPositionMinimum();
abszissMaximum = this.plotProvider.getPositionMaximum();
abszissWindow = abszissMaximum - abszissMinimum;
g.setColor(getForeground());
g.drawLine(
getWidth() - bRight - plotWidth,
bTop + plotHeight,
getWidth() - bRight,
bTop + plotHeight
);
for (int n=0;n <= nMarker; n++){
int xpos = plotWidth * n / nMarker;
double pos = abszissMinimum + (abszissWindow * n / nMarker);
String xlabel = this.defaultLabeler.getAbzisseLabel(this, pos);
int xlwidth = g.getFontMetrics().stringWidth(xlabel);
g.drawString(xlabel, getWidth() - bRight - plotWidth + xpos - (xlwidth / 2) , getHeight() - bBottom);
g.drawLine(
getWidth() - bRight - plotWidth + xpos,
bTop + plotHeight,
getWidth() - bRight - plotWidth + xpos,
bTop + plotHeight + axMarkerLength
);
if (drawVerticalGrid){
g.setColor(verticalGridColor);
g.drawLine(
getWidth() - bRight - plotWidth + xpos,
bTop,
getWidth() - bRight - plotWidth + xpos,
bTop + plotHeight
);
g.setColor(getForeground());
};
}
}
void paintGraphs(Graphics2D g){
int ordinate;
Color graphColor;
Color[] graphColors = this.plotProvider.getColors();
for (int graph=0; graph < this.plotProvider.getNumGraphs(); graph++){
this.plotPainters[ graph ].reset();
ordinate = this.plotProvider.getOrdinate(graph);
graphColor = graphColors[graph];
if (graphColor == null){
graphColor = this.ordinateViews[ordinate].colDraw;
}
if (graphColor == null){
graphColor = Color.BLACK;
}
for (int n=0;n<this.plotProvider.getLength(); n++){
int x,y;
Float value = this.plotProvider.getValue(n, graph);
Float position = this.plotProvider.getPosition(n, graph);
if ((value != null) && (position != null) )
{
x = getWidth() - bRight - plotWidth + (int)((position - abszissMinimum) * plotWidth / abszissWindow);
y = bTop + plotHeight - this.ordinateViews[ ordinate ].scaler.getPosition(value);
this.plotPainters[ graph ].paintPoint(g, graphColor, x, y);
};
}
}
}
public Diagram getDiagram() {
if (diagram==null)
diagram = new Diagram();
return diagram;
}
public void setDiagram(Diagram diagram) {
this.diagram = diagram;
}
public int getNumLabels(){
return this.diagram.getNumLabels();
/*
g.setColor(foreground);
g.drawLine(x0, y0 + 5, x0, y1 - 10);
g.drawLine(x0, y1 - 10 , x0 - 5, y1 - 5);
g.drawLine(x0, y1 - 10 , x0 + 5, y1 - 5);
g.drawLine(x0, y0, x1 + 10, y0);
g.drawLine(x1 + 10 , y0, x1 + 5, y0 - 5);
g.drawLine(x1 + 10 , y0, x1 + 5, y0 + 5);
Color[] colors = this.plotProvider.getColors();
double[] min,max;
min = new double[this.plotProvider.getMaxOrdinate()+1];
max = new double[this.plotProvider.getMaxOrdinate()+1];
Arrays.fill(min, double.MAX_VALUE);
Arrays.fill(max, double.MIN_VALUE);
for (int n=0;n<this.plotProvider.getNumGraphs();n++){
int ordinate = this.plotProvider.getOrdinate(n);
plotPainter.reset();
for (int i=0;i<this.plotProvider.getLength();i++){
int x,y;
double v = this.plotProvider.getValue(i, n);
if (v != null){
x = point2x(i);
y = value2y(ordinate,v);
plotPainter.paintPoint(g, colors[n], x, y);
if (v < min[ordinate])
min[ordinate] = v;
if (v > max[ordinate])
max[ordinate] = v;
} else {
plotPainter.reset();
}
}
}
for (int i=0;i<this.autoscale.length;i++){
if (this.autoscale[i]){
if (!(this.minValues[i].equals(min[i]) && this.maxValues[i].equals(max[i]))){
this.minValues[i] = min[i];
this.maxValues[i] = max[i];
this.autoscale(i);
rescaled = true;
}
}
}
if (rescaled){
this.plot(g,width,height);
}
}
public void setNumLabels(int nLabels){
this.diagram.setNumLabels(nLabels);
*/
class OrdinateView {
int num;
Color colDraw,
colGrid;
int ordinateLabelWidth;
Scaler scaler;
public OrdinateView(int num) {
this.num = num;
this.colDraw = Color.BLACK;
this.colGrid = Color.LIGHT_GRAY;
this.scaler = new LinearScaler();
}
Scaler getScaler(){
return this.scaler;
}
void setScaler(Scaler scaler){
this.scaler = scaler;
}
}
public String getLabelFormatSpec(){
return this.diagram.getLabelFormatSpec();
}
public void setLabelFormatSpec(String spec){
this.diagram.setLabelFormatSpec(spec);
}
@Override
public Font getFont() {
return super.getFont();
}
@Override
public void setFont(Font font) {
if (diagram != null)
diagram.setFont(font);
super.setFont(font);
}
@Override
public Color getBackground() {
return getDiagram().getBackground();
}
@Override
public void setBackground(Color bg) {
getDiagram().setBackground(bg);
repaint();
}
@Override
public void setForeground(Color fg) {
getDiagram().setForeground(fg);
repaint();
}
@Override
public Color getForeground() {
return getDiagram().getForeground();
}
}

View File

@ -8,6 +8,8 @@ import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import org.hwo.ui.diagram.CirclePlotPainter;
import org.hwo.ui.diagram.LinePlotPainter;
import org.hwo.ui.diagram.LogarithmicScaler;
import org.hwo.ui.diagram.SimplePlotProvider;
import java.awt.GridBagLayout;
@ -41,7 +43,7 @@ public class JUITest extends JFrame {
*/
public JUITest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1111, 342);
setBounds(100, 100, 928, 342);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
@ -53,8 +55,7 @@ public class JUITest extends JFrame {
contentPane.setLayout(gbl_contentPane);
diagram = new JDiagram();
diagram.setLabelFormatSpec("%.2f");
diagram.setNumLabels(6);
diagram.setBackground(Color.WHITE);
diagram.setFont(new Font("Nimbus Mono L", Font.PLAIN, 14));
GridBagConstraints gbc_diagram = new GridBagConstraints();
gbc_diagram.fill = GridBagConstraints.BOTH;
@ -66,33 +67,51 @@ public class JUITest extends JFrame {
}
private void initialize(){
SimplePlotProvider p = new SimplePlotProvider(2, 32);
SimplePlotProvider p = new SimplePlotProvider(3, 41);
Float f = 0.0f;
Float[] values = p.getMatrix()[0];
for (int i=0;i<p.getPoints();i++){
Float f = 5.0f;
Float[] values = p.getPlot(0);
for (int i=0;i<p.getLength();i++){
f += (float)(Math.random()-0.5f)*0.5f;
values[i] = f;
}
p.getColors()[0] = Color.BLUE;
values = p.getMatrix()[1];
for (int i=0;i<p.getPoints();i++){
if ((i&1) == 0){
f += (float)(Math.random()-0.5f)*0.5f;
values[i] = f;
} else {
values[i] = null;
}
values = p.getPlot(1);
for (int i=0;i<p.getLength();i++){
//values[i] = 5 + (float)Math.sin(Math.PI * i / 8) * 4;
values[i] = (float)(10 + (((float)i/4)*10.0));
}
values = p.getPlot(2);
for (int i=0;i<p.getLength();i++){
//values[i] = 5 + (float)Math.sin(Math.PI * i / 8) * 4;
values[i] = (float)(10 + (((float)i/4)*10.0));
}
diagram.getDiagram().setPlotPainter(new CirclePlotPainter());
diagram.getDiagram().setPlotProvider(p);
p.setOrdinate(1, 1);
p.setOrdinate(2, 2);
p.getColors()[0] = Color.GREEN;
p.getColors()[1] = Color.BLUE;
p.getColors()[2] = Color.RED;
diagram.getDiagram().setYoffset(-3.0f);
diagram.getDiagram().setYscale(6.0f);
diagram.setPlotProvider(p);
diagram.setScaler(2, new LogarithmicScaler());
diagram.getScaler(0).scale(0, 10, false);
diagram.getScaler(1).scale(0, 100, false);
diagram.getScaler(2).scale(1, 100, false);
diagram.setDrawVerticalGrid(true);
diagram.setAbszissLabels( (values.length / 4) );
diagram.setOrdinateColor(1, Color.BLUE);
diagram.setOrdinateColor(2, Color.RED);
diagram.setPreferLabelHints(true);
LinePlotPainter lpp = (LinePlotPainter)diagram.getPlotPainter(0);
lpp.setWidth(2.0f);
//diagram.getDiagram().autoScale();
}
}

View File

@ -28,9 +28,18 @@ public class AnnotatedPlotProvider implements PlotProvider2{
private Vector<Object>
values;
private int diagram;
public AnnotatedPlotProvider(Class<?> clazz){
this.setClazz(clazz);
this.setValues(new Object[0]);
this.diagram = 0;
}
public AnnotatedPlotProvider(Class<?> clazz,int diagram){
this.diagram = diagram;
this.setClazz(clazz);
this.setValues(new Object[0]);
}
public void setClazz(Class<?> clazz) {
@ -60,13 +69,15 @@ public class AnnotatedPlotProvider implements PlotProvider2{
for (Field f: this.clazz.getDeclaredFields()){
Plot plot = f.getAnnotation(Plot.class);
if (plot != null){
gdl.add(new GraphDefinition(f));
if (plot.diagram() == this.diagram)
gdl.add(new GraphDefinition(f));
}
}
for (Method m: this.clazz.getDeclaredMethods()){
Plot plot = m.getAnnotation(Plot.class);
if (plot != null){
gdl.add(new GraphDefinition(m));
if (plot.diagram() == this.diagram)
gdl.add(new GraphDefinition(m));
}
}
@ -193,4 +204,19 @@ public class AnnotatedPlotProvider implements PlotProvider2{
}
}
@Override
public Float getPosition(int x, int graph) {
return (float)x;
}
@Override
public Float getPositionMinimum() {
return 0.0f;
}
@Override
public Float getPositionMaximum() {
return this.values.size()-1.0f;
}
}

View File

@ -2,6 +2,8 @@ package org.hwo.ui.diagram;
import java.util.SortedMap;
import org.hwo.ui.JDiagram;
public class AnnotatedSortedMapPlotProvider<T> extends AnnotatedPlotProvider implements PlotProvider2,PlotLabeler {
private SortedMap<Object, T> sortedMap;
@ -28,12 +30,12 @@ public class AnnotatedSortedMapPlotProvider<T> extends AnnotatedPlotProvider imp
@Override
public String getAbzisseLabel(Diagram diagram, int pos) {
public String getAbzisseLabel(JDiagram diagram, Double pos) {
return "";
}
@Override
public String getOrdinateLabel(Diagram diagram, Float value) {
public String getOrdinateLabel(JDiagram diagram, Double value) {
return value.toString();
}

View File

@ -1,356 +0,0 @@
package org.hwo.ui.diagram;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class Diagram {
private PlotProvider2 plotProvider;
private PlotPainter plotPainter;
private int x0,
x1,
y0,
y1;
int yh,xw;
private Float scaleBorder;
private Float[] minValues,maxValues;
private Float[] yscales;
private Float[] yoffsets;
private boolean[] autoscale;
private Font font;
private int numLabels;
private String labelFormatSpec;
private int xlabel_skip;
private LinkedList<ColoredBackground> coloredBackgrounds;
private PlotLabeler defaultLabeler;
private Color background,
foreground;
private Float abMinimum,
abMaximum;
public Diagram(){
background = Color.WHITE;
foreground = Color.BLACK;
coloredBackgrounds = new LinkedList<ColoredBackground>();
plotPainter = new LinePlotPainter();
font = new Font("Arial", Font.PLAIN, 24);
numLabels = 0;
scaleBorder = 0.1f;
defaultLabeler = new SimplePlotLabeler();
setPlotProvider(new AnnotatedPlotProvider(Object.class));
}
private void updatePlotProviderParams(){
minValues = new Float[ plotProvider.getMaxOrdinate()+1];
maxValues = new Float[ plotProvider.getMaxOrdinate()+1];
yscales = new Float[ plotProvider.getMaxOrdinate()+1];
yoffsets = new Float[ plotProvider.getMaxOrdinate()+1];
autoscale = new boolean[ plotProvider.getMaxOrdinate()+1];
Arrays.fill(minValues, 0, minValues.length, Float.MAX_VALUE);
Arrays.fill(maxValues, 0, maxValues.length, Float.MIN_VALUE);
Arrays.fill(yscales, 0, yscales.length, new Float(1.0));
Arrays.fill(yoffsets, 0, yoffsets.length, new Float(0.0));
}
public Color getBackground() {
return background;
}
public void setBackground(Color background) {
this.background = background;
}
public Color getForeground() {
return foreground;
}
public void setForeground(Color foreground) {
this.foreground = foreground;
}
public float getYoffset(int graph) {
return yoffsets[graph];
}
public void setYoffset(int graph,float yoffset) {
this.yoffsets[graph] = yoffset;
}
public float getYscale(int graph) {
return yscales[graph];
}
public void setYscale(int graph,float yscale) {
this.yscales[graph] = yscale;
}
public int getXlabel_skip() {
return xlabel_skip;
}
public void setXlabel_skip(int xlabel_skip) {
this.xlabel_skip = xlabel_skip;
}
public Font getFont() {
return font;
}
public void setFont(Font font) {
this.font = font;
}
public int getNumLabels() {
return numLabels;
}
public void setNumLabels(int numLabels) {
this.numLabels = numLabels;
}
public PlotPainter getPlotPainter() {
return plotPainter;
}
public void setPlotPainter(PlotPainter plotPainter) {
this.plotPainter = plotPainter;
}
public PlotProvider2 getPlotProvider() {
return plotProvider;
}
public void setPlotProvider(PlotProvider2 plotProvider) {
this.plotProvider = plotProvider;
updatePlotProviderParams();
}
public String getLabelFormatSpec() {
return labelFormatSpec;
}
public void setLabelFormatSpec(String labelFormatSpec) {
this.labelFormatSpec = labelFormatSpec;
}
public List<ColoredBackground> getColoredBackgrounds() {
return coloredBackgrounds;
}
public void setYMinimum(int graph,Float minimum){
setYoffset(graph,minimum);
}
public Float getYMinimum(int graph){
return getYoffset(graph);
}
public void setYMaximum(int graph,Float maximum){
setYscale(graph,maximum - yoffsets[graph]);
}
public Float getYMaximum(int graph){
return getYscale(graph) + yoffsets[graph];
}
public void autoscale(int ordinate){
yscales[ordinate] = (maxValues[ordinate] - minValues[ordinate]) * (1.0f + scaleBorder);
yoffsets[ordinate] = minValues[ordinate] - ((maxValues[ordinate] - minValues[ordinate]) * scaleBorder);
if (yscales[ordinate] == 0.0f){
if (yoffsets[ordinate] == 0.0f){
yoffsets[ordinate] = -1.0f;
yscales[ordinate] = 2.0f * (1.0f + scaleBorder);
} else {
yscales[ordinate] = yoffsets[ordinate] * (1.0f + scaleBorder);
yoffsets[ordinate] -= yscales[ordinate] / 2.0f;
}
}
System.err.println(String.format("AutoScale Ordinate %d: %f x %f", ordinate, yoffsets[ordinate], yscales[ordinate]));
}
public void autoScale(){
for (int i=0;i<minValues.length;i++){
autoscale(i);
}
}
public void setAutoScale(boolean autoScale){
for (int i=0;i<this.autoscale.length;i++)
this.autoscale[i] = autoScale;
}
public boolean isAutoScale(int ordinate){
return this.autoscale[ordinate];
}
public void setAutoScale(int ordinate,boolean autoScale){
this.autoscale[ordinate] = autoScale;
}
public BufferedImage plot(int width,int height){
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
plot(image.createGraphics(),width,height);
return image;
}
private int value2y(int graph,Float value){
return y0 - (int)(yh * ((value - yoffsets[graph])/yscales[graph]));
}
private int point2x(int point){
return x0 + (xw * point / (this.plotProvider.getLength()-1));
}
public void plot(Graphics2D g,int width,int height){
boolean rescaled = false;
int lineHeight = font.getSize() * Toolkit.getDefaultToolkit().getScreenResolution() / 72 ;
int nLabels = numLabels;
g.setColor(background);
g.fillRect(0, 0, width, height);
y0 = height - lineHeight - 10;
y1 = 10;
yh = y0 - y1;
x0 = 0;
x1 = width - 10;
if (nLabels == 0){
nLabels = ((y0 - y1) / lineHeight);
}
if (nLabels == 0)
nLabels = 1;
for (ColoredBackground bg: coloredBackgrounds){
int ya = value2y(0,bg.getMin());
int yb = value2y(0,bg.getMax());
g.setColor(bg.getColor());
g.fillRect(0, yb, width, ya - yb);
}
g.setColor(foreground);
if (this.font != null)
g.setFont(this.font);
for (int graph=0; graph < minValues.length; graph++){
int mw = 0;
for (int i=0;i<=nLabels;i++){
String l = this.defaultLabeler.getOrdinateLabel(this, (yoffsets[graph] + (yscales[graph] * i / nLabels)));
int lw = g.getFontMetrics().stringWidth(l);
if (lw > mw)
mw = lw;
}
x0 += mw;
for (int i=0;i<=nLabels;i++){
String l = this.defaultLabeler.getOrdinateLabel(this, (yoffsets[graph] + (yscales[graph] * i / nLabels)));
int lw = g.getFontMetrics().stringWidth(l);
g.drawString(l, 2 + (x0 - lw), y0 - (yh * i / nLabels) + (lineHeight/4));
}
x0 += 5;
}
x0 += 10;
xw = x1 - x0;
for (int i=0;i<=nLabels;i++){
g.drawLine(x0 - 5, y0 - (yh * i / nLabels) , x0, y0 - (yh * i / nLabels));
}
for (int i=0;i<this.plotProvider.getLength();i+=1 + this.xlabel_skip){
g.drawLine(point2x(i), y0, point2x(i), y0 + 5);
String xlabel = this.defaultLabeler.getAbzisseLabel(this, i);
int lw = g.getFontMetrics().stringWidth(xlabel);
g.drawString(xlabel, point2x(i) - (lw/2), y0 + 5 + lineHeight);
}
g.setColor(foreground);
g.drawLine(x0, y0 + 5, x0, y1 - 10);
g.drawLine(x0, y1 - 10 , x0 - 5, y1 - 5);
g.drawLine(x0, y1 - 10 , x0 + 5, y1 - 5);
g.drawLine(x0, y0, x1 + 10, y0);
g.drawLine(x1 + 10 , y0, x1 + 5, y0 - 5);
g.drawLine(x1 + 10 , y0, x1 + 5, y0 + 5);
Color[] colors = this.plotProvider.getColors();
Float[] min,max;
min = new Float[this.plotProvider.getMaxOrdinate()+1];
max = new Float[this.plotProvider.getMaxOrdinate()+1];
Arrays.fill(min, Float.MAX_VALUE);
Arrays.fill(max, Float.MIN_VALUE);
for (int n=0;n<this.plotProvider.getNumGraphs();n++){
int ordinate = this.plotProvider.getOrdinate(n);
plotPainter.reset();
for (int i=0;i<this.plotProvider.getLength();i++){
int x,y;
Float v = this.plotProvider.getValue(i, n);
if (v != null){
x = point2x(i);
y = value2y(ordinate,v);
plotPainter.paintPoint(g, colors[n], x, y);
if (v < min[ordinate])
min[ordinate] = v;
if (v > max[ordinate])
max[ordinate] = v;
} else {
plotPainter.reset();
}
}
}
for (int i=0;i<this.autoscale.length;i++){
if (this.autoscale[i]){
if (!(this.minValues[i].equals(min[i]) && this.maxValues[i].equals(max[i]))){
this.minValues[i] = min[i];
this.maxValues[i] = max[i];
this.autoscale(i);
rescaled = true;
}
}
}
if (rescaled){
this.plot(g,width,height);
}
}
public PlotLabeler getDefaultLabeler() {
return defaultLabeler;
}
public void setDefaultLabeler(PlotLabeler defaultLabeler) {
this.defaultLabeler = defaultLabeler;
}
}

View File

@ -0,0 +1,69 @@
package org.hwo.ui.diagram;
public class LinearScaler implements Scaler{
double offset,
window,
scale;
int height;
public LinearScaler() {
this.height = 1;
this.offset = 0;
this.window = 1;
this.scale();
}
private void scale(){
this.scale = this.height / this.window;
}
@Override
public void setHeight(int height) {
this.height = height;
this.scale();
}
@Override
public void scale(double minValue, double maxValue, boolean useMargin) {
this.offset = minValue;
this.window = maxValue - minValue;
if (this.window == 0)
{
this.window = this.offset * 0.1;
this.offset -= this.window / 2;
}
this.scale();
}
@Override
public int getPosition(double value) {
return (int)((value - this.offset) * this.scale);
}
@Override
public double getValue(int position) {
return ((double)position / this.scale) + this.offset;
}
@Override
public double getMinValue() {
return this.offset;
}
@Override
public double getMaxValue() {
return this.offset + this.window;
}
@Override
public double getWindow() {
return this.window;
}
@Override
public double[] getMarkerHints() {
return null;
}
}

View File

@ -0,0 +1,148 @@
package org.hwo.ui.diagram;
import java.util.ArrayList;
public class LogarithmicScaler implements Scaler {
int height;
double minimum,
maximum;
Double minDecade,
maxDecade;
public LogarithmicScaler() {
scale(1, 10, true);
height = 100;
}
@Override
public void setHeight(int height) {
this.height = height;
}
@Override
public void scale(double minValue, double maxValue, boolean useMargin) {
Double d;
System.err.println(String.format("LogarithmicScaler: minValue: %f maxValue: %f", minValue, maxValue));
if (minValue == 0)
minValue = 0.0000001;
if (minValue > 0){
d = Math.log10(minValue);
System.err.format("LS: d=%f\n", d);
if (!isInt(d) & (d < 0))
d = d - 1;
minDecade = Math.floor(d);
minimum = Math.pow(10, minDecade);
if (!useMargin){
double step = minimum;
while ( (minimum + step) <= minValue ){
minimum += step;
}
minDecade = Math.log10( minimum );
}
} else {
minDecade = null;
minimum = 0;
}
d = Math.log10(maxValue);
if (!isInt(d))
d = d + 1;
maxDecade = Math.floor(d);
maximum = Math.pow(10, maxDecade);
if (!useMargin){
double step = maximum / 10.0;
while ( (maximum - step) >= maxValue ){
maximum -= step;
}
maxDecade = Math.log10( maximum );
}
System.err.println(String.format("LogarithmicScaler: min: %f max: %f minDec: %.2f maxDec: %.2f", minimum, maximum, minDecade, maxDecade));
}
@Override
public int getPosition(double value) {
double max = maxDecade;
double pos = (Math.log10( value ));
double min = minDecade;
double win = max - min;
int r = (int)((pos - min) * height / win);
return r;
}
@Override
public double getValue(int position) {
return 0;
}
@Override
public double getMinValue() {
return minimum;
}
@Override
public double getMaxValue() {
return maximum;
}
@Override
public double getWindow() {
return maximum - minimum;
}
@Override
public double[] getMarkerHints() {
ArrayList<Double> hints = new ArrayList<Double>();
if (minDecade != null)
{
hints.add(minimum);
double hValue = minimum;
int decade = minDecade.intValue();
if (decade < 0)
decade--;
double step = Math.pow(10, (double)decade );
while (hValue < maximum){
hValue += step;
int nextDecade = new Double(Math.log10( hValue )).intValue();
if (nextDecade > decade){
step *= 10.0;
decade = nextDecade;
}
if (decade >= (maxDecade-2))
hints.add(hValue);
}
}
double[] result = new double[ hints.size() ];
for (int i=0;i<result.length;i++)
result[i] = hints.get(i);
return result;
}
private int decades(double max,double min){
Double d = Math.log10(max) - Math.log10(min);
int decades = d.intValue();
return decades;
}
private boolean isInt(Double d){
if (d.isNaN() || d.isInfinite())
return false;
return (d.equals(Math.floor(d)));
}
}

View File

@ -1,8 +1,10 @@
package org.hwo.ui.diagram;
import org.hwo.ui.JDiagram;
public interface PlotLabeler {
public String getOrdinateLabel(Diagram diagram,Float value);
public String getAbzisseLabel(Diagram diagram,int pos);
public String getOrdinateLabel(JDiagram diagram,Double value);
public String getAbzisseLabel(JDiagram diagram,Double pos);
}

View File

@ -9,8 +9,13 @@ public interface PlotProvider2 {
public int getNumGraphs();
public String getLabel(int graph);
public Float getValue(int x,int graph);
public Float getPosition(int x,int graph);
public int getOrdinate(int graph);
public Float getPositionMinimum();
public Float getPositionMaximum();
public Color[] getColors();
}

View File

@ -0,0 +1,19 @@
package org.hwo.ui.diagram;
public interface Scaler {
void setHeight (int height);
void scale (double minValue,double maxValue,boolean useMargin);
int getPosition (double value);
double getValue (int position);
double getMinValue ();
double getMaxValue ();
double getWindow ();
double[]
getMarkerHints();
}

View File

@ -1,5 +1,7 @@
package org.hwo.ui.diagram;
import org.hwo.ui.JDiagram;
public class SimplePlotLabeler implements PlotLabeler {
private int decimals;
@ -24,7 +26,7 @@ public class SimplePlotLabeler implements PlotLabeler {
@Override
public String getOrdinateLabel(Diagram diagram, Float value) {
public String getOrdinateLabel(JDiagram diagram, Double value) {
if (value == null)
return "";
if (value.isNaN())
@ -33,8 +35,8 @@ public class SimplePlotLabeler implements PlotLabeler {
}
@Override
public String getAbzisseLabel(Diagram diagram, int pos) {
return new Integer(pos).toString();
public String getAbzisseLabel(JDiagram diagram, Double pos) {
return String.format("%.4f", pos);
}
}

View File

@ -4,19 +4,21 @@ import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
public class SimplePlotProvider implements PlotProvider {
public class SimplePlotProvider implements PlotProvider2 {
int points;
int xmin;
ArrayList<Float[]> plots;
ArrayList<String> labels;
ArrayList<String> labels;
ArrayList<Integer> ordinates;
Color[] colors;
public SimplePlotProvider(int plots,int points) {
this.points = points;
this.plots = new ArrayList<Float[]>();
this.labels = new ArrayList<String>();
this.ordinates = new ArrayList<Integer>();
this.xmin = 0;
this.colors = new Color[plots];
@ -24,7 +26,8 @@ public class SimplePlotProvider implements PlotProvider {
this.plots.add(new Float[points]);
this.labels.add(String.format("Plot %d", i));
Arrays.fill(this.plots.get(i), 0.0f);
this.colors[i] = new Color(255,0,0);
this.colors[i] = null;
this.ordinates.add(0);
}
}
@ -34,33 +37,11 @@ public class SimplePlotProvider implements PlotProvider {
public void setXmin(int xmin) {
this.xmin = xmin;
}
@Override
public int getPoints() {
return this.points;
}
@Override
public int getPlots() {
return this.plots.size();
}
@Override
public Float[][] getMatrix() {
return this.plots.toArray(new Float[][]{});
}
@Override
public String getLabel(int plot) {
return this.labels.get(plot);
}
@Override
public String getPointLabel(int point) {
return String.format("%d", (this.xmin + point));
}
@Override
public Color[] getColors() {
@ -71,5 +52,56 @@ public class SimplePlotProvider implements PlotProvider {
Float[] cv = Arrays.copyOf(values, points);
this.plots.set(plot, cv);
}
public Float[] getPlot(int plot){
return this.plots.get(plot);
}
@Override
public int getMaxOrdinate() {
int m = 0;
for (Integer o:ordinates)
if (o > m)
m = o;
return m;
}
@Override
public int getLength() {
return this.points;
}
@Override
public int getNumGraphs() {
return this.plots.size();
}
@Override
public Float getValue(int x, int graph) {
return this.plots.get(graph)[x];
}
@Override
public Float getPosition(int x, int graph) {
return (float)x;
}
@Override
public int getOrdinate(int graph) {
return this.ordinates.get(graph);
}
public void setOrdinate(int graph,int ordinate) {
this.ordinates.set(graph, ordinate);
}
@Override
public Float getPositionMaximum() {
return (float)(this.points-1);
}
@Override
public Float getPositionMinimum() {
return (float)0;
}
}

View File

@ -13,4 +13,5 @@ public @interface Plot {
public int g() default 0;
public int b() default 0;
public int diagram() default 0;
}