/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/*
* Chart.java
*
* Created on 06-ago-2010, 10:07:32
*/
package com.GestDB.swing;
import com.GestDB.general.Trackbug;
import com.GestDB.sql.JdbcTModel;
import com.GestDB.sql.SortTModel;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.util.Calendar;
import javax.swing.JTable;
import com.utils.utilidades;
import java.util.Vector;
/**
*
* @author seni
*/
public class Chart extends javax.swing.JPanel {
/** Creates new form Chart */
public Chart(int tipo) {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
@Override
public void paint(Graphics g)
{
super.paint(g);
if ((getWidth() <= 0) || (getHeight() <= 0)) {
return;
}
Graphics2D g2 = (Graphics2D)g;
Rectangle clipRect = g2.getClipBounds();
int clipX;
int clipY;
int clipW;
int clipH;
if (clipRect == null) {
clipX = clipY = 0;
clipW = getWidth();
clipH = getHeight();
}
else {
clipX = clipRect.x;
clipY = clipRect.y;
clipW = clipRect.width;
clipH = clipRect.height;
}
if(clipW > getWidth()) {
clipW = getWidth();
}
if(clipH > getHeight()) {
clipH = getHeight();
}
if (clipRect == null) {
g2.setClip(clipX, clipY, clipW, clipH);
}
// dibujamos las lineas de la gr�fica
// pueden ser 2d o 3d
// sacamos la esquina inferior izquierda de la l�neas en la que coinciden los tres l�nes X, Y y Z. es decir el eje.
FontMetrics fm = getGraphics().getFontMetrics(this.getFont());
Calendar cal = Calendar.getInstance();
String cadena = biColYMax.toString();
if(tmodel != null && esFecha(tmodel.columnTypes[coly[0]]))
{
cal.setTimeInMillis(tiColYMax.getTime());
cadena = utilidades.GenDateString(cal,false,tmodel.columnTypes[coly[0]]);
}
int anchoTitles = 100;
int maxAncho = fm.bytesWidth(cadena.getBytes(), 0, cadena.length());
int margenY = 38;
int margenX = 50;
if(margenX < (maxAncho + 15))
margenX = maxAncho + 15;
int ejeX = clipX + margenX;
int ejeY = clipY + clipH - margenY;
int anchoChart = clipW - (margenX + margenX);
int altoChart = clipH - (margenY * 2);
int porcionesAncho = 20;
int porcionesAlto = 10;
if(tmodel != null && porcionesAncho > numElementosX)
porcionesAncho = numElementosX;
if(bDrawTitles)
anchoChart = anchoChart - anchoTitles;
double incrementoX = (double)anchoChart / (double)porcionesAncho;
double incrementoY = (double)altoChart / (double)porcionesAlto;
if(ejeY < margenY)
return;
g2.setColor(Color.BLACK);
g2.drawLine(margenX, margenY, ejeX, ejeY);
g2.drawLine(ejeX, ejeY, ejeX + anchoChart, ejeY);
if(tmodel != null)
{
if(tipo == CHART_2D)
{
// l�neas verticales
double i = (double)margenY;
int k = 0;
BigDecimal biIncrementoY = null;
long lIncrementoY = 0;
if(esFecha(tmodel.columnTypes[coly[0]]) == false)
{
biIncrementoY = biColYMax.subtract(biColYMin).divide(new BigDecimal(porcionesAlto),mathContext);
}
else
{
lIncrementoY = (tiColYMax.getTime() - tiColYMin.getTime()) / porcionesAlto;
}
int ancho = 0;
while(i < ejeY)
{
if(bDrawLines)
{
g2.setColor(Color.LIGHT_GRAY);
g2.drawLine(margenX, (int)i, margenX + anchoChart, (int)i);
g2.setColor(Color.BLACK);
}
g2.drawLine(margenX, (int)i, margenX + 5, (int)i);
if(esFecha(tmodel.columnTypes[coly[0]]) == false)
{
cadena = biColYMax.subtract(biIncrementoY.multiply(new BigDecimal(k++))).toString();
}
else
{
cal.setTimeInMillis(new java.util.Date(tiColYMin.getTime() + (lIncrementoY * k++)).getTime());
cadena = utilidades.GenDateString(cal,false,tmodel.columnTypes[coly[0]]);
}
ancho = fm.bytesWidth(cadena.getBytes(), 0, cadena.length());
Trackbug.info("Cadena: [" + cadena + "], longitud: " + ancho);
g2.drawString(cadena, 10 + (maxAncho - ancho), (int)i + 5);
i += incrementoY;
}
// l�neas horizontales
i = (double)margenX;
double limite = margenX + anchoChart;
k = 0;
int posY2 = 0;
BigDecimal biIncrementoX = null;
long lIncrementoX = 0;
if(esFecha(tmodel.columnTypes[colx]) == false)
{
biIncrementoX = biColXMax.subtract(biColXMin).divide(new BigDecimal(porcionesAncho),mathContext);
}
else
{
lIncrementoX = (tiColXMax.getTime() - tiColXMin.getTime()) / porcionesAncho;
}
while(i <= limite)
{
if(bDrawLines)
{
g2.setColor(Color.LIGHT_GRAY);
g2.drawLine((int)i, ejeY, (int)i, margenY);
g2.setColor(Color.BLACK);
}
g2.drawLine((int)i, ejeY, (int)i, ejeY - 5);
if(esFecha(tmodel.columnTypes[colx]) == false)
{
cadena = biIncrementoX.multiply(new BigDecimal(k++)).toPlainString();
ancho = fm.bytesWidth(cadena.getBytes(), 0, cadena.length()) / 2;
g2.drawString(cadena, (int)i - ancho, ejeY + 12);
}
else
{
cal.setTimeInMillis(new java.util.Date(tiColXMin.getTime() + (lIncrementoX * k++)).getTime());
cadena = utilidades.GenDateString(cal,false,tmodel.columnTypes[colx]);
ancho = fm.bytesWidth(cadena.getBytes(), 0, cadena.length()) / 2;
++posY2;
if(posY2 > 3 || (posY2 > 2 && tmodel.columnTypes[colx] != java.sql.Timestamp.class))
posY2 = 1;
g2.drawString(cadena, (int)i - ancho, ejeY + (12 * posY2));
}
i += incrementoX;
}
// vamos con las leyendas
if(bDrawTitles)
{
int posIni = margenX + anchoChart + 15;
posY2 = margenY;
for(k=0; k < coly.length; k++, posY2 += 16)
{
g2.setColor(colores[k]);
g2.fill3DRect(posIni, posY2, 12, 12, true);
g2.setColor(Color.BLACK);
g2.drawString(tmodel.columnNames[coly[k]], posIni + 17, posY2 + 10);
}
g2.setColor(Color.BLACK);
g2.drawString(tmodel.columnNames[colx], posIni + 47, ejeY + 12);
}
// Dibujamos los puntos y las l�neas de la gr�fica
boolean bPrimeraVez = true;
int xAnterior = 0;
int yAnterior[] = new int[coly.length];
int xActual = -1;
int yActual = -1;
incrementoX = (double)anchoChart / (double)100;
incrementoY = (double)altoChart / (double)100;
BigDecimal bi100PorCienX = null;
BigDecimal bi100PorCienY = null;
long l100PorCienX = 0;
long l100PorCienY = 0;
if(esFecha(tmodel.columnTypes[colx]) == false)
{
bi100PorCienX = biColXMax.subtract(biColXMin);
}
else
{
l100PorCienX = tiColXMax.getTime() - tiColXMin.getTime();
}
if(esFecha(tmodel.columnTypes[coly[0]]) == false)
{
bi100PorCienY = biColYMax.subtract(biColYMin);
}
else
{
l100PorCienY = tiColYMax.getTime() - tiColYMin.getTime();
}
BigDecimal bi100 = new BigDecimal(100);
BigDecimal biValorX = null;
BigDecimal biValorY = null;
BigDecimal biValor = null;
long lValorX = 0;
long lValorY = 0;
long lValor = 0;
biIncrementoX = new BigDecimal(incrementoX);
biIncrementoY = new BigDecimal(incrementoY);
for(int j=0, ilimite = tmodel.rows.size(); j < ilimite; j++)
{
// se aplica una regla de 3 para calcular la posici�n del punto
if(esFecha(tmodel.columnTypes[colx]) == false)
{
biValorX = ObjectToBigDecimal(sorttmodel.getValueAt(j, colx));
biValor = (((biValorX.subtract(biColXMin)).multiply(bi100)).divide(bi100PorCienX,2,RoundingMode.FLOOR)).multiply(biIncrementoX);
xActual = ejeX + biValor.intValue();
}
else
{
lValorX = ObjectTolong(sorttmodel.getValueAt(j, colx));
lValor = (long) ((((lValorX - tiColXMin.getTime()) * 100) / l100PorCienX) * incrementoX);
xActual = (int) (ejeX + lValor);
}
for(k=0; k < coly.length; k++)
{
g2.setColor(colores[k]);
if(esFecha(tmodel.columnTypes[coly[k]]) == false)
{
biValorY = ObjectToBigDecimal(sorttmodel.getValueAt(j, coly[k]));
biValor = (((biValorY.subtract(biColYMin)).multiply(bi100)).divide(bi100PorCienY,2,RoundingMode.FLOOR)).multiply(biIncrementoY);
yActual = ejeY - biValor.intValue();
}
else
{
lValorY = ObjectTolong(sorttmodel.getValueAt(j, coly[k]));
lValor = (long) ((((lValorY - tiColYMin.getTime()) * 100) / l100PorCienY) * incrementoY);
yActual = (int) (ejeY - lValor);
}
g2.drawOval(xActual - 4, yActual - 4, 8, 8);
g2.fillOval(xActual - 2, yActual - 2, 4, 4);
if(!bPrimeraVez)
g2.drawLine(xAnterior, yAnterior[k], xActual, yActual);
else
g2.drawLine(ejeX, ejeY, xActual, yActual);
if(bDrawValues)
{
g2.setColor(Color.BLACK);
if(esFecha(tmodel.columnTypes[coly[k]]) == false)
{
cadena = biValorY.toString() + "/";
}
else
{
cal.setTimeInMillis(new java.util.Date(lValorY).getTime());
cadena = utilidades.GenDateString(cal,false,tmodel.columnTypes[coly[k]]) + "+";
}
if(esFecha(tmodel.columnTypes[colx]) == false)
{
cadena += biValorX.toString();
}
else
{
cal.setTimeInMillis(new java.util.Date(lValorX).getTime());
cadena += utilidades.GenDateString(cal,false,tmodel.columnTypes[colx]);
}
ancho = fm.bytesWidth(cadena.getBytes(), 0, cadena.length()) / 2;
g2.drawString(cadena, (xActual + 3) - ancho, yActual - 4);
}
yAnterior[k] = yActual;
}
if(bPrimeraVez)
bPrimeraVez = false;
xAnterior = xActual;
}
// BigDecimal bi = ObjectToBigDecimal(sorttmodel.getValueAt(0, colx));
}
}
}
public BigDecimal ObjectToBigDecimal(Object objeto)
{
BigDecimal bi = new BigDecimal(0,mathContext);
if(objeto != null)
{
if(objeto instanceof java.lang.Long)
bi = new BigDecimal((Long)objeto);
else if(objeto instanceof java.lang.Short)
bi = new BigDecimal((Short)objeto);
else if(objeto instanceof java.lang.Integer)
bi = new BigDecimal((Integer)objeto);
else if(objeto instanceof java.lang.Number)
bi = new BigDecimal(((Number)objeto).toString());
else if(objeto instanceof java.lang.Double)
bi = new BigDecimal((Double)objeto);
else if(objeto instanceof BigDecimal)
bi = (BigDecimal)objeto;
else if(objeto instanceof java.sql.Date)
bi = new BigDecimal(((java.sql.Date)objeto).getTime());
else if(objeto instanceof java.sql.Time)
bi = new BigDecimal(((java.sql.Time)objeto).getTime());
else if(objeto instanceof java.sql.Timestamp)
bi = new BigDecimal(((java.sql.Timestamp)objeto).getTime());
}
return bi;
}
private long ObjectTolong(Object valueAt)
{
long resultado = 0;
if(valueAt != null)
{
if(valueAt instanceof java.sql.Date)
resultado = ((java.sql.Date)valueAt).getTime();
else if(valueAt instanceof java.sql.Time)
resultado = ((java.sql.Time)valueAt).getTime();
else if(valueAt instanceof java.sql.Timestamp)
resultado = ((java.sql.Timestamp)valueAt).getTime();
}
return resultado;
}
public void setModel(JdbcTModel tmodel, int colx, int coly[], int tipo)
{
// tenemos que sacar la m�xima X e Y
Vector vtemp = null;
Object objeto = null;
BigDecimal bi = null;
biColXMax = new BigDecimal(0);
biColXMin = new BigDecimal(0);
biColYMax = new BigDecimal(0);
biColYMin = new BigDecimal(0);
tiColXMax = new java.sql.Timestamp(0);
tiColXMin = new java.sql.Timestamp(0);
tiColYMax = new java.sql.Timestamp(0);
tiColYMin = new java.sql.Timestamp(0);
numElementosX = tmodel.rows.size();
for(int i=0,limite = tmodel.rows.size(); i < limite;i++)
{
vtemp = (Vector)tmodel.rows.elementAt(i);
// vamos con colx
objeto = vtemp.elementAt(colx);
bi = ObjectToBigDecimal(objeto);
if(esFecha(tmodel.columnTypes[colx]) == false)
{
biColXMax = bi.max(biColXMax);
biColXMin = bi.min(biColXMin);
}
else
{
if(tiColXMax.compareTo(new Timestamp(bi.longValue())) < 0)
tiColXMax = new Timestamp(bi.longValue());
if(tiColXMin.compareTo(new Timestamp(bi.longValue())) > 0 || tiColXMin.getTime() == 0)
tiColXMin = new Timestamp(bi.longValue());
}
// vamos con coly
for(int j = 0; j < coly.length; j++)
{
objeto = vtemp.elementAt(coly[j]);
bi = ObjectToBigDecimal(objeto);
if(esFecha(tmodel.columnTypes[coly[0]]) == false)
{
biColYMax = bi.max(biColYMax);
biColYMin = bi.min(biColYMin);
}
else
{
if(tiColYMax.compareTo(new Timestamp(bi.longValue())) < 0)
tiColYMax = new Timestamp(bi.longValue());
if(tiColYMin.compareTo(new Timestamp(bi.longValue())) > 0 || tiColYMin.getTime() == 0)
tiColYMin = new Timestamp(bi.longValue());
}
}
}
this.tmodel = tmodel;
this.sorttmodel = new SortTModel(new JTable(),this.tmodel);
this.sorttmodel.sortByColumn(colx);
this.colx = colx;
this.coly = coly;
this.tipo = tipo;
repaint();
}
public void setDrawLines(boolean selected)
{
this.bDrawLines = selected;
repaint();
}
public void setDrawValues(boolean selected)
{
this.bDrawValues = selected;
repaint();
}
public void setDrawTitles(boolean selected)
{
this.bDrawTitles = selected;
repaint();
}
public void setDecimals(int decimales)
{
mathContext = new MathContext(decimales);
}
private boolean esFecha(Class clase)
{
boolean resultado = false;
if(clase == java.sql.Date.class || clase == java.sql.Time.class || clase == java.sql.Timestamp.class)
resultado = true;
return resultado;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
public static int CHART_2D = 0;
public static int CHART_3D = 1;
private int tipo = 0; // 0 2d, 1 3d
private JdbcTModel tmodel = null;
private SortTModel sorttmodel = null; // este lo utilizamos por que es necesario ordenar la colmnax
private int colx = 0;
private int coly[] = null;
private MathContext mathContext = new MathContext(2);
private BigDecimal biColXMax = new BigDecimal(0);
private BigDecimal biColXMin = new BigDecimal(0);
private BigDecimal biColYMax = new BigDecimal(0);
private BigDecimal biColYMin = new BigDecimal(0);
private java.sql.Timestamp tiColXMax = new java.sql.Timestamp(0);
private java.sql.Timestamp tiColXMin = new java.sql.Timestamp(0);
private java.sql.Timestamp tiColYMax = new java.sql.Timestamp(0);
private java.sql.Timestamp tiColYMin = new java.sql.Timestamp(0);
private int numElementosX = 0;
private boolean bDrawLines = false;
private boolean bDrawValues = false;
private boolean bDrawTitles = true;
private Color colores[] = { new Color(0,150,0), new Color(0,0,150), new Color(150,0,0), Color.ORANGE, Color.PINK, Color.CYAN ,
Color.YELLOW, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.RED, new Color(150,150,0),
new Color(0,150,150), new Color(150,150,150), new Color(200,50,100), new Color(100,50,200),
new Color(150,150,40), new Color(30,50,90), new Color(200,150,90), new Color(100,150,100),
new Color(0,150,0), new Color(0,0,150), new Color(150,0,0), Color.ORANGE, Color.PINK, Color.CYAN ,
Color.YELLOW, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.RED, new Color(150,150,0),
new Color(0,150,150), new Color(150,150,150), new Color(200,50,100), new Color(100,50,200),
new Color(150,150,40), new Color(30,50,90), new Color(200,150,90), new Color(100,150,100),
new Color(0,150,0), new Color(0,0,150), new Color(150,0,0), Color.ORANGE, Color.PINK, Color.CYAN ,
Color.YELLOW, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.RED, new Color(150,150,0),
new Color(0,150,150), new Color(150,150,150), new Color(200,50,100), new Color(100,50,200),
new Color(150,150,40), new Color(30,50,90), new Color(200,150,90), new Color(100,150,100),
new Color(0,150,0), new Color(0,0,150), new Color(150,0,0), Color.ORANGE, Color.PINK, Color.CYAN ,
Color.YELLOW, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.RED, new Color(150,150,0),
new Color(0,150,150), new Color(150,150,150), new Color(200,50,100), new Color(100,50,200),
new Color(150,150,40), new Color(30,50,90), new Color(200,150,90), new Color(100,150,100),
new Color(0,150,0), new Color(0,0,150), new Color(150,0,0), Color.ORANGE, Color.PINK, Color.CYAN ,
Color.YELLOW, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.RED, new Color(150,150,0),
new Color(0,150,150), new Color(150,150,150), new Color(200,50,100), new Color(100,50,200),
new Color(150,150,40), new Color(30,50,90), new Color(200,150,90), new Color(100,150,100)};
}