Page 3 of 4
We'll draw the rectangles in the color specified by the GraphItem. To allow us to go back to the original color, we set a temporary color variable to hold the current value before we change it. We cycle through the vector of graph items, calculating an adjusted
vertical value for each one, drawing the title of the item and a filled rectangle representing its value. The increment is
added to the x position variable each time through the loop.
The adjusted vertical value ensures that if the component is stretched vertically, the graph will still remain true to its
plotted values. To do this properly, we need to take the percentage of the range the item represents and multiply that value
by the actual pixel range of the graph drawing region. We then subtract the result from the bottom value to correctly plot the point.
As you can see from the following diagram, the total horizontal pixel size is represented by right - left and the total vertical size is represented by bottom - top.

We take care of the horizontal stretching by initializing the position variable to the left edge and increasing it by the increment variable for each item. Because the position and increment variables are dependent on the actual current pixel values, the component is always resized correctly in the horizontal direction.
To ensure that the vertical plotting is always correct, we must map the graph item values with actual pixel placements. There
is one complication: The max and min values should be meaningful to the position of the graph item value. In other words, if the graph starts at 150 and goes
to 200, an item with a value of 175 should appear halfway up the vertical axis. To achieve this, we find the percentage of
the graph range that the item represents and multiply it by the actual pixel range. Because our graph is upside down from
the graphics context's coordinate system, we subtract this number from bottom to find the correct plot point. Remember, the origin (0,0) is in the upper-left corner for the code, but the bottom-left
corner for the style of graph we are creating.

import java.awt.*;
public class LineGraph extends Graph {
int increment;
int position;
public LineGraph(String title, int min, int max) {
super(title, min, max);
}
Just as before, we need to space the items evenly, so we keep an increment variable to indicate the amount we will shift to the right for each item. The position variable is the current position, and the increment variable is added to it each time. The constructor simply calls the super constructor.
Almost all of the work is done in the paint method. Let's look at that now.
public void paint(Graphics g) {
super.paint(g);
increment = (right - left)/(items.size() - 1);
position = left;
Color temp = g.getColor();
GraphItem firstItem = (GraphItem)items.firstElement();
int firstAdjustedValue = bottom - (((firstItem.value - min)*(bottom - top)
)/(max - min));
g.setColor(firstItem.color);
g.drawString(firstItem.title, position - fm.stringWidth(firstItem.title),
firstAdjustedValue - 2);
g.fillOval(position - 2, firstAdjustedValue - 2, 4, 4);
g.setColor(temp);
for (int i = 0; i < items.size() - 1; i++) {
GraphItem thisItem = (GraphItem)items.elementAt(i);
int thisAdjustedValue = bottom - (((thisItem.value - min)*
(bottom - top))/(max - min));
GraphItem nextItem = (GraphItem)items.elementAt(i+1);
int nextAdjustedValue = bottom - (((nextItem.value - min)*
(bottom - top))/(max - min));
g.drawLine(position, thisAdjustedValue,
position+=increment, nextAdjustedValue);
g.setColor(nextItem.color);
if (nextAdjustedValue < thisAdjustedValue)
g.drawString(nextItem.title, position - fm.stringWidth(nextItem.title),
nextAdjustedValue + titleHeight + 4);
else
g.drawString(nextItem.title, position - fm.stringWidth(nextItem.title),
nextAdjustedValue - 4);
g.fillOval(position - 2, nextAdjustedValue - 2, 4, 4);
g.setColor(temp);
}
} // end paint
We first call the super paint method to draw the framework, then we implement our custom graph drawing. We find the value of the increment by measuring the difference between the left and right edges of the graph region and then by dividing the result by the number
of elements minus 1. This formula will produce the correct increment value. Because we are drawing points with the first one
at the left edge and the last one at the right edge, the increment is slightly different than it was with the bar chart. The position is initialized to the left edge of the drawing area.
Yes, it does work!By Anonymous on March 26, 2009, 11:20 amThe author may take this lesson out of context and assume that you can wrap his work with a simple JFrame yourself, but indeed it does work just fine. www.GoMotocross.com
Reply | Read entire comment
graph framework and custom graph componentsBy danjospehj82 on March 11, 2009, 9:49 pmDoes this code actually work I wonder??
Reply | Read entire comment
View all comments