如何将jfreecharts重定向到选项卡? [英] How can I redirect my jfreecharts into the tabs?

查看:154
本文介绍了如何将jfreecharts重定向到选项卡?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有6个标签页,分别为不同的区域(A,B,C,S,SH,W)命名,每个标签页均显示来自CSV文件的数据.在csv文件中,我有一列#毫秒的列,我将其转换为小时和分钟,另一列是区域的字母(与制表符相同).我可以在选项卡上显示数据,但只在一个选项卡中显示每个区域数据.我试图在每个选项卡中显示每个区域的数据.我应该如何处理?我已经看过这个主题,但是并不能解决我的问题:添加使用JPanel将ChartPanel转换为JTabbedPane

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);
    }
}

推荐答案

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

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<>();

附录:我是否为每个区域创建一个 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并添加其数据.

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));
    }
    …
}

这篇关于如何将jfreecharts重定向到选项卡?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆