如何将jfreecharts重定向到选项卡?

时间:2014-07-25 17:37:19

标签: java swing jframe jpanel jfreechart

我有6个以不同区域(A,B,C,S,SH,W)命名的选项卡,每个选项卡都显示来自csv文件的数据。在csv文件中,我有#milliseconds列,我将其转换为Hour和minutes,另一列是Zone的字母(与制表符相同)。我可以在选项卡上显示数据,但它只是在一个选项卡中显示每个区域数据。我试图在每个标签中显示每个区域的数据。我该怎么做呢?我已经看过这个主题,但它没有解决我的问题: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);
    }
}

1 个答案:

答案 0 :(得分:2)

您有一个TimeSeriests的静态实例,您可以向其中添加所有数据。然后,您可以使用该单个实例创建每个图表面板。结果,图表都显示相同的数据。而是创建一个TimeSeriesCollection的单个实例,为每个区域添加TimeSeries。您可以将区域名称用作系列键,然后在构建每个图表面板时按名称检索每个系列。

顺便说一下,考虑编码到集合界面,例如

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

附录:我是否为每个区域创建了 TimeSeries

是。鉴于以下声明,

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

您可以为每个区域的集合添加一个空系列,并使用区域名称作为每个TimeSeries的键。遇到CSV文件中的区域名称时,请按名称获取相应的TimeSeries并添加其数据。

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
}

稍后,使用区域名称获取构建图表所需的数据集。

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

最后,使用区域名称创建每个窗格。

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