c.torres
c.torres

Reputation: 31

How can I redirect my jfreecharts into the tabs?

I have 6 tabs that are named for different zones (A,B,C,S,SH,W) and each show their own data from the csv file. Inside the csv file I have a columns of # milliseconds that I convert to Hour and minutes and the other column is the letter of the Zone (same as tabs). I can display the data on the tab but it just shows each of the zones data in one tab. I am trying to show each of the zone's data in each of their own tabs. How should I approach this? I already looked at this topic but it didn't solve my problem : Adding ChartPanel to JTabbedPane using JPanel

public class NewestInductionGraph {

    private static final String titles[] = {"Zone A", "Zone B",
        "Zone C", "Zone S", "Zone SH", "Zone W"};

    final static TimeSeries ts = new TimeSeries("data", Minute.class);
    static Day day = new Day(9,7,2014);

    private void display() {
        JFrame f = new JFrame("Induction Zone Chart");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTabbedPane jtp = new JTabbedPane();
        final int i = 0;
        jtp.add(titles[i], createPane());
        jtp.add(createPane(), createInduction());
        f.add(jtp, BorderLayout.CENTER);
        final JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        final JPanel p1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        p.add(new JButton(new AbstractAction("Add Other Zones") {

            public void actionPerformed(ActionEvent e) {
                jtp.add(titles[i+1], createPane());
                jtp.add(titles[i+2], createPane());
                jtp.add(titles[i+3], createPane());
                jtp.add(titles[i+4], createPane());
                jtp.add(titles[i+5], createPane());
            }
        }));

        p1.add(new JButton(new AbstractAction("Update") {

            public void actionPerformed(ActionEvent e) {

            }
        }));
        f.add(p, BorderLayout.NORTH);
        f.add(p1, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private TreeMap<String, TreeMap<Integer, Integer[]>> createInduction() {

        final TreeMap<String, TreeMap<Integer, Integer[]>> zoneMap = new TreeMap<String, TreeMap<Integer, Integer[]>>();

        String fileName = "/home/a002384/ECLIPSE/IN070914.CSV";

        try 
        {
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            String line;
            try
            {
                // Read a line from the csv file until it reaches to the end of the file...
                while ((line = br.readLine()) != null)
                {
                    // Parse a line of text in the CSV...
                    String [] indData = line.split("\\,");
                    long millisecond = Long.parseLong(indData[0]);
                    String zone = indData[1];

                    // The millisecond value is the number of milliseconds since midnight.
                    // From this, we can derive the hour and minute of the day as follows:
                    int secOfDay = (int)(millisecond / 1000);
                    int hrOfDay = secOfDay / 3600;
                    int minInHr = secOfDay % 3600 / 60;

                    // Obtain the induction rate TreeMap for the current zone.
                    // If this is a "newly-encountered" zone, create a new TreeMap.
                    TreeMap<Integer, Integer[]> hourCountsInZoneMap;
                    if (zoneMap.containsKey(zone))
                        hourCountsInZoneMap = zoneMap.get(zone);
                    else
                        hourCountsInZoneMap = new TreeMap<Integer, Integer[]>();

                    // Obtain the induction rate array for the current hour in the current zone.
                    // If this is a new hour in the current zone, create a new array,
                    // and initialize this array with all zeroes.
                    // The array is size 60, because there are 60 minutes in the hour.
                    // Each element in the array represents the induction rate for that minute.
                    Integer [] indRatePerMinArray;
                    if (hourCountsInZoneMap.containsKey(hrOfDay))
                        indRatePerMinArray = hourCountsInZoneMap.get(hrOfDay);
                    else
                    {
                        indRatePerMinArray = new Integer[60];
                        Arrays.fill(indRatePerMinArray, 0);
                    }

                    // Increment the induction rate for the current minute by one.
                    // Each line in the csv file represents a single induction at a
                    // single point in time.
                    indRatePerMinArray[minInHr]++;

                    // Add everything back into the TreeMaps if these are newly-created.
                    if (!hourCountsInZoneMap.containsKey(hrOfDay))
                        hourCountsInZoneMap.put(hrOfDay, indRatePerMinArray);
                    if (!zoneMap.containsKey(zone))
                        zoneMap.put(zone, hourCountsInZoneMap);
                }
            }
            finally
            {
                br.close();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }   

        // Iterate through all zones and print induction rates for every minute into
        // every hour by zone...
        Iterator<String> zoneIT = zoneMap.keySet().iterator();
        while (zoneIT.hasNext())
        {
            String zone = zoneIT.next();
            TreeMap<Integer,Integer[]> hourCountsInZoneMap = zoneMap.get(zone);
            System.out.println("ZONE " + zone + " : ");
            Iterator<Integer> hrIT = hourCountsInZoneMap.keySet().iterator();
            while (hrIT.hasNext())
            {
                int hour = hrIT.next();
                Integer [] indRatePerMinArray = hourCountsInZoneMap.get(hour);
                for (int i=0; i< indRatePerMinArray.length; i++)
                {
                    System.out.print(hour + ":");
                    System.out.print(i < 10 ? "0" + i : i);
                    System.out.println(" = " + indRatePerMinArray[i] + " induction(s)");
                }
            }
        }

        TreeMap<Integer, Integer[]> dayAZone = zoneMap.get("A");
        Iterator<Integer> hourIT = dayAZone.keySet().iterator();
        while (hourIT.hasNext())
        {
            Integer indHour = hourIT.next();
            Hour hour = new Hour(indHour, day);
            Integer [] indMins = dayAZone.get(indHour);
            for (int i = 0; i < 60; i++)
                   ts.addOrUpdate(new Minute(i, hour), indMins[i]);
                    System.out.println(zoneMap);

        }

        TreeMap<Integer, Integer[]> dayBZone = zoneMap.get("B");
        Iterator<Integer> hourIT1 = dayBZone.keySet().iterator();
        while (hourIT1.hasNext())
        {
            Integer indHour = hourIT1.next();
            Hour hour = new Hour(indHour, day);
            Integer [] indMins = dayBZone.get(indHour);
            for (int i = 0; i < 60; i++)
                   ts.addOrUpdate(new Minute(i, hour), indMins[i]);
                    System.out.println(zoneMap);

        }

        TreeMap<Integer, Integer[]> dayCZone = zoneMap.get("C");
        Iterator<Integer> hourIT2 = dayCZone.keySet().iterator();
        while (hourIT2.hasNext())
        {
            Integer indHour = hourIT2.next();
            Hour hour = new Hour(indHour, day);
            Integer [] indMins = dayCZone.get(indHour);
            for (int i = 0; i < 60; i++)
                   ts.addOrUpdate(new Minute(i, hour), indMins[i]);
                   System.out.println(zoneMap);
        }

        TreeMap<Integer, Integer[]> daySZone = zoneMap.get("S");
        Iterator<Integer> hourIT3 = daySZone.keySet().iterator();
        while (hourIT3.hasNext())
        {
            Integer indHour = hourIT3.next();
            Hour hour = new Hour(indHour, day);
            Integer [] indMins = daySZone.get(indHour);
            for (int i = 0; i < 60; i++)
               if (indMins[i] > 0)
                   ts.addOrUpdate(new Minute(i, hour), indMins[i]);
                   System.out.println(zoneMap);
        }

        TreeMap<Integer, Integer[]> daySHZone = zoneMap.get("SH");
        Iterator<Integer> hourIT4 = daySHZone.keySet().iterator();
        while (hourIT4.hasNext())
        {
            Integer indHour = hourIT4.next();
            Hour hour = new Hour(indHour, day);
            Integer [] indMins = daySHZone.get(indHour);
            for (int i = 0; i < 60; i++)
                   ts.addOrUpdate(new Minute(i, hour), indMins[i]);
                   System.out.println(zoneMap);
        }

            TreeMap<Integer, Integer[]> dayWZone = zoneMap.get("W");
        Iterator<Integer> hourIT5 = dayWZone.keySet().iterator();
        while (hourIT5.hasNext())
        {
            Integer indHour = hourIT5.next();
            Hour hour = new Hour(indHour, day);
            Integer [] indMins = dayWZone.get(indHour);
            for (int i = 0; i < 60; i++)
                   ts.addOrUpdate(new Minute(i, hour), indMins[i]);
                   System.out.println(zoneMap);
        }

        return zoneMap;
    }

    private ChartPanel createPane() {

        TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(ts);
        new Timer(1000, new ActionListener() {

            public void actionPerformed(ActionEvent e) {

            }
        }).start();
        JFreeChart chart = ChartFactory.createXYBarChart(
                "Induction Zone", 
                "Hour", 
                true, 
                "Inductions Per Minute", 
                dataset, 
                PlotOrientation.VERTICAL, 
                true, 
                true, 
                false
                );

        XYPlot plot = (XYPlot)chart.getPlot();
        XYBarRenderer renderer = (XYBarRenderer)plot.getRenderer();
        renderer.setBarPainter(new StandardXYBarPainter());
        renderer.setDrawBarOutline(false);

        // Set an induction of 30 per minute...
        Marker target = new ValueMarker(30);
        target.setPaint(java.awt.Color.blue);
        target.setLabel("Target Rate");
        plot.addRangeMarker(target); 

        return new ChartPanel(chart) {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(1000, 600);
            }
        };
    }

    public static void main(String[] args) {
        Runnable runner = new Runnable() {
            public void run() {
                new NewestInductionGraph().display();
            }
        };
        EventQueue.invokeLater(runner);
    }
}

Upvotes: 0

Views: 120

Answers (1)

trashgod
trashgod

Reputation: 205835

You have a single, static instance of TimeSeries, ts, to which you add all your data. You then use that single instance to create each chart panel. As a result, the charts all display the same data. Instead, create a single instance of TimeSeriesCollection to which you add a TimeSeries for each zone. You can use the zone name as the series key and later retrieve each series by name as you construct each chart panel.

As an aside, consider coding to the collection interface, for example

Map<String, Map<Integer, List<Integer>>> zoneMap = new TreeMap<>();

Addendum: Do I create a TimeSeries for each zone?

Yes. Given the following declarations,

private static final String titles[] = {
    "Zone A", "Zone B", "Zone C", "Zone S", "Zone SH", "Zone W"};
private final TimeSeriesCollection all = new TimeSeriesCollection();

You can add an empty series to the collection for each zone and use the zone name as the key of each TimeSeries. When encountering a zone name in the CSV file, get the corresponding TimeSeries by name and add its data.

private void createInduction() {
    for (String s : titles) {
        all.addSeries(new TimeSeries(s));
    }
    // while parsing the CSV file
    String zone = …;
    TimeSeries ts = all.getSeries(zone);
    // add data to this zone's series
}

Later, use the zone name to get the dataset needed to construct the chart.

private ChartPanel createPane(String title) {
    TimeSeriesCollection dataset = new TimeSeriesCollection(all.getSeries(title));
    JFreeChart chart = ChartFactory.createXYBarChart(…. dataset. …);
    // decorate chart
    return new ChartPanel(chart);
}

Finally, use the zone name to create each pane.

private void display() {
    …
    JTabbedPane jtp = new JTabbedPane();
    for (String s : titles) {
        jtp.add(createPane(s));
    }
    …
}

Upvotes: 2

Related Questions