Unable to keep the JFreeChart Zoom system

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
MrJack
Posts: 13
Joined: Thu May 18, 2017 3:41 pm
antibot: No, of course not.

Unable to keep the JFreeChart Zoom system

Post by MrJack » Fri May 19, 2017 10:04 am

EDIT 1 : I'm overriding the XYBlockRenderer to improve his performance by using a picture instead of the basic system

Hello !

So I've manage to render a BufferedImage instead of render dot by dot BUT the zoom wheel and the rectangle zoom don't work properly :

The domain and range axis zoom and unzoom properly but on the chart itself nothing happened. I'm sure it's because of the way I draw the BufferedImage but I don't know how to correlate the range and domain axis to the BufferedImage ...

Here what I've done for now :

Code: Select all

public void drawImage(Graphics2D g2, XYItemRendererState state,PlotRenderingInfo info, JFCXYPlot plot, ValueAxis domainAxis, ValueAxis rangeAxis,XYDataset dataset, int series, CrosshairState crosshairState) {
        //initialization of private variable
        pPlot= plot;
        graphic2 = g2;
        double zVal;
        //this is a PaintScale that I've made
        CustomPaintScale tmp_paintScale = (CustomPaintScale)getPaintScale();
        XYZDataset tmp_dataset = (XYZDataset) dataset;
        m_img2D = new BufferedImage(pPlot.getImgWidth(),pPlot.getImgHeight(), BufferedImage.TYPE_INT_ARGB);
        for(int i = 0; i < pPlot.getImgWidth(); i++) {
            for(int j = 0; j < pPlot.getImgHeight(); j++) {
                zVal = tmp_dataset.getZValue(series, (i * pPlot.getImgHeight() + j));
                m_img2D.setRGB(i, j, tmp_paintScale.getColor(zVal).getRGB());
            }
        }
        graphic2.translate(pPlot.getDataArea().getWidth()/2,pPlot.getDataArea().getHeight()/2);
        graphic2.translate(-((pPlot.getImgWidth()*zoom)/2),-((pPlot.getImgHeight()*zoom)/2));
        graphic2.translate(x, y);
        graphic2.scale(zoom, zoom);
        graphic2.drawImage(m_img2D,0,0, null);
    }
The main issue is that I work with screen coordinate instead of the plot coordinate, but not only : I've to draw the picture at a certain point but the Zoom that I've build work by translate (X,Y) of my BufferedImage so because of that the domain and range axis isn't synchronized.

If more info are needed I will post more code :)

Thanks a lot !

MrJack

EDIT :
Changed the name of the topic which was maybe not accurate enough

MrJack
Posts: 13
Joined: Thu May 18, 2017 3:41 pm
antibot: No, of course not.

Re: Unable to keep the JFreeChart Zoom system

Post by MrJack » Tue May 30, 2017 4:27 pm

So after many try I've manage to fix the generation of the BufferedImage by doing this :

Code: Select all

public void drawImage(Graphics2D g2, XYItemRendererState state,
            PlotRenderingInfo info, JFCXYPlot plot, ValueAxis domainAxis,
            ValueAxis rangeAxis,XYDataset dataset, int series,
            CrosshairState crosshairState) {
        pPlot= plot;
        graphic2 = g2;
        double zVal;
        
        CustomPaintScale tmp_paintScale = (CustomPaintScale)getPaintScale();
        XYZDataset tmp_dataset = (XYZDataset) dataset;
        m_img2D = new BufferedImage(pPlot.getImgWidth(),pPlot.getImgHeight(), BufferedImage.TYPE_INT_ARGB);
        int[] mid = {(plot.getImgWidth())/2,(plot.getImgHeight())/2};
        
        for(int xImg = 0; xImg < m_img2D.getWidth(); xImg++) {
            for(int yImg = 0; yImg < m_img2D.getHeight(); yImg++) {
                zVal = tmp_dataset.getZValue(series, (xImg * pPlot.getImgHeight()) + yImg);
                m_img2D.setRGB(xImg, yImg, ((Color)tmp_paintScale.getPaint(zVal)).getRGB());
            }
        }
        // I was try to see if their was any difference between pPlot.getDataArea and info.getPlotArea()
        graphic2.translate(info.getPlotArea().getX(),info.getPlotArea().getX());
        graphic2.scale(zoomW, zoomH);
        graphic2.drawImage(m_img2D,x,y, null);
The auto scale :

Code: Select all

public void autoScaleZoom(){
        x = 0;
        y = 0;
        zoomH = (pPlot.getDataArea().getHeight())/((double)m_img2D.getHeight() + pPlot.getDataArea().getY());
        zoomW = (pPlot.getDataArea().getWidth())/((double)m_img2D.getWidth() + pPlot.getDataArea().getX());
        graphic2.scale(zoomW, zoomH);
    }
The mouse wheel zoom:

Code: Select all

    public void mouseWheelZoom(int notches, double mx, double my){
        if((mx<= pPlot.getDataArea().getWidth() ||mx >= 0 )
                &&(my<= pPlot.getDataArea().getHeight() ||my >= 0 )){
            double newxpan,newypan;

            double wwidth  = (pPlot.getDataArea().getWidth()- pPlot.getDataArea().getX()) /2.0; 
            double wheight = (pPlot.getDataArea().getHeight()- pPlot.getDataArea().getY())/2.0; 

            double zfactor;

            if (notches < 0) { // Mouse wheel moved UP            
                zfactor = 1.05;
            }else{   
                zfactor = 0.95;
            }

            zoomH*=zfactor;
            zoomW*=zfactor;
            newxpan = mx - wwidth  - zfactor*(mx-wwidth-getX());
            newypan = my - wheight - zfactor*(my-wheight-getY());
            x = (int)newxpan;
            y = (int)newypan;
            // Utility: 20.8 -> 21 instead of 20
            if(getX() < (newxpan-(0.5))){
                x++;
            }
            if(getY() < (newypan-(0.5))){
                y++;
            }
        }
    }
Now I'm trying to have a rectangle zoom :

Code: Select all

    //Doesn't work properly I will update it when I've someting better
    //UPDATE 0 : divide both x and y by the zoom is the wrong way, now it's work more properly than before but I still have some minor issue
    public void mouseDragZoom(Rectangle2D newDataArea){
        
        double rx =newDataArea.getX();
        double ry =newDataArea.getY();
        double newxpan,newypan;
        newxpan = x-rx/zoomW;
        newypan = y-ry/zoomH;
        x = (int)newxpan;
        y = (int)newypan;
        
        if(x < (newxpan-(0.5))){
            x++;
        }
        if(y < (newypan-(0.5))){
            y++;
        }
        zoomH *= (pPlot.getDataArea().getHeight())/(newDataArea.getHeight());
        zoomW *= (pPlot.getDataArea().getWidth())/(newDataArea.getWidth());
        graphic2.scale(zoomW, zoomH);
    }

Locked