Как сделать построение графиков с помощью jfreecharts более динамичным? - PullRequest
0 голосов
/ 04 января 2019

Введение

Моя цель - ввести набор продуктов и выбрать параметр для отображения, например:

System.out.print("Input number of products to represent: ");
      prodNum = scan.nextInt();
      String[] prodName = new String[prodNum];
System.out.print("Enter which products to represent: ");
     for (int i = 0; i < prodName.length; i++)
         {
           prodName[i] = scan.next();
         }
System.out.println("----Options----");
System.out.println("1. Cantidad");
System.out.println("2. Calidad");
System.out.println("3. RealmQ");
System.out.println("4. Coste");
      option = scan.nextInt();                

      userOptionWas(option);

, а затем с помощью JFreeCharts я хотелуметь выбирать, сколько строк (для каждого вводимого продукта) и какую опцию отображать (количество, качество и материал), которая хранится внутри некоторых явно названных массивов.

Мой подход

  private XYDataset multipleLine(int prodNum, String[] prodName, int option){

   XYSeriesCollection dataset = new XYSeriesCollection();

   XYSeries product3 = new XYSeries("product3");
   XYSeries product4 = new XYSeries("product4");
   XYSeries product5 = new XYSeries("product5");
   XYSeries product6 = new XYSeries("product6");
   XYSeries product7 = new XYSeries("product7");
   XYSeries product8 = new XYSeries("product8");

   switch(prodNum)
   {
       case(2):
       {

           if (option == 1)
           {
                XYSeries product1 = new XYSeries(prodName[0]);
                XYSeries product2 = new XYSeries(prodName[1]);

                for (int i = 0; i < CSVinput.cantidad.length; i++)
                {
                    try
                    {
                        if (CSVinput.nombre[i].equals(prodName[0]))
                        {                            
                            product1.add(i, CSVinput.cantidad[i]);
                        }
                    }catch(ArrayIndexOutOfBoundsException e){}
                    }
           }
           if (option == 2)
           {

           }
           if (option == 3)
           {

           }
           if (option == 4)
           {

           }

       }
   }       
   return dataset;
 }

На полпути реализации моей идеи я начал задаваться вопросом, невозможно ли это сделать, или просто я не на пути к своей цели.

Чего я ожидаю

  • Я хочу иметь возможность создавать различные графики из простого меню, которое я показывал ранее.
  • Если это возможно, динамическое (, если я ввожу 2 продуктапрограмма отображает 2 строки, относящиеся к каждому продукту )

Дополнительные примечания

  • Я новичок в JFreeCharts.

  • Найдите минутку здесь product1.add(i, CSVinput.cantidad[i]);, где я использую (int) «i» вместо моей (String) «date» fOrmat.Почему я не могу использовать строку?Есть ли способ обойти это?

Чего я ожидаю от этого вопроса

Я хотел бы узнать более эффективные и дружественные способы достижения этого без излишней сложности.

Пример данных

2018/12/29-Tejido,321 908,13.55,43.18,$15.98,
2018/12/29-Ropa,195 045,20.55,45.93,$123.01,
2018/12/29-Gorra de visera,126 561,17.43,42.32,$79.54,
2018/12/29-Cerveza,80 109,3.37,17.93,$12.38,
2018/12/29-Mercancías de playa,75 065,11.48,39.73,$105.93,
2018/12/29-Bebidas alcohólicas,31 215,4.84,27.90,$32.29,
2018/12/29-Artículos de cuero,19 098,23.13,44.09,$198.74,
2018/12/29-Bolsas y carteras,7 754,23.09,41.34,$1 176.54,
2018/12/30-Tejido,252 229,12.86,43.14,$18.87,
2018/12/30-Ropa,132 392,18.09,46.02,$177.58,
2018/12/30-Gorra de visera,87 676,14.42,42.46,$122.48,
2018/12/30-Cerveza,44 593,2.72,17.79,$18.71,
2018/12/30-Mercancías de playa,44 593,8.26,39.56,$200.78,
2018/12/30-Bebidas alcohólicas,27 306,4.30,23.88,$31.95,
2018/12/30-Artículos de cuero,16 147,21.08,43.91,$207.49,
2018/12/30-Bolsas y carteras,6 552,21.11,40.59,$1 195.41,
2019/01/02-Tejido,321 908,13.55,43.18,$15.98,
2019/01/02-Ropa,195 045,20.55,45.93,$123.01,
2019/01/02-Gorra de visera,126 561,17.43,42.32,$79.54,
2019/01/02-Cerveza,80 109,3.37,17.93,$12.38,
2019/01/02-Mercancías de playa,75 065,11.48,39.73,$105.93,
2019/01/02-Bebidas alcohólicas,31 215,4.84,27.90,$32.29,
2019/01/02-Artículos de cuero,19 098,23.13,44.09,$198.74,
2019/01/02-Bolsas y carteras,7 754,23.09,41.34,$1 176.54,
2019/01/03-Tejido,1 164 607,12.87,43.14,$15.54,
2019/01/03-Ropa,131 409,17.18,45.97,$161.17,
2019/01/03-Gorra de visera,79 242,13.54,43.17,$100.38,
2019/01/03-Cerveza,48 332,2.80,18.10,$17.48,
2019/01/03-Mercancías de playa,46 157,8.70,38.39,$180.54,
2019/01/03-Bebidas alcohólicas,25 210,4.04,23.72,$33.52,
2019/01/03-Artículos de cuero,14 321,19.56,39.92,$216.00,
2019/01/03-Bolsas y carteras,5 814,19.85,39.68,$1 227.29,

РЕДАКТИРОВАТЬ:

Большое спасибо за помощь, я думаю, что я узнал, но путьникогда не заканчивается, так как по какой-то причине экземпляр, который берет набор данных, не отображает набор данных Что мне не хватает? .

PD: Дайте мне знать в комментариях, если вынужен CSVinput для предоставления решения.

import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Scanner;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.general.SeriesException;
import org.jfree.data.time.Day;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

import webscrapper.CSVinput;

/**
 *
 * @author Jonathan
 */
public class TimeSeriesChartExample extends ApplicationFrame{

    //To parse dates below and be able to debug outside the loop
    public static String[] dateSplit;

    //Instace that declares properties and uses the dataset to create the chart
    public TimeSeriesChartExample(String title) 
    {
       super(title);
       // Create dataset
       XYDataset dataset = createDataset();
       // Create chart
       JFreeChart chart = ChartFactory.createTimeSeriesChart(
           "Titulo", // Chart
           "Date", // X-Axis Label
           "Number", // Y-Axis Label
           dataset);

        //Changes background color
        XYPlot plot = (XYPlot)chart.getPlot();
        plot.setBackgroundPaint(new Color(255,228,196));  
    }
    //Create the set of data to be plotted
    private XYDataset createDataset() 
    {
        //A collection of datasets
        TimeSeriesCollection dataset = new TimeSeriesCollection();
        //The object were this new series are added thus it's name
        TimeSeries prod1 = new TimeSeries("Cantidad");

            //"For each" name stored in the array
            for (int i = 0; i < CSVinput.nombre.length; i++)
            {
                //If name equals 
                if ("Ropa".equals(CSVinput.nombre[i]))
                {
                    //Pass the "i" position to work it
                    dateSplit = CSVinput.fecha[i].split("/");
                        //Parse the date
                        int day = Integer.parseInt(dateSplit[2]);
                        int month = Integer.parseInt(dateSplit[1]);
                        int year = Integer.parseInt(dateSplit[0]);
                        System.out.println("day is: " + day);
                    //Pass the parsed date and the value from CSV.cantidad at "i" position referring to the name "Ropa"
                    prod1.add(new Day(day, month, year), CSVinput.cantidad[i]);
                    System.out.println(CSVinput.cantidad[i]);//Debug stuff
                }         
            }                    
            //Add everything to the dataset
            dataset.addSeries(prod1);     
        //Return it
        return dataset;
    }
    private XYDataset createDataset2()
    {
        //A collection of datasets
        TimeSeriesCollection dataset = new TimeSeriesCollection();
        //The object were this new series are added thus it's name
        TimeSeries prod2 = new TimeSeries("Cantidad");

            //"For each" name stored in the array
            for (int i = 0; i < CSVinput.nombre.length; i++)
            {
                //If name equals 
                if (CSVinput.nombre[i] == "Tejido")
                {
                    //Pass the "i" position to work it
                    dateSplit = CSVinput.fecha[i].split("/");
                        //Parse the date
                        int day = Integer.parseInt(dateSplit[0]);
                        int month = Integer.parseInt(dateSplit[1]);
                        int year = Integer.parseInt(dateSplit[2]);
                    //Pass the parsed date and the value from CSV.cantidad at "i" position referring to the name "Ropa"
                    prod2.add(new Day(day, month, year), CSVinput.cantidad[i]);
                    System.out.println(CSVinput.cantidad[i]);//Debug stuff
                }         
            }                    
            //Add everything to the dataset
            dataset.addSeries(prod2);     
        //Return it
        return dataset;
    }

    public static void main(String[] args) throws FileNotFoundException
    {       
       //Custom class to import data from the csv into arrays (TODO: make it dynamic)
       CSVinput.ImportData("caca.csv");

       /* //More debugg stuff
       dateSplit = CSVinput.fecha[1].split("/");
       System.out.println("year: " + dateSplit[0] + " month: " + dateSplit[1] + " day: " + dateSplit[2]);
       */

       //Create an instance of the previous class 
       final TimeSeriesChartExample example = new TimeSeriesChartExample("ItWorks!");
       example.pack(); //Part from the ApplicationFrame
       RefineryUtilities.centerFrameOnScreen(example); //Render the graph at the center of screen
       example.setVisible(true);  //make it visible
    }
    }

1 Ответ

0 голосов
/ 04 января 2019

Сначала сфокусируйтесь на модели данных вашей программы:

  • Если ваша серия включает временную область, рассмотрите возможность использования TimeSeriesCollection из TimeSeries вместо XYSeries; TimeSeriesChartDemo1, цитируемый здесь , является базовым примером; разбирать даты как показано здесь и здесь ; для доступа к базе данных рассмотрим JDBCXYDataset.

  • Когда вы читаете данные для каждой серии, сохраняйте серию в List<TimeSeries>, а не в массиве; если задержка является проблемой, выполните синтаксический анализ в фоновом режиме, как показано здесь .

Точные детали будут зависеть от дизайна вашего приложения, но использование шаблона наблюдателя минимизирует сложность; Основной принцип заключается в обновлении модели (Dataset), и прослушивающий view (JFreeChart) обновится в ответ. Используя Swing, например, вы можете управлять отображаемым графиком несколькими способами:

  • Используйте ваш List<TimeSeries> для построения подходящего ListModel<TimeSeries>; для меню серии выберите выбранную модель DefaultComboBoxModel<TimeSeries> для JComboBox или DefaultListModel<TimeSeries> для JList.

  • Добавьте подходящего слушателя к вашему компоненту меню; дайте свой XYPlot а TimeSeriesCollection; используйте addSeries() или removeSeries(), чтобы изменить график при выборе серии; в качестве альтернативы, используйте setSeriesVisible() для переключения видимости, как показано здесь .

Для интерфейса командной строки взаимодействия менее сложны, но и менее универсальны:

  • Используйте List<TimeSeries>, чтобы построить TimeSeriesCollection.

  • Используйте методы TimeSeriesCollection для управления отображением прослушивания XYPlot.

...