Merge pull request #981 from SiboVG/better-plot
This commit is contained in:
commit
8721059361
@ -57,7 +57,7 @@ public class SimulationChart extends ChartPanel {
|
|||||||
/* tooltips */true);
|
/* tooltips */true);
|
||||||
this.setMouseWheelEnabled(true);
|
this.setMouseWheelEnabled(true);
|
||||||
this.setEnforceFileExtensions(true);
|
this.setEnforceFileExtensions(true);
|
||||||
this.setInitialDelay(500);
|
this.setInitialDelay(50);
|
||||||
this.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
|
this.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,10 @@ import java.awt.Stroke;
|
|||||||
import java.awt.geom.Line2D;
|
import java.awt.geom.Line2D;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.util.ArrayList;
|
import java.text.DecimalFormat;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
import java.util.regex.Matcher;
|
||||||
import java.util.HashSet;
|
import java.util.regex.Pattern;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import net.sf.openrocket.document.Simulation;
|
import net.sf.openrocket.document.Simulation;
|
||||||
import net.sf.openrocket.gui.simulation.SimulationPlotPanel;
|
import net.sf.openrocket.gui.simulation.SimulationPlotPanel;
|
||||||
@ -36,7 +35,8 @@ import org.jfree.chart.LegendItemSource;
|
|||||||
import org.jfree.chart.annotations.XYImageAnnotation;
|
import org.jfree.chart.annotations.XYImageAnnotation;
|
||||||
import org.jfree.chart.axis.NumberAxis;
|
import org.jfree.chart.axis.NumberAxis;
|
||||||
import org.jfree.chart.axis.ValueAxis;
|
import org.jfree.chart.axis.ValueAxis;
|
||||||
import org.jfree.chart.block.LineBorder;
|
import org.jfree.chart.block.BlockBorder;
|
||||||
|
import org.jfree.chart.labels.StandardXYToolTipGenerator;
|
||||||
import org.jfree.chart.plot.DefaultDrawingSupplier;
|
import org.jfree.chart.plot.DefaultDrawingSupplier;
|
||||||
import org.jfree.chart.plot.Marker;
|
import org.jfree.chart.plot.Marker;
|
||||||
import org.jfree.chart.plot.PlotOrientation;
|
import org.jfree.chart.plot.PlotOrientation;
|
||||||
@ -47,6 +47,8 @@ import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
|
|||||||
import org.jfree.chart.title.LegendTitle;
|
import org.jfree.chart.title.LegendTitle;
|
||||||
import org.jfree.chart.title.TextTitle;
|
import org.jfree.chart.title.TextTitle;
|
||||||
import org.jfree.data.Range;
|
import org.jfree.data.Range;
|
||||||
|
import org.jfree.data.xy.XYDataItem;
|
||||||
|
import org.jfree.data.xy.XYDataset;
|
||||||
import org.jfree.data.xy.XYSeries;
|
import org.jfree.data.xy.XYSeries;
|
||||||
import org.jfree.data.xy.XYSeriesCollection;
|
import org.jfree.data.xy.XYSeriesCollection;
|
||||||
import org.jfree.text.TextUtilities;
|
import org.jfree.text.TextUtilities;
|
||||||
@ -114,13 +116,15 @@ public class SimulationPlot {
|
|||||||
/*legend*/false,
|
/*legend*/false,
|
||||||
/*tooltips*/true,
|
/*tooltips*/true,
|
||||||
/*urls*/false
|
/*urls*/false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
chart.getTitle().setFont(new Font("Dialog", Font.BOLD, 23));
|
||||||
|
chart.setBackgroundPaint(new Color(240, 240, 240));
|
||||||
this.legendItems = new LegendItems();
|
this.legendItems = new LegendItems();
|
||||||
LegendTitle legend = new LegendTitle(legendItems);
|
LegendTitle legend = new LegendTitle(legendItems);
|
||||||
legend.setMargin(new RectangleInsets(1.0, 1.0, 1.0, 1.0));
|
legend.setMargin(new RectangleInsets(1.0, 1.0, 1.0, 1.0));
|
||||||
legend.setFrame(new LineBorder());
|
legend.setFrame(BlockBorder.NONE);
|
||||||
legend.setBackgroundPaint(Color.white);
|
legend.setBackgroundPaint(new Color(240, 240, 240));
|
||||||
legend.setPosition(RectangleEdge.BOTTOM);
|
legend.setPosition(RectangleEdge.BOTTOM);
|
||||||
chart.addSubtitle(legend);
|
chart.addSubtitle(legend);
|
||||||
|
|
||||||
@ -222,7 +226,23 @@ public class SimulationPlot {
|
|||||||
plot.setDomainPannable(true);
|
plot.setDomainPannable(true);
|
||||||
plot.setRangePannable(true);
|
plot.setRangePannable(true);
|
||||||
|
|
||||||
|
// Plot appearance
|
||||||
|
plot.setBackgroundPaint(Color.white);
|
||||||
|
plot.setAxisOffset(new RectangleInsets(0, 0, 0, 0));
|
||||||
|
plot.setRangeGridlinesVisible(true);
|
||||||
|
plot.setRangeGridlinePaint(Color.lightGray);
|
||||||
|
|
||||||
|
plot.setDomainGridlinesVisible(true);
|
||||||
|
plot.setDomainGridlinePaint(Color.lightGray);
|
||||||
|
|
||||||
int axisno = 0;
|
int axisno = 0;
|
||||||
|
Color[] colors = {new Color(0,114,189), // Colors for data lines
|
||||||
|
new Color(217,83,25),
|
||||||
|
new Color(237,177,32),
|
||||||
|
new Color(126,49,142),
|
||||||
|
new Color(119,172,48),
|
||||||
|
new Color(77,190,238),
|
||||||
|
new Color(162,20,47)};
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
// Check whether axis has any data
|
// Check whether axis has any data
|
||||||
if (data[i].getSeriesCount() > 0) {
|
if (data[i].getSeriesCount() > 0) {
|
||||||
@ -233,19 +253,57 @@ public class SimulationPlot {
|
|||||||
axis.setLabel(axisLabel[i]);
|
axis.setLabel(axisLabel[i]);
|
||||||
// axis.setRange(axes.get(i).getMinValue(), axes.get(i).getMaxValue());
|
// axis.setRange(axes.get(i).getMinValue(), axes.get(i).getMaxValue());
|
||||||
plot.setRangeAxis(axisno, axis);
|
plot.setRangeAxis(axisno, axis);
|
||||||
|
axis.setLabelFont(new Font("Dialog", Font.BOLD, 14));
|
||||||
|
|
||||||
double domainMin = data[i].getDomainLowerBound(true);
|
double domainMin = data[i].getDomainLowerBound(true);
|
||||||
double domainMax = data[i].getDomainUpperBound(true);
|
double domainMax = data[i].getDomainUpperBound(true);
|
||||||
|
|
||||||
plot.setDomainAxis(new PresetNumberAxis(domainMin, domainMax));
|
plot.setDomainAxis(new PresetNumberAxis(domainMin, domainMax));
|
||||||
|
|
||||||
|
// Custom tooltip generator
|
||||||
|
int finalAxisno = axisno;
|
||||||
|
StandardXYToolTipGenerator tooltipGenerator = new StandardXYToolTipGenerator() {
|
||||||
|
final DecimalFormat f = new DecimalFormat("0.00");
|
||||||
|
@Override
|
||||||
|
public String generateToolTip(XYDataset dataset, int series, int item) {
|
||||||
|
XYSeries ser = data[finalAxisno].getSeries(series);
|
||||||
|
String name = ser.getDescription();
|
||||||
|
// Extract the unit from the last part of the series description, between parenthesis
|
||||||
|
Matcher m = Pattern.compile(".*\\((.*?)\\)").matcher(name);
|
||||||
|
String unit_y = "";
|
||||||
|
if (m.find()) {
|
||||||
|
unit_y = m.group(1);
|
||||||
|
}
|
||||||
|
String unit_x = domainUnit.getUnit();
|
||||||
|
String ord_end = "th"; // Ordinal number ending (1'st', 2'nd'...)
|
||||||
|
if (item % 10 == 1)
|
||||||
|
ord_end = "st";
|
||||||
|
else if (item % 10 == 2)
|
||||||
|
ord_end = "nd";
|
||||||
|
else if (item % 10 == 3)
|
||||||
|
ord_end = "rd";
|
||||||
|
return String.format("<html>" +
|
||||||
|
"<b><i>%s</i></b><br>" +
|
||||||
|
"Y: %s %s<br>" +
|
||||||
|
"X: %s %s<br>" +
|
||||||
|
"%d<sup>%s</sup> sample" +
|
||||||
|
"</html>",
|
||||||
|
name, f.format(dataset.getYValue(series, item)), unit_y,
|
||||||
|
f.format(dataset.getXValue(series, item)), unit_x, item, ord_end);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Add data and map to the axis
|
// Add data and map to the axis
|
||||||
plot.setDataset(axisno, data[i]);
|
plot.setDataset(axisno, data[i]);
|
||||||
ModifiedXYItemRenderer r = new ModifiedXYItemRenderer(branchCount);
|
ModifiedXYItemRenderer r = new ModifiedXYItemRenderer(branchCount);
|
||||||
renderers.add(r);
|
renderers.add(r);
|
||||||
|
r.setBaseToolTipGenerator(tooltipGenerator);
|
||||||
plot.setRenderer(axisno, r);
|
plot.setRenderer(axisno, r);
|
||||||
r.setBaseShapesVisible(initialShowPoints);
|
r.setBaseShapesVisible(initialShowPoints);
|
||||||
r.setBaseShapesFilled(true);
|
r.setBaseShapesFilled(true);
|
||||||
|
r.setSeriesPaint(0, colors[i]);
|
||||||
|
r.setSeriesPaint(1, colors[i+2]);
|
||||||
|
r.setSeriesPaint(2, colors[i+4]);
|
||||||
for (int j = 0; j < data[i].getSeriesCount(); j++) {
|
for (int j = 0; j < data[i].getSeriesCount(); j++) {
|
||||||
Stroke lineStroke = new BasicStroke(PLOT_STROKE_WIDTH);
|
Stroke lineStroke = new BasicStroke(PLOT_STROKE_WIDTH);
|
||||||
r.setSeriesStroke(j, lineStroke);
|
r.setSeriesStroke(j, lineStroke);
|
||||||
@ -271,7 +329,7 @@ public class SimulationPlot {
|
|||||||
plot.addDomainMarker(new ValueMarker(0));
|
plot.addDomainMarker(new ValueMarker(0));
|
||||||
plot.addRangeMarker(new ValueMarker(0));
|
plot.addRangeMarker(new ValueMarker(0));
|
||||||
|
|
||||||
|
plot.getDomainAxis().setLabelFont(new Font("Dialog", Font.BOLD, 14));
|
||||||
|
|
||||||
// Create list of events to show (combine event too close to each other)
|
// Create list of events to show (combine event too close to each other)
|
||||||
this.eventList = buildEventInfo();
|
this.eventList = buildEventInfo();
|
||||||
@ -368,6 +426,7 @@ public class SimulationPlot {
|
|||||||
m.setPaint(color);
|
m.setPaint(color);
|
||||||
m.setLabelPaint(color);
|
m.setLabelPaint(color);
|
||||||
m.setAlpha(0.7f);
|
m.setAlpha(0.7f);
|
||||||
|
m.setLabelFont(new Font("Dialog", Font.PLAIN, 13));
|
||||||
plot.addDomainMarker(m);
|
plot.addDomainMarker(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,3 +712,4 @@ public class SimulationPlot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user