Skip to content

Commit 1bf54bd

Browse files
committed
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+
}

0 commit comments

Comments
 (0)