-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChart.java
122 lines (104 loc) · 3.82 KB
/
Chart.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package chart;
import javax.swing.*;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
/**
* @author Cay Horstmann
* @version 1.34 2015-06-12
*/
public class Chart extends JApplet {
public void init() {
EventQueue.invokeLater(() -> {
String v = getParameter("values");
if (v == null) return;
int n = Integer.parseInt(v);
double[] values = new double[n];
String[] names = new String[n];
for (int i = 0; i < n; i++) {
values[i] = Double.parseDouble(getParameter("value." + (i + 1)));
names[i] = getParameter("name." + (i + 1));
}
add(new ChartComponent(values, names, getParameter("title")));
});
}
}
/**
* A component that draws a bar chart.
*/
class ChartComponent extends JComponent {
private double[] values;
private String[] names;
private String title;
/**
* Constructs a ChartComponent.
*
* @param v the array of values for the chart
* @param n the array of names for the values
* @param t the title of the chart
*/
public ChartComponent(double[] v, String[] n, String t) {
values = v;
names = n;
title = t;
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// compute the minimum and maximum values
if (values == null) return;
double minValue = 0;
double maxValue = 0;
for (double v : values) {
if (minValue > v) minValue = v;
if (maxValue < v) maxValue = v;
}
if (maxValue == minValue) return;
int panelWidth = getWidth();
int panelHeight = getHeight();
Font titleFont = new Font("SansSerif", Font.BOLD, 20);
Font labelFont = new Font("SansSerif", Font.PLAIN, 10);
// compute the extent of the title
FontRenderContext context = g2.getFontRenderContext();
Rectangle2D titleBounds = titleFont.getStringBounds(title, context);
double titleWidth = titleBounds.getWidth();
double top = titleBounds.getHeight();
// draw the title
double y = -titleBounds.getY(); // ascent
double x = (panelWidth - titleWidth) / 2;
g2.setFont(titleFont);
g2.drawString(title, (float) x, (float) y);
// compute the extent of the bar labels
LineMetrics labelMetrics = labelFont.getLineMetrics("", context);
double bottom = labelMetrics.getHeight();
y = panelHeight - labelMetrics.getDescent();
g2.setFont(labelFont);
// get the scale factor and width for the bars
double scale = (panelHeight - top - bottom) / (maxValue - minValue);
int barWidth = panelWidth / values.length;
// draw the bars
for (int i = 0; i < values.length; i++) {
// get the coordinates of the bar rectangle
double x1 = i * barWidth + 1;
double y1 = top;
double height = values[i] * scale;
if (values[i] >= 0)
y1 += (maxValue - values[i]) * scale;
else {
y1 += maxValue * scale;
height = -height;
}
// fill the bar and draw the bar outline
Rectangle2D rect = new Rectangle2D.Double(x1, y1, barWidth - 2, height);
g2.setPaint(Color.RED);
g2.fill(rect);
g2.setPaint(Color.BLACK);
g2.draw(rect);
// draw the centered label below the bar
Rectangle2D labelBounds = labelFont.getStringBounds(names[i], context);
double labelWidth = labelBounds.getWidth();
x = x1 + (barWidth - labelWidth) / 2;
g2.drawString(names[i], (float) x, (float) y);
}
}
}