JFeechart e JTable

14 respostas Resolvido
java
R

Gostaria que o gráfico tivesse os valores sendo retirados de um jtable, porém me falta lógica pra eu conseguir fazer isso. Eu teria que converter data em String para adiciona-lo nas label’s do gráfico e posteriormente fazer uma soma de todas as vendas por mês, separando-as. Exemplo mês 01/2017 com R$ 3000, mês 02/2017 com R$ 4000 e por ai vai

Exemplo Minimo

import java.awt.Color;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.table.AbstractTableModel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;

public class ExemploMinimo
{
    public class Request implements Serializable
    {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private Date registrationDate;
        private String noteTotal;

        public Date getRegistrationDate()
        {
            return registrationDate;
        }

        public void setRegistrationDate(Date registrationDate)
        {
            this.registrationDate = registrationDate;
        }

        public String getNoteTotal()
        {
            return noteTotal;
        }

        public void setNoteTotal(String noteTotal)
        {
            this.noteTotal = noteTotal;
        }
    }

    // ----------------------------------------------------------------------------------------
    public interface Dao<R>
    {
        public List<R> searchAll() throws Exception;
    }

    // ----------------------------------------------------------------------------------------
    public class ModelTableRequestRoute extends AbstractTableModel
    {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private List<Request> request = new ArrayList<>();
        private SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

        public ModelTableRequestRoute(List<Request> list)
        {
            request = list;
        }

        @Override
        public String getColumnName(int column)
        {
            switch (column)
            {
                case 0:
                    return "data";
                case 1:
                    return "valor";
            }
            return super.getColumnName(column);
        }

        @Override
        public int getColumnCount()
        {
            return 2;
        }

        @Override
        public int getRowCount()
        {
            return request.size();
        }

        @Override
        public Object getValueAt(int row, int column)
        {
            Request r = request.get(row);
            switch (column)
            {
                case 0:
                    return dateFormat.format(r.getRegistrationDate());
                case 1:
                    return r.getNoteTotal();
                default:
                    return null;
            }
        }

    }

    // ----------------------------------------------------------------------------------------

    public class FrameMinimo extends JFrame
    {
        /**
         * 
         */
        private static final long serialVersionUID = 4320341978109746731L;

        private List<Request> requestList = new ArrayList<>();

        private JPanel tablePanel;
        private JPanel graphicPanel;

        private Date currentDate = new Date();

        private JTable table;
        private JScrollPane scroll;

        public FrameMinimo()
        {
            inicializarComponentes();
            inicializarEventos();

            Request r = new Request();
            r.registrationDate = currentDate;
            r.noteTotal = "3000.00";
            requestList.add(r);

            ContruirTabela();
            construirGraficos();
        }

        private void inicializarComponentes()
        {
            setTitle("Exemplo Minimo");
            setSize(1150, 637);
            setLocationRelativeTo(null);
            setResizable(false);
            setLayout(null);
            setDefaultCloseOperation(EXIT_ON_CLOSE);

            // Table panel
            tablePanel = new JPanel();
            tablePanel.setSize(400, 402);
            tablePanel.setLocation(3, 3);
            tablePanel.setLayout(null);
            tablePanel.setBackground(Color.WHITE);
            tablePanel.setBorder(new LineBorder(Color.BLACK));
            add(tablePanel);

            // Table
            table = new JTable();
            scroll = new JScrollPane(table);
            scroll.setFont(getFont());
            scroll.setBorder(new LineBorder(Color.BLACK));
            scroll.setLocation(3, 3);
            scroll.setSize(394, 395);
            scroll.getViewport().setBackground(Color.WHITE);
            tablePanel.add(scroll);

            // Graphic panel
            graphicPanel = new JPanel();
            graphicPanel.setSize(737, 603);
            graphicPanel.setLocation(tablePanel.getX() + tablePanel.getWidth() + 1, 3);
            graphicPanel.setLayout(null);
            graphicPanel.setBackground(Color.WHITE);
            graphicPanel.setBorder(new LineBorder(Color.BLACK));
            add(graphicPanel);
        }

        private void ContruirTabela()
        {
            ModelTableRequestRoute modelTableRequestRoute = new ModelTableRequestRoute(requestList);
            table.setModel(modelTableRequestRoute);
        }

        private void construirGraficos()
        {
            // FIXME Create data set with table values
            DefaultCategoryDataset ds = new DefaultCategoryDataset();
            ds.addValue(40.5, "Venda", "01.2017"); // o valor de 40.5 deveria ser substituido pelo valor total calculado no mes
            ds.addValue(20.5, "Venda", "02/2017"); // Onde esta "Venda" não precisa ser alterado
            ds.addValue(40.5, "Venda", "03/2017"); // A data devera ser o mês e o ano em dois digitos

            // Create chart
            JFreeChart chart = ChartFactory.createLineChart("Vendas por Rota", "Mês", "Valor", ds, PlotOrientation.VERTICAL, true, true,
                    false);

            // Chart properties
            CategoryPlot plot = chart.getCategoryPlot();
            plot.setBackgroundPaint(Color.WHITE);
            plot.setRangeGridlinePaint(Color.GRAY);

            ChartPanel cp = new ChartPanel(chart);
            cp.setSize(730, 550);
            cp.setLocation(3, 3);
            cp.setVisible(true);
            graphicPanel.add(cp);
            graphicPanel.repaint();
        }

        private void inicializarEventos()
        {

        }
    }

    public static void main(String[] args)
    {
        ExemploMinimo e = new ExemploMinimo();
        FrameMinimo fm = e.new FrameMinimo();
        fm.setVisible(true);
    }
}

14 Respostas

A

Olá, é simples, faça o seguinte:

private void construirGraficos()
    {
        // FIXME Create data set with table values
        DefaultCategoryDataset ds = new DefaultCategoryDataset();

         for (Request request: requestList) {
           
             ds.addValue(new Double(request.getNoteTotal().replace(".", "").replace(",", ".")), new SimpleDateFormat("MM/yyyy").format(request.getRegistrationDate())); 

         }
}

Se não me engano em alguns tipos de gráfico o JFreeChart agrupa as informações e as soma, só não entendi o motivo de o valor ser uma String.

Caso o agrupamento não ocorra sugiro criar um Map<String, Double> para armazenar os dados antes de passar pro dataset daí você soma os valores antes.

R

O motivo de eu pensar que poderia ser uma string, foi que, em um dos meus testes ele me acusou o erro me informando que eu deveria converter a data para String ou algo assim. Vou testar o código e já dou um retorno

R

Ele fica me acusando um erro ao tentar usar o que você sugeriu, Segue abaixo o Erro

The method addValue(Number, Comparable, Comparable) in the type DefaultCategoryDataset is not applicable for the arguments (Double, String)

A

O dataset do gráfico pede 3 parâmetros o primeiro é o valor o segundo no seu caso seria o período e o terceiro seria a série, que como será somente uma deixe um valor padrão ex: ‘VALOR’

R

Me perdi um pouco nessa parte, eu entendi que ele recebe 3 parâmetros, o que eu me perdi foi esse ‘VALOR’ que você falou, onde coloca-lo e de onde saiu ele

R

Ignore minha ultima resposta, eu entendi, porém ele só pega o ultimo valor. você mencionou um map, você pode me dizer o que seria e o que ele faz?

A

Então, seria um agrupador de dados, exemplo, se num mês você quisesse exibir uma barra vermelha para valor e uma barra azul para descontos, por exemplo, você usaria addValue 2 vezes passando no último parâmetro “Valor” e “Desconto”, respectivamente.

ds.addValue(100.0, "09/2017", "Valor");
 ds.addValue(50.0, "09/2017", "Desconto");

Nesse caso ele não iria somar o segundo lançamento mesmo sendo do mesmo mês, pois sua série é diferente. Pelo que me lembro é isso.

R

Seria viável eu usar isso dentro de um laço de repetição? como eu apenas somaria as venda do mês e depois armazenaria o valor dentro de uma variável, você sabe como seria uma lógica pra pra ele somar apenas os valores do mesmo mês, e quando acabasse o mês ele somaria o do próximo. Desculpe se está um pouco confuso

R

Ele está pegando o ultimo valor apenas, não sei se a imagem ajuda, mas acho que pode dar uma ideia do que está acontecendo

A

Como disse antes, acho que o próprio JFreeChart faz isso (a soma), basta você ir usando o addValue no dataset, daí ele identifica que é do mesmo mês e soma. Não vejo outra forma de fazer sem que seja com um laço de repetição.

Caso o JFreeChart não faça a soma automática use um Map<String, Double>, onde a string é sua chave (mês) e o Double é o total correspondente ao mês, o próprio Map não vai deixar que sejam adicionados meses repetidos então basta você verificar a cada iteração do seu for se o mês já está no Map, caso esteja use o método get para obeter o valor do mês e o some e depois use put para alterar.

R

Certo, vou testar

A
Solucao aceita

Veja se isso ajuda:

Map<String, Double> mapa = new HashMap<>();

    for (Request request: requestList) {

        
        Double total = new Double(request.getNoteTotal().replace(".", "").replace(",", "."));
        String mes = new SimpleDateFormat("MM/yyyy").format(request.getRegistrationDate());
        
        if(mapa.containsKey(mes)){
            
            Double totalMes = mapa.get(mes);
            mapa.put(mes, (totalMes + total));
            
        } else {
            
            mapa.put(mes, total);
        }

    }
    
    for (Map.Entry<String, Double> entry : mapa.entrySet()){
        String mes = entry.getKey();
        Double total = entry.getValue();
        
        ds.addValue(mes, total, "Valor");
    }
R

Ajuda e muito, deu uma clareada na ideia pra mim

R

Funcionou certinho, Valeu mesmo

Criado 7 de outubro de 2017
Ultima resposta 9 de out. de 2017
Respostas 14
Participantes 2