Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1bf54bd

Browse files
committedApr 7, 2022
Merge branch 'plot-service'
This adds a JFreeChart-backed implementation for the SciJava PlotService.
2 parents 3c6062b + fa8b2f8 commit 1bf54bd

24 files changed

+2035
-2
lines changed
 

‎pom.xml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
<parent>
66
<groupId>org.scijava</groupId>
77
<artifactId>pom-scijava</artifactId>
8-
<version>31.0.0</version>
8+
<version>31.1.0</version>
99
<relativePath />
1010
</parent>
1111

1212
<artifactId>scijava-ui-swing</artifactId>
13-
<version>0.13.4-SNAPSHOT</version>
13+
<version>0.14.0-SNAPSHOT</version>
1414

1515
<name>SciJava UI: Swing</name>
1616
<description>SciJava user interface components for Java Swing.</description>
@@ -107,6 +107,8 @@
107107

108108
<jdatepicker.version>1.3.2</jdatepicker.version>
109109
<object-inspector.version>0.1</object-inspector.version>
110+
<scijava-plot.version>0.2.0</scijava-plot.version>
111+
<jfreesvg.version>3.2</jfreesvg.version>
110112
</properties>
111113

112114
<repositories>
@@ -126,6 +128,11 @@
126128
<groupId>org.scijava</groupId>
127129
<artifactId>scijava-table</artifactId>
128130
</dependency>
131+
<dependency>
132+
<groupId>org.scijava</groupId>
133+
<artifactId>scijava-plot</artifactId>
134+
<version>${scijava-plot.version}</version>
135+
</dependency>
129136
<dependency>
130137
<groupId>org.scijava</groupId>
131138
<artifactId>scijava-ui-awt</artifactId>
@@ -150,6 +157,15 @@
150157
<artifactId>jdatepicker</artifactId>
151158
<version>${jdatepicker.version}</version>
152159
</dependency>
160+
<dependency>
161+
<groupId>org.jfree</groupId>
162+
<artifactId>jfreechart</artifactId>
163+
</dependency>
164+
<dependency>
165+
<groupId>org.jfree</groupId>
166+
<artifactId>jfreesvg</artifactId>
167+
<version>${jfreesvg.version}</version>
168+
</dependency>
153169

154170
<!-- Test scope dependencies -->
155171
<dependency>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.scijava.ui.swing.plot.converter;
2+
3+
import org.jfree.chart.JFreeChart;
4+
import org.scijava.Priority;
5+
import org.scijava.convert.AbstractConverter;
6+
import org.scijava.convert.ConversionRequest;
7+
import org.scijava.convert.ConvertService;
8+
import org.scijava.convert.Converter;
9+
import org.scijava.plot.Plot;
10+
import org.scijava.plugin.Parameter;
11+
import org.scijava.plugin.Plugin;
12+
13+
import java.awt.geom.Rectangle2D;
14+
import java.awt.image.BufferedImage;
15+
16+
/**
17+
* Converter plugin, that converts an {@link Plot} to {@link BufferedImage}.
18+
*
19+
* @author Matthias Arzt
20+
* @see ConvertService
21+
*/
22+
@Plugin(type = Converter.class, priority = Priority.NORMAL_PRIORITY)
23+
public class PlotToBufferedImageConverter extends AbstractConverter<Plot, BufferedImage>
24+
{
25+
26+
@Parameter
27+
ConvertService convertService;
28+
29+
@Override
30+
public boolean canConvert(ConversionRequest request) {
31+
return request.destClass().isAssignableFrom( BufferedImage.class ) &&
32+
Plot.class.isAssignableFrom( request.sourceClass() ) &&
33+
convertService.supports(new ConversionRequest(
34+
request.sourceObject(), request.sourceType(), JFreeChart.class));
35+
}
36+
37+
@Override
38+
public <T> T convert(Object o, Class<T> aClass) {
39+
if(o instanceof Plot && BufferedImage.class.equals(aClass)) {
40+
@SuppressWarnings("unchecked")
41+
T t = (T) toBufferedImage((Plot) o);
42+
return t;
43+
}
44+
return null;
45+
}
46+
47+
private BufferedImage toBufferedImage(Plot plot) {
48+
BufferedImage image = new BufferedImage( plot.getPreferredWidth(), plot.getPreferredHeight(), BufferedImage.TYPE_INT_ARGB );
49+
JFreeChart chart = convertService.convert(plot, JFreeChart.class);
50+
chart.draw(image.createGraphics(), new Rectangle2D.Float(0, 0, image.getWidth(), image.getHeight()));
51+
return image;
52+
}
53+
54+
@Override
55+
public Class<BufferedImage> getOutputType() {
56+
return BufferedImage.class;
57+
}
58+
59+
@Override
60+
public Class<Plot> getInputType() {
61+
return Plot.class;
62+
}
63+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.scijava.ui.swing.plot.io;
2+
3+
import org.scijava.plot.Plot;
4+
import org.jfree.chart.JFreeChart;
5+
import org.jfree.graphics2d.svg.SVGGraphics2D;
6+
import org.jfree.graphics2d.svg.SVGUtils;
7+
import org.scijava.convert.ConvertService;
8+
import org.scijava.io.AbstractIOPlugin;
9+
import org.scijava.io.IOPlugin;
10+
import org.scijava.plugin.Parameter;
11+
import org.scijava.plugin.Plugin;
12+
13+
import java.awt.*;
14+
import java.io.File;
15+
import java.io.IOException;
16+
17+
/**
18+
* Plugin that can write {@link Plot} as SVG file.
19+
*
20+
* @author Matthias Arzt
21+
*/
22+
@Plugin(type = IOPlugin.class)
23+
public class PlotToSvgIOPlugin extends AbstractIOPlugin<Plot> {
24+
25+
@Parameter
26+
ConvertService convertService;
27+
28+
@Override
29+
public boolean supportsOpen(String source) {
30+
return false;
31+
}
32+
33+
@Override
34+
public boolean supportsSave(String destination) {
35+
return destination.endsWith(".svg");
36+
}
37+
38+
@Override
39+
public boolean supportsSave(Object data, String destination) {
40+
return supportsSave(destination) &&
41+
data instanceof Plot &&
42+
convertService.supports(data, JFreeChart.class);
43+
}
44+
45+
@Override
46+
public Plot open(String source) throws IOException {
47+
throw new UnsupportedOperationException();
48+
}
49+
50+
@Override
51+
public void save(Plot data, String destination) throws IOException {
52+
if(!supportsSave(data, destination))
53+
throw new IllegalArgumentException();
54+
JFreeChart chart = convertService.convert(data, JFreeChart.class);
55+
SVGGraphics2D g = new SVGGraphics2D(data.getPreferredWidth(), data.getPreferredWidth());
56+
chart.draw(g, new Rectangle(0, 0, g.getWidth(), g.getHeight()));
57+
SVGUtils.writeToSVG(new File(destination), g.getSVGElement());
58+
}
59+
60+
@Override
61+
public Class<Plot> getDataType() {
62+
return Plot.class;
63+
}
64+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.jfree.chart.ChartPanel;
35+
import org.jfree.chart.JFreeChart;
36+
import org.scijava.convert.ConvertService;
37+
import org.scijava.plot.Plot;
38+
import org.scijava.ui.viewer.DisplayWindow;
39+
import org.scijava.ui.viewer.plot.PlotDisplay;
40+
import org.scijava.ui.viewer.plot.PlotDisplayPanel;
41+
42+
import javax.swing.*;
43+
import java.awt.*;
44+
import java.util.Objects;
45+
46+
/**
47+
* A JFreeChart-driven display panel for {@link Plot}s.
48+
*
49+
* @author Curtis Rueden
50+
*/
51+
public class SwingPlotDisplayPanel extends JPanel implements PlotDisplayPanel
52+
{
53+
54+
// -- instance variables --
55+
56+
private final DisplayWindow window;
57+
private final PlotDisplay display;
58+
private final ConvertService convertService;
59+
private Dimension prefferedSize;
60+
61+
// -- constructor --
62+
63+
public SwingPlotDisplayPanel(final PlotDisplay display,
64+
final DisplayWindow window, final ConvertService convertService)
65+
{
66+
this.display = display;
67+
this.window = window;
68+
this.convertService = convertService;
69+
setLayout(new BorderLayout());
70+
initPreferredSize();
71+
setupChart();
72+
window.setContent(this);
73+
}
74+
75+
private void initPreferredSize() {
76+
Plot plot = display.get(0);
77+
prefferedSize = new Dimension(plot.getPreferredWidth(), plot.getPreferredHeight());
78+
}
79+
80+
private void setupChart() {
81+
final JFreeChart chart = convertToJFreeChart(display.get(0));
82+
add(new ChartPanel(chart));
83+
}
84+
85+
private JFreeChart convertToJFreeChart(Plot plot) {
86+
return Objects.requireNonNull(convertService.convert(plot, JFreeChart.class));
87+
}
88+
89+
public static boolean supports(Plot abstractPlot, ConvertService convertService) {
90+
return convertService.supports(abstractPlot, JFreeChart.class);
91+
}
92+
93+
// -- PlotDisplayPanel methods --
94+
95+
@Override
96+
public PlotDisplay getDisplay() {
97+
return display;
98+
}
99+
100+
// -- DisplayPanel methods --
101+
102+
@Override
103+
public DisplayWindow getWindow() {
104+
return window;
105+
}
106+
107+
@Override
108+
public void redoLayout() { }
109+
110+
@Override
111+
public void setLabel(final String s) { }
112+
113+
@Override
114+
public void redraw() { }
115+
116+
@Override
117+
public Dimension getPreferredSize() {
118+
return prefferedSize;
119+
}
120+
121+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.Plot;
35+
import org.scijava.ui.viewer.plot.AbstractPlotDisplayViewer;
36+
import org.scijava.convert.ConvertService;
37+
import org.scijava.display.Display;
38+
import org.scijava.plugin.Parameter;
39+
import org.scijava.plugin.Plugin;
40+
import org.scijava.ui.UserInterface;
41+
import org.scijava.ui.swing.SwingUI;
42+
import org.scijava.ui.viewer.DisplayViewer;
43+
import org.scijava.ui.viewer.DisplayWindow;
44+
import org.scijava.ui.viewer.plot.PlotDisplay;
45+
46+
/**
47+
* A Swing {@link Plot} display viewer, which displays plots using JFreeChart.
48+
*
49+
* @author Curtis Rueden
50+
*/
51+
@Plugin(type = DisplayViewer.class)
52+
public class SwingPlotDisplayViewer extends AbstractPlotDisplayViewer {
53+
54+
@Parameter
55+
ConvertService convertService;
56+
57+
@Override
58+
public boolean isCompatible(final UserInterface ui) {
59+
return ui instanceof SwingUI;
60+
}
61+
62+
@Override
63+
public boolean canView(final Display<?> d) {
64+
if(! (d instanceof PlotDisplay ))
65+
return false;
66+
Plot plot = ((PlotDisplay) d).get(0);
67+
return SwingPlotDisplayPanel.supports(plot, convertService);
68+
}
69+
70+
@Override
71+
public void view(final DisplayWindow w, final Display<?> d) {
72+
super.view(w, d);
73+
setPanel(new SwingPlotDisplayPanel(getDisplay(), w, convertService));
74+
}
75+
76+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.LineStyle;
35+
36+
import java.awt.*;
37+
38+
/**
39+
* @author Matthias Arzt
40+
*/
41+
42+
class AwtLineStyles {
43+
44+
private final boolean visible;
45+
46+
private final BasicStroke stroke;
47+
48+
private AwtLineStyles(boolean visible, BasicStroke stroke) {
49+
this.visible = visible;
50+
this.stroke = stroke;
51+
}
52+
53+
public boolean isVisible() {
54+
return visible;
55+
}
56+
57+
public BasicStroke getStroke() {
58+
return stroke;
59+
}
60+
61+
public static AwtLineStyles getInstance(LineStyle style) {
62+
if(style != null)
63+
switch (style) {
64+
case SOLID:
65+
return solid;
66+
case DASH:
67+
return dash;
68+
case DOT:
69+
return dot;
70+
case NONE:
71+
return none;
72+
}
73+
return solid;
74+
}
75+
76+
// --- Helper Constants ---
77+
78+
private static AwtLineStyles solid = new AwtLineStyles(true, Strokes.solid);
79+
80+
private static AwtLineStyles dash = new AwtLineStyles(true, Strokes.dash);
81+
82+
private static AwtLineStyles dot = new AwtLineStyles(true, Strokes.dot);
83+
84+
private static AwtLineStyles none = new AwtLineStyles(false, Strokes.none);
85+
86+
static class Strokes {
87+
88+
private static BasicStroke solid = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
89+
90+
private static BasicStroke dash = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
91+
.0f, new float[]{6.0f, 6.0f}, 0.0f);
92+
93+
private static BasicStroke dot = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
94+
.0f, new float[]{0.6f, 4.0f}, 0.0f);
95+
96+
private static BasicStroke none = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND,
97+
.0f, new float[]{0.0f, 100.0f}, 0.0f);
98+
}
99+
100+
}
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.MarkerStyle;
35+
36+
import java.awt.*;
37+
import java.awt.geom.Ellipse2D;
38+
import java.awt.geom.Path2D;
39+
import java.awt.geom.Rectangle2D;
40+
41+
/**
42+
* @author Matthias Arzt
43+
*/
44+
45+
class AwtMarkerStyles {
46+
47+
private final boolean visible;
48+
49+
private final boolean filled;
50+
51+
private final Shape shape;
52+
53+
private AwtMarkerStyles(boolean visible, boolean filled, Shape shape) {
54+
this.visible = visible;
55+
this.filled = filled;
56+
this.shape = shape;
57+
}
58+
59+
public boolean isVisible() {
60+
return visible;
61+
}
62+
63+
public boolean isFilled() {
64+
return filled;
65+
}
66+
67+
public Shape getShape() {
68+
return shape;
69+
}
70+
71+
public static AwtMarkerStyles getInstance(MarkerStyle style) {
72+
if(style != null)
73+
switch (style) {
74+
case NONE:
75+
return none;
76+
case PLUS:
77+
return plus;
78+
case X:
79+
return x;
80+
case STAR:
81+
return star;
82+
case SQUARE:
83+
return square;
84+
case FILLEDSQUARE:
85+
return filledSquare;
86+
case CIRCLE:
87+
return circle;
88+
case FILLEDCIRCLE:
89+
return filledCircle;
90+
}
91+
return square;
92+
}
93+
94+
// --- Helper Constants ---
95+
96+
private static AwtMarkerStyles none = new AwtMarkerStyles(false, false, null);
97+
98+
private static AwtMarkerStyles plus = new AwtMarkerStyles(true, false, Shapes.plus);
99+
100+
private static AwtMarkerStyles x = new AwtMarkerStyles(true, false, Shapes.x);
101+
102+
private static AwtMarkerStyles star = new AwtMarkerStyles(true, false, Shapes.star);
103+
104+
private static AwtMarkerStyles square = new AwtMarkerStyles(true, false, Shapes.square);
105+
106+
private static AwtMarkerStyles filledSquare = new AwtMarkerStyles(true, true, Shapes.square);
107+
108+
private static AwtMarkerStyles circle = new AwtMarkerStyles(true, false, Shapes.circle);
109+
110+
private static AwtMarkerStyles filledCircle = new AwtMarkerStyles(true, true, Shapes.circle);
111+
112+
113+
static private class Shapes {
114+
115+
private static Shape x = getAwtXShape();
116+
117+
private static Shape plus = getAwtPlusShape();
118+
119+
private static Shape star = getAwtStarShape();
120+
121+
private static Shape square = new Rectangle2D.Double(-3.0, -3.0, 6.0, 6.0);
122+
123+
private static Shape circle = new Ellipse2D.Double(-3.0, -3.0, 6.0, 6.0);
124+
125+
private static Shape getAwtXShape() {
126+
final Path2D p = new Path2D.Double();
127+
final double s = 3.0;
128+
p.moveTo(-s, -s);
129+
p.lineTo(s, s);
130+
p.moveTo(s, -s);
131+
p.lineTo(-s, s);
132+
return p;
133+
}
134+
135+
private static Shape getAwtPlusShape() {
136+
final Path2D p = new Path2D.Double();
137+
final double t = 4.0;
138+
p.moveTo(0, -t);
139+
p.lineTo(0, t);
140+
p.moveTo(t, 0);
141+
p.lineTo(-t, 0);
142+
return p;
143+
}
144+
145+
private static Shape getAwtStarShape() {
146+
final Path2D p = new Path2D.Double();
147+
final double s = 3.0;
148+
p.moveTo(-s, -s);
149+
p.lineTo(s, s);
150+
p.moveTo(s, -s);
151+
p.lineTo(-s, s);
152+
final double t = 4.0;
153+
p.moveTo(0, -t);
154+
p.lineTo(0, t);
155+
p.moveTo(t, 0);
156+
p.lineTo(-t, 0);
157+
return p;
158+
}
159+
160+
}
161+
162+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.CategoryChart;
35+
import org.jfree.chart.JFreeChart;
36+
import org.scijava.Priority;
37+
import org.scijava.convert.AbstractConverter;
38+
import org.scijava.convert.Converter;
39+
import org.scijava.plugin.Plugin;
40+
41+
/**
42+
* @author Matthias Arzt
43+
*/
44+
@Plugin(type = Converter.class, priority = Priority.NORMAL_PRIORITY)
45+
public class CategoryChartConverter extends AbstractConverter<CategoryChart, JFreeChart> {
46+
@SuppressWarnings("unchecked")
47+
@Override
48+
public <T> T convert(Object o, Class<T> aClass) {
49+
return (T) CategoryChartGenerator.run((CategoryChart) o);
50+
}
51+
52+
@Override
53+
public Class<JFreeChart> getOutputType() {
54+
return JFreeChart.class;
55+
}
56+
57+
@Override
58+
public Class<CategoryChart> getInputType() {
59+
return CategoryChart.class;
60+
}
61+
}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.BarSeries;
35+
import org.scijava.plot.BoxSeries;
36+
import org.scijava.plot.CategoryChart;
37+
import org.scijava.plot.CategoryChartItem;
38+
import org.scijava.plot.LineSeries;
39+
import org.scijava.plot.SeriesStyle;
40+
import org.jfree.chart.JFreeChart;
41+
import org.jfree.chart.axis.CategoryAxis;
42+
import org.jfree.chart.axis.CategoryLabelPositions;
43+
import org.jfree.chart.plot.CategoryPlot;
44+
import org.jfree.chart.renderer.category.*;
45+
import org.jfree.data.category.DefaultCategoryDataset;
46+
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
47+
import org.scijava.ui.awt.AWTColors;
48+
import org.scijava.util.ColorRGB;
49+
50+
import java.util.*;
51+
52+
/**
53+
* @author Matthias Arzt
54+
*/
55+
class CategoryChartGenerator {
56+
57+
private final CategoryChart chart;
58+
59+
private final Utils.SortedLabelFactory labelFactory = new Utils.SortedLabelFactory();
60+
61+
private final CategoryPlot jfcPlot = new CategoryPlot();
62+
63+
private final LineAndBarDataset lineData;
64+
65+
private final LineAndBarDataset barData;
66+
67+
private final BoxDataset boxData;
68+
69+
private CategoryChartGenerator(CategoryChart chart) {
70+
this.chart = chart;
71+
List<Utils.SortedLabel > categoryList = setupCategoryList();
72+
lineData = new LineAndBarDataset(new LineAndShapeRenderer(), categoryList);
73+
barData = new LineAndBarDataset(createFlatBarRenderer(), categoryList);
74+
boxData = new BoxDataset(categoryList);
75+
}
76+
77+
public static JFreeChart run(CategoryChart chart) {
78+
return new CategoryChartGenerator(chart).getJFreeChart();
79+
}
80+
81+
private List<Utils.SortedLabel > setupCategoryList() {
82+
List<?> categories = chart.getCategories();
83+
List<Utils.SortedLabel > categoryList = new ArrayList<>(categories.size());
84+
Utils.SortedLabelFactory categoryFactory = new Utils.SortedLabelFactory();
85+
for(Object category : categories)
86+
categoryList.add(categoryFactory.newLabel(category));
87+
return categoryList;
88+
}
89+
90+
private JFreeChart getJFreeChart() {
91+
jfcPlot.setDomainAxis(new CategoryAxis(chart.categoryAxis().getLabel()));
92+
jfcPlot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45);
93+
jfcPlot.setRangeAxis( Utils.getJFreeChartAxis(chart.numberAxis()));
94+
processAllSeries();
95+
lineData.addDatasetToPlot(0);
96+
boxData.addDatasetToPlot(1);
97+
barData.addDatasetToPlot(2);
98+
return Utils.setupJFreeChart(chart.getTitle(), jfcPlot);
99+
}
100+
101+
static private BarRenderer createFlatBarRenderer() {
102+
BarRenderer jfcBarRenderer = new BarRenderer();
103+
jfcBarRenderer.setBarPainter(new StandardBarPainter());
104+
jfcBarRenderer.setShadowVisible(false);
105+
return jfcBarRenderer;
106+
}
107+
108+
private void processAllSeries() {
109+
for(CategoryChartItem series : chart.getItems()) {
110+
if(series instanceof BarSeries )
111+
barData.addSeries((BarSeries) series);
112+
if(series instanceof LineSeries )
113+
lineData.addSeries((LineSeries) series);
114+
if(series instanceof BoxSeries )
115+
boxData.addBoxSeries((BoxSeries) series);
116+
}
117+
}
118+
119+
private class BoxDataset {
120+
121+
private final DefaultBoxAndWhiskerCategoryDataset jfcDataset;
122+
123+
private final BoxAndWhiskerRenderer jfcRenderer;
124+
125+
private final List<Utils.SortedLabel > categoryList;
126+
127+
BoxDataset(List<Utils.SortedLabel > categoryList) {
128+
jfcDataset = new DefaultBoxAndWhiskerCategoryDataset();
129+
jfcRenderer = new BoxAndWhiskerRenderer();
130+
jfcRenderer.setFillBox(false);
131+
this.categoryList = categoryList;
132+
setCategories();
133+
}
134+
135+
void addBoxSeries(BoxSeries series) {
136+
Utils.SortedLabel uniqueLabel = labelFactory.newLabel(series.getLabel());
137+
setSeriesData(uniqueLabel, series.getValues());
138+
setSeriesVisibility(uniqueLabel, true, series.getLegendVisible());
139+
setSeriesColor(uniqueLabel, series.getColor());
140+
}
141+
142+
143+
private void setCategories() {
144+
Utils.SortedLabel uniqueLabel = labelFactory.newLabel("dummy");
145+
for(Utils.SortedLabel category : categoryList)
146+
jfcDataset.add(Collections.emptyList(), uniqueLabel, category);
147+
setSeriesVisibility(uniqueLabel, false, false);
148+
}
149+
150+
private void setSeriesData(Utils.SortedLabel uniqueLabel, Map<?, ? extends Collection<Double>> data) {
151+
for(Utils.SortedLabel category : categoryList) {
152+
Collection<Double> value = data.get(category.getLabel());
153+
if(value != null)
154+
jfcDataset.add(new ArrayList<>(value), uniqueLabel, category);
155+
}
156+
}
157+
158+
private void setSeriesColor(Utils.SortedLabel uniqueLabel, ColorRGB color) {
159+
if(color == null)
160+
return;
161+
int index = jfcDataset.getRowIndex(uniqueLabel);
162+
if(index < 0)
163+
return;
164+
jfcRenderer.setSeriesPaint(index, AWTColors.getColor(color));
165+
}
166+
167+
private void setSeriesVisibility(Utils.SortedLabel uniqueLabel, boolean seriesVsisible, boolean legendVisible) {
168+
int index = jfcDataset.getRowIndex(uniqueLabel);
169+
if(index < 0)
170+
return;
171+
jfcRenderer.setSeriesVisible(index, seriesVsisible, false);
172+
jfcRenderer.setSeriesVisibleInLegend(index, legendVisible, false);
173+
}
174+
175+
176+
void addDatasetToPlot(int datasetIndex) {
177+
jfcPlot.setDataset(datasetIndex, jfcDataset);
178+
jfcPlot.setRenderer(datasetIndex, jfcRenderer);
179+
}
180+
181+
}
182+
183+
184+
private class LineAndBarDataset {
185+
186+
private final DefaultCategoryDataset jfcDataset;
187+
188+
private final AbstractCategoryItemRenderer jfcRenderer;
189+
190+
private final List<Utils.SortedLabel > categoryList;
191+
192+
LineAndBarDataset(AbstractCategoryItemRenderer renderer, List<Utils.SortedLabel > categoryList) {
193+
jfcDataset = new DefaultCategoryDataset();
194+
jfcRenderer = renderer;
195+
this.categoryList = categoryList;
196+
setCategories();
197+
}
198+
199+
private void setCategories() {
200+
Utils.SortedLabel uniqueLabel = labelFactory.newLabel("dummy");
201+
for(Utils.SortedLabel category : categoryList)
202+
jfcDataset.addValue(0.0, uniqueLabel, category);
203+
setSeriesVisibility(uniqueLabel, false, false);
204+
}
205+
206+
void addSeries(BarSeries series) {
207+
Utils.SortedLabel uniqueLabel = labelFactory.newLabel(series.getLabel());
208+
addSeriesData(uniqueLabel, series.getValues());
209+
setSeriesColor(uniqueLabel, series.getColor());
210+
setSeriesVisibility(uniqueLabel, true, series.getLegendVisible());
211+
}
212+
213+
void addSeries(LineSeries series) {
214+
Utils.SortedLabel uniqueLabel = labelFactory.newLabel(series.getLabel());
215+
addSeriesData(uniqueLabel, series.getValues());
216+
setSeriesStyle(uniqueLabel, series.getStyle());
217+
setSeriesVisibility(uniqueLabel, true, series.getLegendVisible());
218+
}
219+
220+
private void setSeriesVisibility(Utils.SortedLabel uniqueLabel, boolean seriesVsisible, boolean legendVisible) {
221+
int index = jfcDataset.getRowIndex(uniqueLabel);
222+
if(index < 0)
223+
return;
224+
jfcRenderer.setSeriesVisible(index, seriesVsisible, false);
225+
jfcRenderer.setSeriesVisibleInLegend(index, legendVisible, false);
226+
}
227+
228+
private void addSeriesData(Utils.SortedLabel uniqueLabel, Map<?, Double> values) {
229+
for(Utils.SortedLabel category : categoryList) {
230+
Double value = values.get(category.getLabel());
231+
if(value != null)
232+
jfcDataset.addValue(value, uniqueLabel, category);
233+
}
234+
}
235+
236+
private void setSeriesStyle(Utils.SortedLabel uniqueLabel, SeriesStyle style) {
237+
if(style == null)
238+
return;
239+
int index = jfcDataset.getRowIndex(uniqueLabel);
240+
if(index < 0)
241+
return;
242+
RendererModifier.wrap(jfcRenderer).setSeriesStyle(index, style);
243+
}
244+
245+
private void setSeriesColor(Utils.SortedLabel uniqueLabel, ColorRGB style) {
246+
if(style == null)
247+
return;
248+
int index = jfcDataset.getRowIndex(uniqueLabel);
249+
if(index < 0)
250+
return;
251+
RendererModifier.wrap(jfcRenderer).setSeriesColor(index, style);
252+
}
253+
254+
void addDatasetToPlot(int datasetIndex) {
255+
jfcPlot.setDataset(datasetIndex, jfcDataset);
256+
jfcPlot.setRenderer(datasetIndex, jfcRenderer);
257+
}
258+
259+
}
260+
261+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.LineStyle;
35+
import org.scijava.plot.MarkerStyle;
36+
import org.scijava.plot.SeriesStyle;
37+
import org.jfree.chart.renderer.AbstractRenderer;
38+
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
39+
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
40+
import org.scijava.ui.awt.AWTColors;
41+
import org.scijava.util.ColorRGB;
42+
43+
/**
44+
* @author Matthias Arzt
45+
*/
46+
class RendererModifier {
47+
48+
final AbstractRenderer renderer;
49+
50+
private RendererModifier(AbstractRenderer renderer) {
51+
this.renderer = renderer;
52+
}
53+
54+
static public RendererModifier wrap(AbstractRenderer renderer) {
55+
return new RendererModifier(renderer);
56+
}
57+
58+
public void setSeriesStyle(int index, SeriesStyle style) {
59+
if(style == null)
60+
return;
61+
setSeriesColor(index, style.getColor());
62+
setSeriesLineStyle(index, style.getLineStyle());
63+
setSeriesMarkerStyle(index, style.getMarkerStyle());
64+
}
65+
66+
public void setSeriesColor(int index, ColorRGB color) {
67+
if (color == null)
68+
return;
69+
renderer.setSeriesPaint(index, AWTColors.getColor(color));
70+
}
71+
72+
public void setSeriesLineStyle(int index, LineStyle style) {
73+
AwtLineStyles line = AwtLineStyles.getInstance(style);
74+
setSeriesLinesVisible(index, line.isVisible());
75+
renderer.setSeriesStroke(index, line.getStroke());
76+
}
77+
78+
public void setSeriesMarkerStyle(int index, MarkerStyle style) {
79+
AwtMarkerStyles marker = AwtMarkerStyles.getInstance(style);
80+
setSeriesShapesVisible(index, marker.isVisible());
81+
setSeriesShapesFilled(index, marker.isFilled());
82+
renderer.setSeriesShape(index, marker.getShape());
83+
}
84+
85+
private void setSeriesLinesVisible(int index, boolean visible) {
86+
if(renderer instanceof LineAndShapeRenderer)
87+
((LineAndShapeRenderer) renderer).setSeriesLinesVisible(index, visible);
88+
if(renderer instanceof XYLineAndShapeRenderer)
89+
((XYLineAndShapeRenderer) renderer).setSeriesLinesVisible(index, visible);
90+
}
91+
92+
private void setSeriesShapesVisible(int index, boolean visible) {
93+
if(renderer instanceof LineAndShapeRenderer)
94+
((LineAndShapeRenderer) renderer).setSeriesShapesVisible(index, visible);
95+
if(renderer instanceof XYLineAndShapeRenderer)
96+
((XYLineAndShapeRenderer) renderer).setSeriesShapesVisible(index, visible);
97+
}
98+
99+
private void setSeriesShapesFilled(int index, boolean filled) {
100+
if(renderer instanceof LineAndShapeRenderer)
101+
((LineAndShapeRenderer) renderer).setSeriesShapesFilled(index, filled);
102+
if(renderer instanceof XYLineAndShapeRenderer)
103+
((XYLineAndShapeRenderer) renderer).setSeriesShapesFilled(index, filled);
104+
}
105+
106+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.NumberAxis;
35+
import org.scijava.plot.NumberAxis.RangeStrategy;
36+
import org.jfree.chart.JFreeChart;
37+
import org.jfree.chart.axis.LogAxis;
38+
import org.jfree.chart.axis.ValueAxis;
39+
import org.jfree.chart.block.BlockBorder;
40+
import org.jfree.chart.plot.Plot;
41+
42+
import java.awt.*;
43+
import java.util.Objects;
44+
45+
/**
46+
* @author Matthias Arzt
47+
*/
48+
class Utils {
49+
50+
static JFreeChart setupJFreeChart(String title, Plot plot) {
51+
JFreeChart chart = new JFreeChart(plot);
52+
chart.setTitle(title);
53+
chart.setBackgroundPaint(Color.WHITE);
54+
chart.getLegend().setFrame(BlockBorder.NONE);
55+
return chart;
56+
}
57+
58+
static ValueAxis getJFreeChartAxis(NumberAxis v) {
59+
if(v.isLogarithmic())
60+
return getJFreeChartLogarithmicAxis(v);
61+
else
62+
return getJFreeCharLinearAxis(v);
63+
}
64+
65+
static ValueAxis getJFreeChartLogarithmicAxis(NumberAxis v) {
66+
LogAxis axis = new LogAxis(v.getLabel());
67+
switch (v.getRangeStrategy()) {
68+
case MANUAL:
69+
axis.setRange(v.getMin(), v.getMax());
70+
break;
71+
default:
72+
axis.setAutoRange(true);
73+
}
74+
return axis;
75+
}
76+
77+
static ValueAxis getJFreeCharLinearAxis(NumberAxis v) {
78+
org.jfree.chart.axis.NumberAxis axis = new org.jfree.chart.axis.NumberAxis(v.getLabel());
79+
switch(v.getRangeStrategy()) {
80+
case MANUAL:
81+
axis.setRange(v.getMin(), v.getMax());
82+
break;
83+
case AUTO:
84+
axis.setAutoRange(true);
85+
axis.setAutoRangeIncludesZero(false);
86+
break;
87+
case AUTO_INCLUDE_ZERO:
88+
axis.setAutoRange(true);
89+
axis.setAutoRangeIncludesZero(true);
90+
break;
91+
default:
92+
axis.setAutoRange(true);
93+
}
94+
return axis;
95+
}
96+
97+
static class SortedLabelFactory {
98+
private int n;
99+
SortedLabelFactory() { n = 0; }
100+
SortedLabel newLabel(Object label) { return new SortedLabel(n++, label); }
101+
}
102+
103+
static class SortedLabel implements Comparable<SortedLabel> {
104+
private final Object label;
105+
private final int id;
106+
SortedLabel(final int id, final Object label) { this.label = Objects.requireNonNull(label); this.id = id; }
107+
@Override public String toString() { return label.toString(); }
108+
@Override public int compareTo(SortedLabel o) { return Integer.compare(id, o.id); }
109+
public Object getLabel() { return label; }
110+
}
111+
112+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.XYPlot;
35+
import org.jfree.chart.JFreeChart;
36+
import org.scijava.Priority;
37+
import org.scijava.convert.AbstractConverter;
38+
import org.scijava.convert.Converter;
39+
import org.scijava.plugin.Plugin;
40+
41+
/**
42+
* @author Matthias.Arzt
43+
*/
44+
@Plugin(type = Converter.class, priority = Priority.NORMAL_PRIORITY)
45+
public class XYPlotConverter extends AbstractConverter<XYPlot, JFreeChart> {
46+
@SuppressWarnings("unchecked")
47+
@Override
48+
public <T> T convert(Object o, Class<T> aClass) {
49+
return (T) XYPlotGenerator.run((XYPlot) o);
50+
}
51+
52+
@Override
53+
public Class<JFreeChart> getOutputType() {
54+
return JFreeChart.class;
55+
}
56+
57+
@Override
58+
public Class<XYPlot> getInputType() {
59+
return XYPlot.class;
60+
}
61+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot.jfreechart;
33+
34+
import org.scijava.plot.SeriesStyle;
35+
import org.scijava.plot.XYPlot;
36+
import org.scijava.plot.XYPlotItem;
37+
import org.scijava.plot.XYSeries;
38+
import org.jfree.chart.JFreeChart;
39+
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
40+
import org.jfree.data.xy.XYSeriesCollection;
41+
42+
import java.util.Collection;
43+
import java.util.Iterator;
44+
45+
import static org.scijava.ui.swing.viewer.plot.jfreechart.Utils.*;
46+
47+
/**
48+
* @author Matthias Arzt
49+
*/
50+
class XYPlotGenerator {
51+
52+
private final XYPlot xyPlot;
53+
54+
private final SortedLabelFactory sortedLabelFactory = new SortedLabelFactory();
55+
56+
private final org.jfree.chart.plot.XYPlot jfcPlot = new org.jfree.chart.plot.XYPlot();
57+
58+
private final XYSeriesCollection jfcDataSet = new XYSeriesCollection();
59+
60+
private final XYLineAndShapeRenderer jfcRenderer = new XYLineAndShapeRenderer();
61+
62+
private XYPlotGenerator(XYPlot xyPlot) {
63+
this.xyPlot = xyPlot;
64+
}
65+
66+
public static JFreeChart run(XYPlot xyPlot) { return new XYPlotGenerator(xyPlot).getJFreeChart();
67+
}
68+
69+
private JFreeChart getJFreeChart() {
70+
jfcPlot.setDataset(jfcDataSet);
71+
jfcPlot.setDomainAxis(getJFreeChartAxis(xyPlot.xAxis()));
72+
jfcPlot.setRangeAxis(getJFreeChartAxis(xyPlot.yAxis()));
73+
jfcPlot.setRenderer(jfcRenderer);
74+
addAllSeries();
75+
return Utils.setupJFreeChart(xyPlot.getTitle(), jfcPlot);
76+
}
77+
78+
private void addAllSeries() {
79+
for(XYPlotItem series : xyPlot.getItems())
80+
if(series instanceof XYSeries )
81+
addSeries((XYSeries) series);
82+
}
83+
84+
private void addSeries(XYSeries series) {
85+
SortedLabel uniqueLabel = sortedLabelFactory.newLabel(series.getLabel());
86+
addSeriesData(uniqueLabel, series.getXValues(), series.getYValues());
87+
setSeriesStyle(uniqueLabel, series.getStyle(), series.getLegendVisible());
88+
}
89+
90+
private void addSeriesData(SortedLabel uniqueLabel, Collection<Double> xs, Collection<Double> ys) {
91+
org.jfree.data.xy.XYSeries series = new org.jfree.data.xy.XYSeries(uniqueLabel, false, true);
92+
Iterator<Double> xi = xs.iterator();
93+
Iterator<Double> yi = ys.iterator();
94+
while (xi.hasNext() && yi.hasNext())
95+
series.add(xi.next(), yi.next());
96+
jfcDataSet.addSeries(series);
97+
}
98+
99+
private void setSeriesStyle(SortedLabel label, SeriesStyle style, boolean legendVisible) {
100+
if (style == null)
101+
return;
102+
int index = jfcDataSet.getSeriesIndex(label);
103+
RendererModifier.wrap(jfcRenderer).setSeriesStyle(index, style);
104+
jfcRenderer.setSeriesVisibleInLegend(index, legendVisible);
105+
}
106+
107+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.scijava.ui.swing.plot.converter;
2+
3+
import org.junit.Test;
4+
import org.scijava.Context;
5+
import org.scijava.convert.ConvertService;
6+
import org.scijava.plot.PlotService;
7+
import org.scijava.plot.XYPlot;
8+
9+
import java.awt.image.BufferedImage;
10+
11+
import static org.junit.Assert.assertEquals;
12+
13+
public class PlotToBufferedImageConverterTest
14+
{
15+
16+
@Test
17+
public void test() {
18+
// setup
19+
Context context = new Context( PlotService.class, ConvertService.class );
20+
PlotService plotService = context.service( PlotService.class );
21+
ConvertService convertService = context.service( ConvertService.class );
22+
XYPlot plot = plotService.newXYPlot();
23+
// process
24+
BufferedImage image = convertService.convert( plot, BufferedImage.class );
25+
// test
26+
assertEquals(plot.getPreferredWidth(), image.getWidth());
27+
assertEquals(plot.getPreferredHeight(), image.getHeight());
28+
// dispose
29+
context.dispose();
30+
}
31+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.scijava.ui.swing.plot.io;
2+
3+
import org.scijava.Context;
4+
import org.scijava.io.IOService;
5+
import org.scijava.plot.Plot;
6+
import org.scijava.plot.PlotService;
7+
import org.scijava.plot.XYPlot;
8+
import org.scijava.plot.XYSeries;
9+
import org.scijava.plugin.Parameter;
10+
11+
import java.io.IOException;
12+
import java.nio.file.Path;
13+
import java.nio.file.Paths;
14+
import java.util.List;
15+
import java.util.stream.Collectors;
16+
import java.util.stream.IntStream;
17+
18+
/**
19+
* @author
20+
*/
21+
public class PlotToSvgDemo {
22+
23+
@Parameter
24+
private PlotService plotService;
25+
26+
@Parameter
27+
private IOService ioService;
28+
29+
public static void main(String... args) throws IOException {
30+
PlotToSvgDemo demo = new PlotToSvgDemo();
31+
new Context().inject(demo);
32+
demo.run();
33+
}
34+
35+
private void run() throws IOException {
36+
Path path = Paths.get(System.getProperty("user.home"), "chart.svg");
37+
Plot plot = getExamplePlot();
38+
ioService.save(plot, path.toString());
39+
System.out.println("Plot saved as " + path.toString());
40+
}
41+
42+
private Plot getExamplePlot() {
43+
XYPlot plot = plotService.newXYPlot();
44+
plot.setTitle("Hello World!");
45+
plot.xAxis().setLabel("x");
46+
plot.yAxis().setLabel("y");
47+
List<Double> xs = IntStream.rangeClosed(0, 100).mapToObj(x -> (double) x * 2. * Math.PI / 100.).collect(Collectors.toList());
48+
List<Double> ys = xs.stream().map(Math::sin).collect(Collectors.toList());
49+
XYSeries series = plot.addXYSeries();
50+
series.setLabel("y = sin(x)");
51+
series.setValues( xs, ys );
52+
return plot;
53+
}
54+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
/**
35+
* @author Matthias Arzt
36+
*/
37+
public class AllDemos {
38+
39+
public static void main(final String... args) {
40+
new BoxPlotDemo().run();
41+
new CategoryChartDemo().run();
42+
new LineStyleDemo().run();
43+
new LogarithmicAxisDemo().run();
44+
new MarkerStyleDemo().run();
45+
new SortingCategoriesDemo().run();
46+
new XYPlotDemo().run();
47+
}
48+
49+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.BoxSeries;
35+
import org.scijava.plot.CategoryChart;
36+
import org.scijava.util.Colors;
37+
38+
import java.util.*;
39+
40+
/**
41+
* @author Matthias Arzt
42+
*/
43+
class BoxPlotDemo extends ChartDemo{
44+
45+
public void run() {
46+
CategoryChart chart = plotService.newCategoryChart();
47+
48+
Map<String, Collection<Double>> randomData1 = new TreeMap<>();
49+
randomData1.put("A", collectionOfRandomNumbers(10));
50+
randomData1.put("B", collectionOfRandomNumbers(20));
51+
randomData1.put("C", collectionOfRandomNumbers(30));
52+
53+
BoxSeries boxSeries1 = chart.addBoxSeries();
54+
boxSeries1.setLabel("boxes1");
55+
boxSeries1.setValues(randomData1);
56+
boxSeries1.setColor(Colors.CYAN);
57+
58+
Map<String, Collection<Double>> randomData2 = new TreeMap<>();
59+
randomData2.put("A", collectionOfRandomNumbers(10));
60+
randomData2.put("B", collectionOfRandomNumbers(20));
61+
randomData2.put("C", collectionOfRandomNumbers(30));
62+
63+
BoxSeries boxSeries2 = chart.addBoxSeries();
64+
boxSeries2.setLabel("boxes2");
65+
boxSeries2.setValues(randomData2);
66+
boxSeries2.setColor(Colors.BLACK);
67+
68+
ui.show(chart);
69+
}
70+
71+
private static Collection<Double> collectionOfRandomNumbers(int size) {
72+
Random rand = new Random();
73+
Vector<Double> result = new Vector<>(size);
74+
for(int i = 0; i < size; i++)
75+
result.add(rand.nextGaussian()*20);
76+
return result;
77+
}
78+
79+
public static void main(final String... args) {
80+
new BoxPlotDemo().run();
81+
}
82+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.BarSeries;
35+
import org.scijava.plot.CategoryChart;
36+
import org.scijava.plot.LineSeries;
37+
38+
import java.util.Arrays;
39+
import java.util.HashMap;
40+
import java.util.Map;
41+
42+
/**
43+
* @author Matthias Arzt
44+
*/
45+
class CategoryChartDemo extends ChartDemo{
46+
47+
public void run() {
48+
49+
CategoryChart chart = plotService.newCategoryChart();
50+
chart.categoryAxis().setManualCategories(Arrays.asList("one wheel", "bicycle", "car"));
51+
52+
Map<String, Double> wheelsData = new HashMap<>();
53+
wheelsData.put("one wheel", 1.0);
54+
wheelsData.put("bicycle", 2.0);
55+
wheelsData.put("car", 4.0);
56+
57+
LineSeries lineSeries = chart.addLineSeries();
58+
lineSeries.setLabel("wheels");
59+
lineSeries.setValues(wheelsData);
60+
61+
Map<String, Double> speedData = new HashMap<>();
62+
speedData.put("one wheel", 10.0);
63+
speedData.put("bicycle", 30.0);
64+
speedData.put("car", 200.0);
65+
66+
BarSeries barSeries = chart.addBarSeries();
67+
barSeries.setLabel("speed");
68+
barSeries.setValues(speedData);
69+
70+
ui.show(chart);
71+
}
72+
73+
public static void main(final String... args) {
74+
new CategoryChartDemo().run();
75+
}
76+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.Context;
35+
import org.scijava.plot.PlotService;
36+
import org.scijava.plugin.Parameter;
37+
import org.scijava.ui.UIService;
38+
39+
/**
40+
* @author Matthias Arzt
41+
*/
42+
class ChartDemo {
43+
44+
@Parameter
45+
public UIService ui;
46+
47+
@Parameter
48+
public PlotService plotService;
49+
50+
ChartDemo() {
51+
new Context().inject( this );
52+
}
53+
54+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.LineStyle;
35+
import org.scijava.plot.MarkerStyle;
36+
import org.scijava.plot.XYPlot;
37+
import org.scijava.plot.XYSeries;
38+
import org.scijava.util.Colors;
39+
40+
import java.util.Arrays;
41+
42+
/**
43+
* @author Matthias Arzt
44+
*/
45+
class LineStyleDemo extends ChartDemo {
46+
47+
48+
public void run() {
49+
LineStyle[] lineStyles = LineStyle.values();
50+
51+
XYPlot plot = plotService.newXYPlot();
52+
plot.setTitle("Line Styles");
53+
plot.xAxis().setManualRange(-1.0, 2.0);
54+
plot.yAxis().setManualRange(-1.0, (double) lineStyles.length);
55+
56+
for(int i = 0; i < lineStyles.length; i++)
57+
addSeries(plot, i, lineStyles[i]);
58+
59+
ui.show(plot);
60+
}
61+
62+
private void addSeries(XYPlot plot, double y, LineStyle lineStyle) {
63+
XYSeries series = plot.addXYSeries();
64+
series.setLabel(lineStyle.toString());
65+
series.setValues(Arrays.asList(0.0,1.0), Arrays.asList(y,y));
66+
series.setStyle(plotService.newSeriesStyle(Colors.BLACK, lineStyle, MarkerStyle.CIRCLE));
67+
}
68+
69+
public static void main(final String... args) {
70+
new LineStyleDemo().run();
71+
}
72+
73+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.XYPlot;
35+
import org.scijava.plot.XYSeries;
36+
37+
import java.util.ArrayList;
38+
import java.util.List;
39+
40+
/**
41+
* @author Matthias Arzt
42+
*/
43+
class LogarithmicAxisDemo extends ChartDemo {
44+
45+
public void run() {
46+
47+
XYPlot plot = plotService.newXYPlot();
48+
plot.setTitle("Logarithmic");
49+
plot.xAxis().setAutoRange();
50+
plot.yAxis().setAutoRange();
51+
plot.yAxis().setLogarithmic(true);
52+
53+
List<Double> xs = new ArrayList<>();
54+
List<Double> ys = new ArrayList<>();
55+
for(double x = 0; x < 10; x += 0.1) {
56+
xs.add(x);
57+
ys.add(Math.exp(Math.sin(x)));
58+
}
59+
60+
XYSeries series = plot.addXYSeries();
61+
series.setLabel("exp(sin(x))");
62+
series.setValues(xs, ys);
63+
64+
ui.show(plot);
65+
}
66+
67+
public static void main(final String... args) {
68+
new LogarithmicAxisDemo().run();
69+
}
70+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.MarkerStyle;
35+
import org.scijava.plot.XYPlot;
36+
import org.scijava.plot.XYSeries;
37+
38+
import java.util.Arrays;
39+
40+
/**
41+
* @author Matthias Arzt
42+
*/
43+
class MarkerStyleDemo extends ChartDemo {
44+
45+
public void run() {
46+
MarkerStyle[] markerStyles = MarkerStyle.values();
47+
48+
XYPlot plot = plotService.newXYPlot();
49+
plot.setTitle("Marker Styles");
50+
plot.xAxis().setManualRange(-1.0, 2.0);
51+
plot.yAxis().setManualRange(-1.0, (double) markerStyles.length);
52+
53+
for(int i = 0; i < markerStyles.length; i++)
54+
addSeries(plot, i, markerStyles[i]);
55+
56+
ui.show(plot);
57+
}
58+
59+
private void addSeries(XYPlot plot, double y, MarkerStyle markerStyle) {
60+
XYSeries series = plot.addXYSeries();
61+
series.setLabel(markerStyle.toString());
62+
series.setValues(Arrays.asList(0.0, 1.0), Arrays.asList(y,y));
63+
series.setStyle(plotService.newSeriesStyle(null, null, markerStyle));
64+
}
65+
66+
public static void main(final String... args) {
67+
new MarkerStyleDemo().run();
68+
}
69+
70+
}
71+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.BarSeries;
35+
import org.scijava.plot.CategoryAxis;
36+
import org.scijava.plot.CategoryChart;
37+
38+
import java.util.Arrays;
39+
import java.util.Collections;
40+
import java.util.Map;
41+
import java.util.TreeMap;
42+
43+
/**
44+
* @author Matthias Arzt
45+
*/
46+
47+
class SortingCategoriesDemo extends ChartDemo {
48+
49+
public void run() {
50+
showSortedCategoryChart( axis -> {
51+
axis.setManualCategories(Arrays.asList("a","c","b"));
52+
axis.setLabel("acb");
53+
} );
54+
showSortedCategoryChart( axis -> {
55+
axis.setManualCategories(Arrays.asList("a","g","c","b"));
56+
axis.setLabel("agcb");
57+
} );
58+
showSortedCategoryChart( axis -> {
59+
axis.setManualCategories(Arrays.asList("d","c","a","b"));
60+
axis.setOrder( String::compareTo );
61+
axis.setLabel("abcd");
62+
} );
63+
showSortedCategoryChart( axis -> {
64+
axis.setManualCategories(Collections.emptyList());
65+
axis.setOrder( String::compareTo );
66+
axis.setLabel("empty");
67+
} );
68+
}
69+
70+
private interface AxisManipulator {
71+
void manipulate( CategoryAxis axis );
72+
}
73+
74+
private void showSortedCategoryChart(AxisManipulator categoryAxisManipulator) {
75+
CategoryChart chart = plotService.newCategoryChart();
76+
categoryAxisManipulator.manipulate(chart.categoryAxis());
77+
78+
Map<String, Double> data = new TreeMap<>();
79+
data.put("a", 1.0);
80+
data.put("b", 2.0);
81+
data.put("c", 3.0);
82+
data.put("d", 4.0);
83+
84+
BarSeries bars = chart.addBarSeries();
85+
bars.setValues(data);
86+
87+
ui.show(chart);
88+
}
89+
90+
public static void main(final String... args) {
91+
new SortingCategoriesDemo().run();
92+
}
93+
94+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* #%L
3+
* ImageJ software for multidimensional image processing and analysis.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.ui.swing.viewer.plot;
33+
34+
import org.scijava.plot.XYPlot;
35+
import org.scijava.plot.XYSeries;
36+
37+
import java.util.ArrayList;
38+
import java.util.List;
39+
40+
/**
41+
* @author Matthias Arzt
42+
*/
43+
class XYPlotDemo extends ChartDemo {
44+
45+
public void run() {
46+
XYPlot plot = plotService.newXYPlot();
47+
plot.setTitle("A series forming a circle.");
48+
plot.xAxis().setAutoRange();
49+
plot.yAxis().setAutoRange();
50+
plot.setPreferredSize(400, 400);
51+
52+
List<Double> xs = new ArrayList<>();
53+
List<Double> ys = new ArrayList<>();
54+
for(double t = 0; t < 2 * Math.PI; t += 0.1) {
55+
xs.add(Math.sin(t));
56+
ys.add(Math.cos(t));
57+
}
58+
59+
XYSeries series = plot.addXYSeries();
60+
series.setLabel("circle");
61+
series.setValues(xs, ys);
62+
63+
ui.show(plot);
64+
}
65+
66+
public static void main(final String... args) {
67+
new XYPlotDemo().run();
68+
}
69+
}

0 commit comments

Comments
 (0)
Please sign in to comment.