one line hides the rest in a 3D line chart

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
itai.marko
Posts: 10
Joined: Mon Jun 22, 2009 2:42 pm

one line hides the rest in a 3D line chart

Post by itai.marko » Tue Aug 11, 2009 2:03 pm

Hi,

I have a 3D line chart created with ChartFactory.createLineChart3D() and sometimes two or more lines might overlap.
The result will be that only the last line drawn will be visible like in the image below:

Image

What I would like is to take advantage of the 3D effect and have each series' line drawn in different 'depth'.
For instance in the example above, there are two series so the depth of the plot will be divided into two halvs. One next to the back wall and one 'in front' of it, 'closer' to the viewer. Each series' line will be drawn in a different half. This way, the overlapping part in the image above will be halved horizontally. One half will be red and the other blue.

Is there a way to do this currently? (I'm using version 1.0.13)
If not, is there a chance to have this feature in the next version?
If not, If I want to implement it myself, which part of the code do I need to override?

Thanks in advance
Itai

itai.marko
Posts: 10
Joined: Mon Jun 22, 2009 2:42 pm

Re: one line hides the rest in a 3D line chart

Post by itai.marko » Tue Aug 18, 2009 10:49 am

Ok I implemented it myself. Here's what I ment:
Image

and here's how I did it:
  • In LineRenderer3D.drawitem() the current data point calculation should be changed from:

    Code: Select all

            
                        // current data point...
                        double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), adjusted, plot.getDomainAxisEdge());
                        double value = v.doubleValue();
                        double y1 = rangeAxis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
    
    to:

    Code: Select all

            
                        // current data point...
                        int seriesCount = getRowCount();
                        double x1 = domainAxis.getCategoryMiddle(column, getColumnCount(), adjusted, plot.getDomainAxisEdge());
                        x1 += row * getXOffset()/seriesCount;
                        double value = v.doubleValue();
                        double y1 = rangeAxis.valueToJava2D(value, adjusted, plot.getRangeAxisEdge());
                        y1 -= row * getYOffset()/seriesCount;
    
  • The previous data point calculation should be changed from:

    Code: Select all

                        // previous data point...
                        double previous = previousValue.doubleValue();
                        double x0 = domainAxis.getCategoryMiddle(column - 1, getColumnCount(), adjusted,
                                                                 plot.getDomainAxisEdge());
                        double y0 = rangeAxis.valueToJava2D(previous, adjusted, plot.getRangeAxisEdge());
    
    to:

    Code: Select all

                        
                        // previous data point...
                        double previous = previousValue.doubleValue();
                        double x0 = domainAxis.getCategoryMiddle(column - 1, getColumnCount(), adjusted, 
                                                                 plot.getDomainAxisEdge());
                        x0 += row * getXOffset()/seriesCount;
                        double y0 = rangeAxis.valueToJava2D(previous, adjusted, plot.getRangeAxisEdge());
                        y0 -= row * getYOffset()/seriesCount;
    
  • The calculation of (x2,y2) and (x3,y3) should be changed from:

    Code: Select all

                        
                        double x2 = x0 + getXOffset();
                        double y2 = y0 - getYOffset();
                        double x3 = x1 + getXOffset();
                        double y3 = y1 - getYOffset();
    
    to:

    Code: Select all

                        
                        double x2 = x0 + getXOffset()/seriesCount;
                        double y2 = y0 - getYOffset()/seriesCount;
                        double x3 = x1 + getXOffset()/seriesCount;
                        double y3 = y1 - getYOffset()/seriesCount;
    
  • Don't forget to set the plot's row rendering order to descending (so the front line won't be drawn behind the back one..):

    Code: Select all

    plot.setRowRenderingOrder(SortOrder.DESCENDING);
  • I also recommend to set the chart's 'depth' to fit the amount of series that you have. You can do something like:

    Code: Select all

        	
           renderer.setXOffset(LineRenderer3D.DEFAULT_X_OFFSET * dataset.getRowCount());
        	renderer.setYOffset(LineRenderer3D.DEFAULT_Y_OFFSET * dataset.getRowCount());
    
I hope this feature can find its way to be included in the next version
Itai

Locked