Skip to content
Snippets Groups Projects
Commit 571e3eea authored by Brady James Garvin's avatar Brady James Garvin
Browse files

Initial commit.

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 710 additions and 0 deletions
/target/
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.unl.cse.soft160.chart_inheritance</groupId>
<artifactId>chart_inheritance</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>chart_inheritance</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package edu.unl.cse.soft160.chart_inheritance;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.lang.reflect.InvocationTargetException;
import java.util.Scanner;
import javax.swing.JFrame;
/**
* This class represents a window displaying a single chart that, when closed,
* exits the application (even if other windows are open). When run as the main
* class, it offers the user a menu on the command line from which they can
* choose one type of chart to display; that chart will be populated with sample
* data.
*
* @see edu.unl.cse.soft160.chart_inheritance.a.BarChart
* @see edu.unl.cse.soft160.chart_inheritance.a.LineChart
* @see edu.unl.cse.soft160.chart_inheritance.b.BarChart
* @see edu.unl.cse.soft160.chart_inheritance.b.CategoryChart
* @see edu.unl.cse.soft160.chart_inheritance.c.RadarChart
* @see edu.unl.cse.soft160.chart_inheritance.c.ScatterChart
*/
public class App extends JFrame {
private static final long serialVersionUID = -7456297737056197824L;
private static final int DEFAULT_SIZE = 600;
private static final Font TEXT_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 16);
private static final Color TEXT_COLOR = new Color(255, 255, 255, 127);
private Object chart;
public App(Object chart) {
super("Example Chart");
this.chart = chart;
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(DEFAULT_SIZE, DEFAULT_SIZE);
}
@Override
public void paint(Graphics uncast) {
super.paint(uncast);
Graphics2D context = (Graphics2D) uncast;
context.setFont(TEXT_FONT);
context.setColor(TEXT_COLOR);
context.setColor(Color.BLUE);
try {
chart.getClass().getDeclaredMethod("draw", Graphics2D.class).invoke(chart, context);
} catch (NoSuchMethodException exception) {
throw new RuntimeException(exception);
} catch (InvocationTargetException exception) {
throw new RuntimeException(exception);
} catch (IllegalAccessException exception) {
throw new RuntimeException(exception);
}
}
public static void main(String... arguments) {
String[] labels = { "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf" };
double[] data = { 4, 5, 6, 2, 3, 11, -2 };
CartesianPoint[] cartesianData = { new CartesianPoint(3, 7), new CartesianPoint(-2, -9),
new CartesianPoint(-5, 1), new CartesianPoint(4, -6) };
PolarPoint[] polarData = { new PolarPoint(1.3, 7), new PolarPoint(2.2, 9), new PolarPoint(3.5, 4),
new PolarPoint(4.9, 6) };
Object[] charts = { new edu.unl.cse.soft160.chart_inheritance.a.BarChart(data),
new edu.unl.cse.soft160.chart_inheritance.a.LineChart(data),
new edu.unl.cse.soft160.chart_inheritance.b.BarChart(data),
new edu.unl.cse.soft160.chart_inheritance.b.CategoryChart(labels, data),
new edu.unl.cse.soft160.chart_inheritance.c.RadarChart(polarData),
new edu.unl.cse.soft160.chart_inheritance.c.ScatterChart(cartesianData), };
System.out.println("Choose a chart type:");
for (int i = 0; i < charts.length; ++i) {
System.out.println(" " + i + ") " + charts[i].getClass());
}
System.out.print("Your selection: ");
Scanner scanner = new Scanner(System.in);
int selection = scanner.nextInt();
scanner.close();
new App(charts[selection]).setVisible(true);
}
}
package edu.unl.cse.soft160.chart_inheritance;
/**
* This class represents a point in Cartesian coordinates. It would likely be
* replaced by <code>Point2D.Double</code> in production code.
*
* @see java.awt.geom.Point2D.Double
*/
public class CartesianPoint {
public double x, y;
public CartesianPoint(double x, double y) {
this.x = x;
this.y = y;
}
}
package edu.unl.cse.soft160.chart_inheritance;
import java.awt.Graphics2D;
import java.awt.Rectangle;
/**
* This class acts as a drawable with operations specifically useful to the
* currently implemented charts. Most of the logic is taken up by the affine
* transformation from chart coordinates to display coordinates; this
* transformation is not implemented as an affine transformation on the
* underlying Graphics2D in order to avoid unintended pixelization.
*
* @see java.awt.Graphics
* @see java.awt.Graphics2D
*/
public class ChartCanvas {
private static final int PADDING = 40;
private static final int POINT_RADIUS = 6;
private Graphics2D context;
private double minX, minY, maxX, maxY;
public ChartCanvas(Graphics2D context, double minX, double minY, double maxX, double maxY) {
this.context = context;
this.minX = minX;
this.minY = minY;
this.maxX = maxX >= minX ? maxX : minX + 1;
this.maxY = maxY >= minY ? maxY : minY + 1;
}
private int toX(double x) {
Rectangle bounds = context.getClipBounds();
int left = bounds.x + PADDING;
int right = bounds.x + bounds.width - PADDING;
double width = (right - left) / (maxX - minX);
return left + (int) Math.round((x - minX) * width);
}
private int toY(double y) {
Rectangle bounds = context.getClipBounds();
int top = bounds.y + PADDING;
int bottom = bounds.y + bounds.height - PADDING;
double height = (bottom - top) / (maxY - minY);
return bottom - (int) Math.round((y - minY) * height);
}
public void drawPoint(double x, double y) {
context.fillOval(toX(x) - POINT_RADIUS, toY(y) - POINT_RADIUS, 2 * POINT_RADIUS, 2 * POINT_RADIUS);
}
public void drawLine(double x0, double y0, double x1, double y1) {
context.drawLine(toX(x0), toY(y0), toX(x1), toY(y1));
}
public void drawRectangle(double x0, double y0, double x1, double y1) {
context.fillRect(toX(x0), toY(y1), toX(x1) - toX(x0), toY(y0) - toY(y1));
}
public void drawTextBelow(double x, double y, String text) {
context.drawString(text, toX(x) - context.getFontMetrics().stringWidth(text) / 2,
toY(y) + context.getFontMetrics().getHeight());
}
public void drawTextLeft(double x, double y, String text) {
context.drawString(text, toX(x) - context.getFontMetrics().stringWidth(text),
toY(y) + context.getFontMetrics().getHeight() / 2);
}
}
package edu.unl.cse.soft160.chart_inheritance;
import java.awt.Point;
import edu.unl.cse.soft160.chart_inheritance.a.BarChart;
import edu.unl.cse.soft160.chart_inheritance.a.LineChart;
/**
* This class, when run as the main class, uses sample data to display the two
* charts in the <code>a</code> package.
*
* @see edu.unl.cse.soft160.chart_inheritance.a.BarChart
* @see edu.unl.cse.soft160.chart_inheritance.a.LineChart
*/
public class PackageADemo {
public static void main(String... arguments) {
double[] data = { 4, 5, 6, 2, 3, 11, -2 };
Object[] charts = { new BarChart(data), new LineChart(data) };
for (int i = 0; i < charts.length; ++i) {
App app = new App(charts[i]);
app.setLocation(new Point(100 * i, 50 * i));
app.setVisible(true);
}
}
}
package edu.unl.cse.soft160.chart_inheritance;
import java.awt.Point;
import edu.unl.cse.soft160.chart_inheritance.b.BarChart;
import edu.unl.cse.soft160.chart_inheritance.b.CategoryChart;
/**
* This class, when run as the main class, uses sample data to display the two
* charts in the <code>b</code> package.
*
* @see edu.unl.cse.soft160.chart_inheritance.b.BarChart
* @see edu.unl.cse.soft160.chart_inheritance.b.CategoryChart
*/
public class PackageBDemo {
public static void main(String... arguments) {
String[] labels = { "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf" };
double[] data = { 4, 5, 6, 2, 3, 11, -2 };
Object[] charts = { new BarChart(data), new CategoryChart(labels, data) };
for (int i = 0; i < charts.length; ++i) {
App app = new App(charts[i]);
app.setLocation(new Point(100 * i, 50 * i));
app.setVisible(true);
}
}
}
package edu.unl.cse.soft160.chart_inheritance;
import java.awt.Point;
import edu.unl.cse.soft160.chart_inheritance.c.RadarChart;
import edu.unl.cse.soft160.chart_inheritance.c.ScatterChart;
/**
* This class, when run as the main class, uses sample data to display the two
* charts in the <code>c</code> package.
*
* @see edu.unl.cse.soft160.chart_inheritance.c.RadarChart
* @see edu.unl.cse.soft160.chart_inheritance.c.ScatterChart
*/
public class PackageCDemo {
public static void main(String... arguments) {
PolarPoint[] polarData = { new PolarPoint(1.3, 7), new PolarPoint(2.2, 9), new PolarPoint(3.5, 4),
new PolarPoint(4.9, 6) };
CartesianPoint[] cartesianData = { new CartesianPoint(3, 7), new CartesianPoint(-2, -9),
new CartesianPoint(-5, 1), new CartesianPoint(4, -6) };
Object[] charts = { new RadarChart(polarData), new ScatterChart(cartesianData) };
for (int i = 0; i < charts.length; ++i) {
App app = new App(charts[i]);
app.setLocation(new Point(100 * i, 50 * i));
app.setVisible(true);
}
}
}
package edu.unl.cse.soft160.chart_inheritance;
/**
* This class represents a point in polar coordinates.
*/
public class PolarPoint {
public double theta, radius;
public PolarPoint(double theta, double radius) {
this.theta = theta;
this.radius = radius;
}
}
package edu.unl.cse.soft160.chart_inheritance.a;
import java.awt.Graphics2D;
import edu.unl.cse.soft160.chart_inheritance.ChartCanvas;
/**
* This class is a bare-bones bar chart, providing just enough functionality to
* illustrate a class design. A <code>BarChart</code> object plots the
* <code>double<code>s given to it in its constructor with the first <code>double</code>
* being the height of the bar on the far left, the next <code>double</code>
* being the height of the next bar, etc., ending with the last
* <code>double</code> in the array being the height of the bar on the far
* right. The background of the chart is a Cartesian grid.
*/
public class BarChart {
private double[] data;
private double min, max;
public BarChart(double[] data) {
this.data = data;
min = 0;
max = 0;
for (double datum : data) {
if (datum < min) {
min = datum;
}
if (datum > max) {
max = datum;
}
}
}
private void drawAxes(ChartCanvas canvas) {
canvas.drawLine(0, 0, data.length, 0);
canvas.drawLine(0, min, 0, max);
}
private void drawXAxisLabels(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
canvas.drawLine(i, -0.25, i, 0.25);
canvas.drawTextBelow(i + 0.5, 0, String.valueOf(i));
}
}
private void drawYAxisLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double y = Math.round(min + i * (max - min) / 10);
canvas.drawLine(-0.25, y, 0.25, y);
canvas.drawTextLeft(-0.25, y, String.valueOf((int) y));
}
}
private void drawData(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
if (data[i] < 0) {
canvas.drawRectangle(i + 0.25, data[i], i + 0.75, 0);
} else {
canvas.drawRectangle(i + 0.25, 0, i + 0.75, data[i]);
}
}
}
public void draw(Graphics2D context) {
ChartCanvas canvas = new ChartCanvas(context, 0, min, data.length, max);
drawAxes(canvas);
drawXAxisLabels(canvas);
drawYAxisLabels(canvas);
drawData(canvas);
}
}
package edu.unl.cse.soft160.chart_inheritance.a;
import java.awt.Graphics2D;
import edu.unl.cse.soft160.chart_inheritance.ChartCanvas;
/**
* This class is a bare-bones line chart, providing just enough functionality to
* illustrate a class design. A <code>LineChart</code> object plots the
* <code>double</code>s given to it in its constructor with the first
* <code>double</code> being the height of the line at its leftmost point, the
* next <code>double</code> being the height of the next point, etc., ending
* with the last <code>double</code> in the array being the height of the line
* at its rightmost point. The background of the chart is a Cartesian grid.
*/
public class LineChart {
private double[] data;
private double min, max;
public LineChart(double[] data) {
this.data = data;
min = 0;
max = 0;
for (double datum : data) {
if (datum < min) {
min = datum;
}
if (datum > max) {
max = datum;
}
}
}
private void drawAxes(ChartCanvas canvas) {
canvas.drawLine(0, 0, data.length, 0);
canvas.drawLine(0, min, 0, max);
}
private void drawXAxisLabels(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
canvas.drawLine(i, -0.25, i, 0.25);
canvas.drawTextBelow(i + 0.5, 0, String.valueOf(i));
}
}
private void drawYAxisLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double y = Math.round(min + i * (max - min) / 10);
canvas.drawLine(-0.25, y, 0.25, y);
canvas.drawTextLeft(-0.25, y, String.valueOf((int) y));
}
}
private void drawData(ChartCanvas canvas) {
for (int i = 1; i < data.length; ++i) {
canvas.drawLine(i - 0.5, data[i - 1], i + 0.5, data[i]);
}
for (int i = 0; i < data.length; ++i) {
canvas.drawPoint(i + 0.5, data[i]);
}
}
public void draw(Graphics2D context) {
ChartCanvas canvas = new ChartCanvas(context, 0, min, data.length, max);
drawAxes(canvas);
drawXAxisLabels(canvas);
drawYAxisLabels(canvas);
drawData(canvas);
}
}
package edu.unl.cse.soft160.chart_inheritance.b;
import java.awt.Graphics2D;
import edu.unl.cse.soft160.chart_inheritance.ChartCanvas;
/**
* This class is a bare-bones bar chart, providing just enough functionality to
* illustrate a class design. A <code>BarChart</code> object plots the
* <code>double<code>s given to it in its constructor with the first <code>double</code>
* being the height of the bar on the far left, the next <code>double</code>
* being the height of the next bar, etc., ending with the last
* <code>double</code> in the array being the height of the bar on the far
* right. The background of the chart is a Cartesian grid.
*/
public class BarChart {
private double[] data;
private double min, max;
public BarChart(double[] data) {
this.data = data;
min = 0;
max = 0;
for (double datum : data) {
if (datum < min) {
min = datum;
}
if (datum > max) {
max = datum;
}
}
}
private void drawAxes(ChartCanvas canvas) {
canvas.drawLine(0, 0, data.length, 0);
canvas.drawLine(0, min, 0, max);
}
private void drawXAxisLabels(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
canvas.drawLine(i, -0.25, i, 0.25);
canvas.drawTextBelow(i + 0.5, 0, String.valueOf(i));
}
}
private void drawYAxisLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double y = Math.round(min + i * (max - min) / 10);
canvas.drawLine(-0.25, y, 0.25, y);
canvas.drawTextLeft(-0.25, y, String.valueOf((int) y));
}
}
private void drawData(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
if (data[i] < 0) {
canvas.drawRectangle(i + 0.25, data[i], i + 0.75, 0);
} else {
canvas.drawRectangle(i + 0.25, 0, i + 0.75, data[i]);
}
}
}
public void draw(Graphics2D context) {
ChartCanvas canvas = new ChartCanvas(context, 0, min, data.length, max);
drawAxes(canvas);
drawXAxisLabels(canvas);
drawYAxisLabels(canvas);
drawData(canvas);
}
}
package edu.unl.cse.soft160.chart_inheritance.b;
import java.awt.Graphics2D;
import edu.unl.cse.soft160.chart_inheritance.ChartCanvas;
/**
* This class is a bare-bones bar chart, providing just enough functionality to
* illustrate a class design. A <code>CategoryChart</code> object plots the
* <code>double<code>s given to it in its constructor with the first <code>double</code>
* being the height of the bar on the far left, the next <code>double</code>
* being the height of the next bar, etc., ending with the last
* <code>double</code> in the array being the height of the bar on the far
* right. The background of the chart is a Cartesian grid, but instead of the
* <i>x</i>&nbsp;axis labels being numbers, they are the <code>string</code>s
* given to the constructor.
*/
public class CategoryChart {
private String[] labels;
private double[] data;
private double min, max;
public CategoryChart(String[] labels, double[] data) {
this.labels = labels;
this.data = data;
min = 0;
max = 0;
for (double datum : data) {
if (datum < min) {
min = datum;
}
if (datum > max) {
max = datum;
}
}
}
private void drawAxes(ChartCanvas canvas) {
canvas.drawLine(0, 0, data.length, 0);
canvas.drawLine(0, min, 0, max);
}
private void drawXAxisLabels(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
canvas.drawLine(i, -0.25, i, 0.25);
canvas.drawTextBelow(i + 0.5, 0, i < labels.length ? labels[i] : String.valueOf(i));
}
}
private void drawYAxisLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double y = Math.round(min + i * (max - min) / 10);
canvas.drawLine(-0.25, y, 0.25, y);
canvas.drawTextLeft(-0.25, y, String.valueOf((int) y));
}
}
private void drawData(ChartCanvas canvas) {
for (int i = 0; i < data.length; ++i) {
if (data[i] < 0) {
canvas.drawRectangle(i + 0.25, data[i], i + 0.75, 0);
} else {
canvas.drawRectangle(i + 0.25, 0, i + 0.75, data[i]);
}
}
}
public void draw(Graphics2D context) {
ChartCanvas canvas = new ChartCanvas(context, 0, min, data.length, max);
drawAxes(canvas);
drawXAxisLabels(canvas);
drawYAxisLabels(canvas);
drawData(canvas);
}
}
package edu.unl.cse.soft160.chart_inheritance.c;
import java.awt.Graphics2D;
import edu.unl.cse.soft160.chart_inheritance.ChartCanvas;
import edu.unl.cse.soft160.chart_inheritance.PolarPoint;
/**
* This class is a bare-bones radar (cobweb) chart, providing just enough
* functionality to illustrate a class design. A <code>RadarChart</code> object
* plots the <code>PolarPoint</code>s given to it in its constructor on a Polar
* grid.
*/
public class RadarChart {
private PolarPoint[] data;
private double maxRadius;
public RadarChart(PolarPoint[] data) {
this.data = data;
maxRadius = 0;
for (PolarPoint datum : data) {
if (datum.radius > maxRadius) {
maxRadius = datum.radius;
}
}
}
private void drawAxes(ChartCanvas canvas) {
for (int i = 0; i < 16; ++i) {
double theta = Math.PI * i / 8;
canvas.drawLine(0, 0, maxRadius * Math.cos(theta), maxRadius * Math.sin(theta));
}
}
private void drawThetaLabels(ChartCanvas canvas) {
for (int i = 1; i < 16; ++i) {
double theta = Math.PI * i / 8;
canvas.drawTextBelow(maxRadius * Math.cos(theta), maxRadius * Math.sin(theta),
String.format("%.2f", theta));
}
}
private void drawRadiusLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double x = Math.round(i * maxRadius / 10);
canvas.drawLine(x, -0.25, x, 0.25);
canvas.drawTextBelow(x, -0.25, String.valueOf((int) x));
}
}
private void drawData(ChartCanvas canvas) {
for (PolarPoint datum : data) {
canvas.drawPoint(datum.radius * Math.cos(datum.theta), datum.radius * Math.sin(datum.theta));
}
}
public void draw(Graphics2D context) {
ChartCanvas canvas = new ChartCanvas(context, -maxRadius, -maxRadius, maxRadius, maxRadius);
drawAxes(canvas);
drawThetaLabels(canvas);
drawRadiusLabels(canvas);
drawData(canvas);
}
}
package edu.unl.cse.soft160.chart_inheritance.c;
import java.awt.Graphics2D;
import edu.unl.cse.soft160.chart_inheritance.CartesianPoint;
import edu.unl.cse.soft160.chart_inheritance.ChartCanvas;
/**
* This class is a bare-bones scatter chart, providing just enough functionality
* to illustrate a class design. A <code>ScatterChart</code> object plots the
* <code>CartesianPoint</code>s given to it in its constructor on a Cartesian
* grid.
*/
public class ScatterChart {
private CartesianPoint[] data;
private double minX, minY, maxX, maxY;
public ScatterChart(CartesianPoint[] data) {
this.data = data;
minX = 0;
minY = 0;
maxX = 0;
maxY = 0;
for (CartesianPoint datum : data) {
if (datum.x < minX) {
minX = datum.x;
}
if (datum.y < minY) {
minY = datum.y;
}
if (datum.x > maxX) {
maxX = datum.x;
}
if (datum.y > maxY) {
maxY = datum.y;
}
}
}
private void drawAxes(ChartCanvas canvas) {
canvas.drawLine(minX, 0, maxX, 0);
canvas.drawLine(0, minY, 0, maxY);
}
private void drawXAxisLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double x = Math.round(minX + i * (maxX - minX) / 10);
canvas.drawLine(x, -0.25, x, 0.25);
canvas.drawTextBelow(x, -0.25, String.valueOf((int) x));
}
}
private void drawYAxisLabels(ChartCanvas canvas) {
for (int i = 0; i <= 10; ++i) {
double y = Math.round(minY + i * (maxY - minY) / 10);
canvas.drawLine(-0.25, y, 0.25, y);
canvas.drawTextLeft(-0.25, y, String.valueOf((int) y));
}
}
private void drawData(ChartCanvas canvas) {
for (CartesianPoint datum : data) {
canvas.drawPoint(datum.x, datum.y);
}
}
public void draw(Graphics2D context) {
ChartCanvas canvas = new ChartCanvas(context, minX, minY, maxX, maxY);
drawAxes(canvas);
drawXAxisLabels(canvas);
drawYAxisLabels(canvas);
drawData(canvas);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment