【问题标题】:How can I redirect my jfreecharts into the tabs?如何将我的 jfreecharts 重定向到选项卡?
【发布时间】:2014-07-25 17:37:19
【问题描述】:

我有 6 个选项卡,分别为不同的区域(A、B、C、S、SH、W)命名,每个选项卡都显示来自 csv 文件的自己的数据。在 csv 文件中,我有一列 # 毫秒,我将其转换为小时和分钟,另一列是区域的字母(与选项卡相同)。我可以在选项卡上显示数据,但它只在一个选项卡中显示每个区域数据。我试图在他们自己的每个选项卡中显示每个区域的数据。我应该如何处理这个?我已经看过这个话题,但它没有解决我的问题: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);
    }
}

【问题讨论】:

    标签: java swing jframe jpanel jfreechart


    【解决方案1】:

    您有一个 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));
        }
        …
    }
    

    【讨论】:

    • 你能举个例子来说明我如何做到这一点吗?我是否为每个区域创建 TimeSeries?
    • 我已经概述了上面的方法。
    • 我会将每个 TimeSeries 放在哪里?
    • @vandale 我在哪里可以找到坐标轴以确保它们是正确的?
    • @c.torres:TimeSeriesCollection 很方便,因为它可以让您按名称检索单个系列。
    猜你喜欢
    • 2015-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多