views:

354

answers:

1

Ok, I know about JFreeChart and others, but I'm coding my own simple scatter graph. I've already got a box chart down (without y-axis labels but that shouldn't be a huge problem when I explain it in my report).

I've got a basic scatter graph class, however I've tried to change it so that I can add in different scatter values.

It works, but it only accepts the first scatter array and doesn't draw the rest. Although it does draw the first scatter array in the last scatter array's color... so it's semi-working.

Here's my full ScatterPanel class:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JPanel;

public class ScatterPanel extends JPanel {
    private TwoArray[] values;
    private String title;
    private String[] color_list;

    // Constructor for ScatterPanel
    public ScatterPanel(TwoArray[] v, String t, String[] c) {
        values = v;
        title = t;
        color_list = c;
    }

    /* This will paint the scatter chart
     * using the values from the above variables:
     * "values", "title" and "color_list"
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;

        // Initialize the titleFont
        Font titleFont = new Font("Verdana", Font.BOLD, 16);
        FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);

        // Get the width of the JPanel
        Dimension d = getSize();
        int clientWidth = d.width;
        //int clientHeight = d.height;

        // Setup the title position and size
        int titleWidth = titleFontMetrics.stringWidth(title);
        int title_y = titleFontMetrics.getAscent();
        int title_x = (clientWidth - titleWidth) / 2;

        // Set the font for the title
        g.setFont(titleFont);

        // Draw the title
        g.drawString(title, title_x, title_y);

        // Initialise min and max display scale
        double min = -0.5;
        double max = 5;

        // Iterate through each different algorithm we are comparing
        for(int point = 0; point < values.length; point++) {
            // Iterate through each algorithm's size array and timing array
            for (int i = 0; i < values[point].array_time.length; i++) {
                // Find the overall max and min for x and y
                double x = (double) values[point].array_size[i];
                double y = (double) values[point].array_time[i];
                // Adjust max and min to include x and y.
                if (x < min)
                    min = x - 0.5;
                if (x > max)
                    max = x + 0.5;
                if (y < min)
                    min = y - 0.5;
                if (y > max)
                    max = y + 0.5;
            }
        }

        g2.translate(getWidth()/2,getHeight()/2);
        g2.scale(getWidth()/(max-min), -getHeight()/(max-min));
        g2.translate(-(max+min)/2, -(max+min)/2);

        // Horizontal size of a pixel in new coords.
        double pixelWidth = (max-min)/getWidth();

        // Vertical size of a pixel in new coord.
        double pixelHeight = (max-min)/getHeight();

        g2.setStroke(new BasicStroke(0));

        // Draw the x and y axis
        g2.setColor(Color.BLUE);
        g2.draw( new Line2D.Double(min,0,max,0));
        g2.draw( new Line2D.Double(0,min,0,max));

        for(int point = 0; point < values.length; point++) {
            if(point % 3 == 0)
                g2.setColor(Color.decode(color_list[0]));
            else if(point % 3 == 1)
                g2.setColor(Color.decode(color_list[4]));
            else if(point % 3 == 2)
                g2.setColor(Color.decode(color_list[8]));

            for (int i = 0; i < values[point].array_time.length; i++) {
                long x = values[point].array_size[i];
                long y = values[point].array_time[i];

                // Plot the x-y co-ords
                g2.draw(new Line2D.Double(x-3*pixelWidth,y,x+3*pixelWidth,y));
                g2.draw(new Line2D.Double(x,y-3*pixelHeight,x,y+3*pixelHeight));
            }
        }
    }
}

TwoArray is just used to store two long arrays.

Inside my main interface class, I draw a scatter graph like this:

for(int i = 0; i < scat_size.length; i++)
    scat_size[i] = i;

for(int i = 0; i < scat_times.length; i++)
    scat_times[i] = i;

// This should be 1,1 2,2 3,3 etc. in Red
scatter_values[0] = new TwoArray(scat_size, scat_times);

// Trying to test a large co-ord so this should be green
scat_size[2] = 70;
scat_times[2] = 20;
scatter_values[1] = new TwoArray(scat_size, scat_times);

// Trying to test another different co-ord so this should be blue
scat_size[2] = 3;
scat_times[2] = 7;
scatter_values[2] = new TwoArray(scat_size, scat_times);

myScatter = new ScatterPanel(scatter_values, scat_title, color_list);

A JPanel is set to myScatter. It works and draws the scatter just fine, but it doesn't draw it with different colored points, and it draws the "red scatter" in the color blue.

Cheers guys.

P.S. I know I don't have any code that draws a curved line through the scatter yet, I'll work on that after I finish this part =)

+1  A: 

scatter_values[] will contain a pointer to the arrays scat_size and scat_times. You're changing values in these arrays, so the change will apply to all items in the scatter_values array. Thus it will draw the 3rd graph three times over the top of each other.

You need to add a dimension to the arrays:

for(int j = 0; j < 3; j++) {
    for(int i = 0; i < scat_size.length; i++)
        scat_size[j][i] = i;

    for(int i = 0; i < scat_times.length; i++)
        scat_times[j][i] = i;
}

// This should be 1,1 2,2 3,3 etc. in Red
scatter_values[0] = new TwoArray(scat_size[0], scat_times[0]);

// Trying to test a large co-ord so this should be green
scat_size[1][2] = 70;
scat_times[1][2] = 20;
scatter_values[1] = new TwoArray(scat_size[1], scat_times[1]);

// Trying to test another different co-ord so this should be blue
scat_size[2][2] = 3;
scat_times[2][2] = 7;
scatter_values[2] = new TwoArray(scat_size[2], scat_times[2]);

myScatter = new ScatterPanel(scatter_values, scat_title, color_list);
Paul
Ah, I just changed my interface using a different array like: scat_size2 and scat_size3 and it shows all 3 arrays!Thanks a lot!
Dan2k3k4