SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
XYChart.java
1/*
2 * Class: XYChart
3 * Description:
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.charts;
26
27import java.io.*;
28import org.jfree.chart.JFreeChart;
29import org.jfree.chart.annotations.*;
30import org.jfree.chart.plot.XYPlot;
31import org.jfree.chart.ui.TextAnchor;
32import javax.swing.JFrame;
33
56public abstract class XYChart {
57 protected Axis XAxis;
58 protected Axis YAxis;
59
60 protected SSJXYSeriesCollection dataset;
61 protected JFreeChart chart;
62 protected boolean latexDocFlag = true;
63
64 protected boolean autoRange;
65 protected double[] manualRange;
66
67 protected boolean grid = false;
68 protected double xstepGrid;
69 protected double ystepGrid;
70
71 // this flag is set true when plotting probabilities. In that case,
72 // y is always >= 0.
73 protected boolean probFlag = false;
74
75 protected double chartMargin = 0.02; // margin around the chart
76
82 public JFreeChart getJFreeChart() {
83 return chart;
84 }
85
91 public Axis getXAxis() {
92 return XAxis;
93 }
94
100 public Axis getYAxis() {
101 return YAxis;
102 }
103
107 public abstract JFrame view(int width, int height);
108
114 public String getTitle() {
115 return chart.getTitle().getText();
116 }
117
124 public void setTitle(String title) {
125 chart.setTitle(title);
126 }
127
133 public void setprobFlag(boolean flag) {
134 probFlag = flag;
135 }
136
140 public void setAutoRange() {
141 setAutoRange(false, false, true, true);
142 }
143
153 public void setAutoRange(boolean right, boolean top) {
154 setAutoRange(false, false, right, top);
155 }
156
157 private double[] adjustRangeBounds(double bmin, double bmax) {
158 // resets chart lower and upper bounds to round values.
159 // Returns corrected [lowerBound, upperBound]
160
161 double del = (bmax - bmin) / 20.0; // Choose 20 intervals to round
162 int a = (int) Math.floor(0.5 + Math.log10(del));
163 double d = Math.pow(10.0, (double) a); // power of 10
164 double lower = d * Math.ceil((bmin - del) / d);
165 if (lower > bmin)
166 lower -= d;
167 if (0 == Math.abs(bmin))
168 lower = 0;
169 double upper = d * Math.floor((bmax + del) / d);
170 if (upper < bmax)
171 upper += d;
172 double[] range = new double[2];
173 range[0] = lower;
174 range[1] = upper;
175 return range;
176 }
177
178 protected void setAutoRange(boolean xZero, boolean yZero, boolean right, boolean top) {
179 // see description of setAxesZero
180 autoRange = true;
181 double BorneMin = (dataset.getDomainBounds())[0];
182 double BorneMax = (dataset.getDomainBounds())[1];
183 double del;
184 if (BorneMax - BorneMin < 1)
185 del = (BorneMax - BorneMin) * chartMargin;
186 else
187 del = chartMargin;
188 if (BorneMin < 0.0)
189 BorneMin *= 1.0 + del;
190 else
191 BorneMin *= 1.0 - del;
192 if (BorneMax < 0.0)
193 BorneMax *= 1.0 - del;
194 else
195 BorneMax *= 1.0 + del;
196 double[] newRange = new double[2];
197 newRange = adjustRangeBounds(BorneMin, BorneMax);
198 if (probFlag && (BorneMin == 0.0))
199 newRange[0] = 0.0;
200 XAxis.getAxis().setLowerBound(newRange[0]);
201 XAxis.getAxis().setUpperBound(newRange[1]);
202
203 BorneMin = (dataset.getRangeBounds())[0];
204 BorneMax = (dataset.getRangeBounds())[1];
205 if (BorneMax - BorneMin < 1)
206 del = (BorneMax - BorneMin) * chartMargin;
207 else
208 del = chartMargin;
209 if (BorneMin < 0.0)
210 BorneMin *= 1.0 + del;
211 else
212 BorneMin *= 1.0 - del;
213 if (BorneMax < 0.0)
214 BorneMax *= 1.0 - del;
215 else
216 BorneMax *= 1.0 + del;
217 newRange = adjustRangeBounds(BorneMin, BorneMax);
218 if (probFlag && (newRange[0] <= 0.0)) // probabilities are always >= 0
219 newRange[0] = 0.0;
220 YAxis.getAxis().setLowerBound(newRange[0]);
221 YAxis.getAxis().setUpperBound(newRange[1]);
222
223 if (xZero)
224 XAxis.setTwinAxisPosition(0);
225 else {
226 if (right)
227 XAxis.setTwinAxisPosition(XAxis.getAxis().getLowerBound());
228 else
229 XAxis.setTwinAxisPosition(XAxis.getAxis().getUpperBound());
230 }
231
232 if (yZero)
233 YAxis.setTwinAxisPosition(0);
234 else {
235 if (top)
236 YAxis.setTwinAxisPosition(YAxis.getAxis().getLowerBound());
237 else
238 YAxis.setTwinAxisPosition(YAxis.getAxis().getUpperBound());
239 }
240 }
241
251 public void setAutoRange00(boolean xZero, boolean yZero) {
252 setAutoRange(xZero, yZero, true, true);
253 }
254
261 public void setManualRange(double[] range) {
262 setManualRange(range, false, false, true, true);
263 }
264
275 public void setManualRange(double[] range, boolean right, boolean top) {
276 setManualRange(range, false, false, right, top);
277 }
278
279 private void setManualRange(double[] range, boolean xZero, boolean yZero, boolean right, boolean top) {
280 if (range.length != 4)
281 throw new IllegalArgumentException("range must have the format: [xmin, xmax, ymin, ymax]");
282 autoRange = false;
283 XAxis.getAxis().setLowerBound(Math.min(range[0], range[1]));
284 XAxis.getAxis().setUpperBound(Math.max(range[0], range[1]));
285 YAxis.getAxis().setLowerBound(Math.min(range[2], range[3]));
286 YAxis.getAxis().setUpperBound(Math.max(range[2], range[3]));
287
288 if (xZero)
289 XAxis.setTwinAxisPosition(0);
290 else {
291 if (right)
292 XAxis.setTwinAxisPosition(XAxis.getAxis().getLowerBound());
293 else
294 XAxis.setTwinAxisPosition(XAxis.getAxis().getUpperBound());
295 }
296
297 if (yZero)
298 YAxis.setTwinAxisPosition(0);
299 else {
300 if (top)
301 YAxis.setTwinAxisPosition(YAxis.getAxis().getLowerBound());
302 else
303 YAxis.setTwinAxisPosition(YAxis.getAxis().getUpperBound());
304 }
305 }
306
317 public void setManualRange00(double[] range, boolean xZero, boolean yZero) {
318 setManualRange(range, xZero, yZero, true, true);
319 }
320
325 public double getChartMargin() {
326 return chartMargin;
327 }
328
335 public void setChartMargin(double margin) {
336 if (margin < 0.0)
337 throw new IllegalArgumentException("margin < 0");
338 chartMargin = margin;
339 }
340
346 public abstract void setTicksSynchro(int s);
347
359 public void drawVerticalLine(double x, String name, double yfrac, boolean right) {
360 double ybottom = YAxis.getAxis().getLowerBound();
361 final Object o = this;
362 if (this instanceof HistogramChart)
363 ybottom = 0;
364 double ytop = YAxis.getAxis().getUpperBound();
365 XYLineAnnotation line = new XYLineAnnotation(x, ybottom, x, ytop);
366 XYTextAnnotation text = new XYTextAnnotation(name, x, ytop * yfrac);
367 if (!right)
368 text.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);
369 else
370 text.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
371 XYPlot plot = getJFreeChart().getXYPlot();
372 plot.addAnnotation(line);
373 plot.addAnnotation(text);
374 }
375
379
390 public void enableGrid(double xstep, double ystep) {
391 this.grid = true;
392 this.xstepGrid = xstep;
393 this.ystepGrid = ystep;
394 }
395
399 public void disableGrid() {
400 this.grid = false;
401 }
402
415 public abstract String toLatex(double width, double height);
416
421 public void toLatexFile(String fileName, double width, double height) {
422 String output = toLatex(width, height);
423 Writer file = null;
424 try {
425 file = new FileWriter(fileName);
426 file.write(output);
427 file.close();
428 } catch (IOException e) {
429 System.err.println(" toLatexFile: cannot write to " + fileName);
430 e.printStackTrace();
431 try {
432 if (file != null)
433 file.close();
434 } catch (IOException ioe) {
435 }
436 }
437 }
438
450 public void setLatexDocFlag(boolean flag) {
451 latexDocFlag = flag;
452 }
453
454 protected void setTick0Flags() {
455 // Set flag true if first or last label is on perpendicular axis.
456 // The label will be moved a little to the right (x-label), or above
457 // (y-label) to prevent it from being on the perpendicular axis.
458 // But it is unnecessary when graph begins or ends where label is;
459 // in this case, flag is false.
460 // We cannot put this method in Axis because it depends on the
461 // other axis.
462 double minAxis = Math.min(XAxis.getAxis().getRange().getLowerBound(), XAxis.getTwinAxisPosition());
463 double maxAxis = Math.max(XAxis.getAxis().getRange().getUpperBound(), XAxis.getTwinAxisPosition());
464 if (XAxis.getTwinAxisPosition() == minAxis || XAxis.getTwinAxisPosition() == maxAxis)
465 YAxis.setTick0Flag(false);
466 else
467 YAxis.setTick0Flag(true);
468
469 minAxis = Math.min(YAxis.getAxis().getRange().getLowerBound(), YAxis.getTwinAxisPosition());
470 maxAxis = Math.max(YAxis.getAxis().getRange().getUpperBound(), YAxis.getTwinAxisPosition());
471 if (YAxis.getTwinAxisPosition() == minAxis || YAxis.getTwinAxisPosition() == maxAxis)
472 XAxis.setTick0Flag(false);
473 else
474 XAxis.setTick0Flag(true);
475 }
476
477 protected double computeXScale(double position) {
478 double[] bounds = new double[2];
479 bounds[0] = XAxis.getAxis().getLowerBound();
480 bounds[1] = XAxis.getAxis().getUpperBound();
481
482 if (position < bounds[0])
483 bounds[0] = position;
484 if (position > bounds[1])
485 bounds[1] = position;
486 bounds[0] -= position;
487 bounds[1] -= position;
488 return computeScale(bounds);
489 }
490
491 protected double computeYScale(double position) {
492 double[] bounds = new double[2];
493 bounds[0] = YAxis.getAxis().getLowerBound();
494 bounds[1] = YAxis.getAxis().getUpperBound();
495
496 if (position < bounds[0])
497 bounds[0] = position;
498 if (position > bounds[1])
499 bounds[1] = position;
500 bounds[0] -= position;
501 bounds[1] -= position;
502 return computeScale(bounds);
503 }
504
505 protected double computeScale(double[] bounds) {
506 int tenPowerRatio = 0;
507 // echelle < 1 si les valeurs sont grandes
508 while (bounds[1] > 1000 || bounds[0] < -1000) {
509 bounds[1] /= 10;
510 bounds[0] /= 10;
511 tenPowerRatio++;
512 }
513 // echelle > 1 si les valeurs sont petites
514 while (bounds[1] < 100 && bounds[0] > -100) {
515 bounds[1] *= 10;
516 bounds[0] *= 10;
517 tenPowerRatio--;
518 }
519 return 1 / Math.pow(10, tenPowerRatio);
520 }
521}
522
Represents an axis of a chart encapsulated by an instance of XYChart.
Definition Axis.java:42
NumberAxis getAxis()
Returns the NumberAxis instance (from JFreeChart) linked with the current variable.
Definition Axis.java:98
void setTwinAxisPosition(double position)
Defines where the opposite axis must be drawn on the current axis, where it should appear,...
Definition Axis.java:221
double getTwinAxisPosition()
Returns the drawing position parameter (default equals 0).
Definition Axis.java:211
Provides tools to create and manage histograms.
double[] getRangeBounds()
Returns range ( -coordinates) min and max values.
double[] getDomainBounds()
Returns domain ( -coordinates) min and max values.
This class provides tools to create charts from data in a simple way.
Definition XYChart.java:56
void enableGrid(double xstep, double ystep)
Puts a grid on the background.
Definition XYChart.java:390
String getTitle()
Gets the current chart title.
Definition XYChart.java:114
void drawVerticalLine(double x, String name, double yfrac, boolean right)
Draws a vertical line on the chart at -coordinate x.
Definition XYChart.java:359
Axis getXAxis()
Returns the chart’s domain axis ( -axis) object.
Definition XYChart.java:91
void toLatexFile(String fileName, double width, double height)
Transforms the chart to LaTeX form and writes it in file fileName.
Definition XYChart.java:421
void setManualRange00(double[] range, boolean xZero, boolean yZero)
Sets the and ranges of the chart using the format: range = [xmin, xmax, ymin, ymax].
Definition XYChart.java:317
void setLatexDocFlag(boolean flag)
Flag to remove the \documentclass (and other) commands in the created LaTeX files.
Definition XYChart.java:450
double getChartMargin()
Returns the chart margin, which is the fraction by which the chart is enlarged on its borders.
Definition XYChart.java:325
void setprobFlag(boolean flag)
Must be set true when plotting probabilities, false otherwise.
Definition XYChart.java:133
void setManualRange(double[] range, boolean right, boolean top)
Sets the and ranges of the chart using the format: range = [xmin, xmax, ymin, ymax].
Definition XYChart.java:275
abstract void setTicksSynchro(int s)
Synchronizes -axis ticks to the -th series.
void setAutoRange()
The and the ranges of the chart are set automatically.
Definition XYChart.java:140
void setManualRange(double[] range)
Sets the and ranges of the chart using the format: range = [xmin, xmax, ymin, ymax].
Definition XYChart.java:261
void setTitle(String title)
Sets a title to this chart.
Definition XYChart.java:124
abstract JFrame view(int width, int height)
Displays chart on the screen using Swing.
void disableGrid()
Disables the background grid.
Definition XYChart.java:399
JFreeChart getJFreeChart()
Returns the JFreeChart object associated with this chart.
Definition XYChart.java:82
void setAutoRange00(boolean xZero, boolean yZero)
The and the ranges of the chart are set automatically.
Definition XYChart.java:251
Axis getYAxis()
Returns the chart’s range axis ( -axis) object.
Definition XYChart.java:100
abstract String toLatex(double width, double height)
Exports the chart to a LaTeX source code using PGF/TikZ.
void setChartMargin(double margin)
Sets the chart margin to margin.
Definition XYChart.java:335
void setAutoRange(boolean right, boolean top)
The and the ranges of the chart are set automatically.
Definition XYChart.java:153