2010-08-11 7 views
1

Je voudrais créer un tracé polaire où les données sont tracées dans l'orientation mathématique (ainsi, la série commence et l'est et continue dans le sens inverse des aiguilles d'une montre). Le comportement par défaut de PolarPlot de JFreeChart est de commencer au nord et de continuer la série dans le sens des aiguilles d'une montre.JFreeChart PolarPlot: orientation mathématique

Y at-il un support pour cela intégré dans la classe PolarPlot? Je sais comment transformer les données pour atteindre l'objectif, mais cette approche est plutôt lourde, car j'aurais aussi besoin d'adapter l'étiquetage des angles.

Répondre

4

En aparté, org.jfree.chart.plot.PolarPlot semble avoir été designed pour navigational et geodetic applications.

utilisant la transformation θ »= π/4 - θ et refreshAngleTicks() primordial, comme suggested par @mort, produit des résultats raisonnables. Addenda: Voir aussi variation en utilisant la nouvelle API PolarPlot.

archimedes spiral

import java.awt.Color; 
import java.awt.Dimension; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.axis.NumberTick; 
import org.jfree.chart.axis.ValueAxis; 
import org.jfree.chart.plot.PolarPlot; 
import org.jfree.chart.renderer.DefaultPolarItemRenderer; 
import org.jfree.chart.renderer.PolarItemRenderer; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 
import org.jfree.ui.TextAnchor; 

/** 
* @see http://en.wikipedia.org/wiki/Polar_coordinate_system 
* @see https://stackoverflow.com/questions/3458824 
*/ 
public class ArchimedesSpiral extends JFrame { 

    private static final String title = "Archimedes' Spiral"; 

    public ArchimedesSpiral(String title) { 
     super(title); 
     JFreeChart chart = createChart(createDataset()); 
     ChartPanel panel = new ChartPanel(chart); 
     panel.setPreferredSize(new Dimension(500, 500)); 
     panel.setMouseZoomable(false); 
     this.add(panel); 
    } 

    private static XYDataset createDataset() { 
     XYSeriesCollection result = new XYSeriesCollection(); 
     XYSeries series = new XYSeries(title); 
     for (int t = 0; t <= 3 * 360; t++) { 
      series.add(90 - t, t); 
     } 
     result.addSeries(series); 
     return result; 
    } 

    private static JFreeChart createChart(XYDataset dataset) { 
     ValueAxis radiusAxis = new NumberAxis(); 
     radiusAxis.setTickLabelsVisible(false); 
     PolarItemRenderer renderer = new DefaultPolarItemRenderer(); 
     PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer) { 

      @Override 
      protected List refreshAngleTicks() { 
       List<NumberTick> ticks = new ArrayList<NumberTick>(); 
       int delta = (int) this.getAngleTickUnit().getSize(); 
       for (int t = 0; t < 360; t += delta) { 
        int tp = (360 + 90 - t) % 360; 
        NumberTick tick = new NumberTick(
         Double.valueOf(t), String.valueOf(tp), 
         TextAnchor.CENTER, TextAnchor.CENTER, 0.0); 
        ticks.add(tick); 
       } 
       return ticks; 
      } 
     }; 
     plot.setBackgroundPaint(new Color(0x00f0f0f0)); 
     plot.setRadiusGridlinePaint(Color.gray); 
     plot.addCornerTextItem("r(θ) = θ; 0 < θ < 6π"); 
     JFreeChart chart = new JFreeChart(
      title, JFreeChart.DEFAULT_TITLE_FONT, plot, true); 
     chart.setBackgroundPaint(Color.white); 
     return chart; 
    } 

    public static void main(String[] args) { 
     ArchimedesSpiral demo = new ArchimedesSpiral(title); 
     demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     demo.pack(); 
     demo.setLocationRelativeTo(null); 
     demo.setVisible(true); 
    } 
} 
2

Malheureusement, il ne semble pas y avoir de support intégré pour cela. Le marquage d'angle peut être adapté en remplaçant les méthodes refreshAngleTicks() de polarplot:

PolarPlot plot = new PolarPlot() { 

     @Override 
     protected List refreshAngleTicks() { 
      List ticks = new ArrayList(); 
      // produce some ticks, e.g. NumberTick instances 
      ticks.add(new NumberTick(0, "90", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(45, "45", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(90, "0", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(135, "315", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(180, "270", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(225, "225", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(270, "180", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      ticks.add(new NumberTick(315, "135", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0)); 
      return ticks; 
     } 
    }; 
+0

Quelle transformation? – trashgod

+0

Je voudrais avoir une intrigue polaire comme elle est utilisée en mathématiques ou en électronique ... les données doivent être tracées en commençant à l'est (à la partie droite de l'axe des x) et en continuant dans le sens inverse des aiguilles d'une montre. Voir http://en.wikipedia.org/wiki/Polar_coordinate_system pour des exemples de graphiques. – mort

+0

+1 pour 'refreshAngleTicks()'. Je voulais dire transformation comme dans θ '= π/4 - θ. – trashgod

3

La version actuelle de JFreeChart semble résoudre ce problème beaucoup plus facile: Il existe trois méthodes disponibles:

setCounterClockwise(true) // changes the direction of the ticks 
setAxisLocation(PolarAxisLocation.EAST_BELOW) // defines the placement of the axis 
setAngleOffset(0); 

Exemple complet adapté de here:

import java.awt.Color; 
import java.awt.Dimension; 
import javax.swing.JFrame; 
import org.jfree.chart.ChartPanel; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.axis.ValueAxis; 
import org.jfree.chart.plot.PolarAxisLocation; 
import org.jfree.chart.plot.PolarPlot; 
import org.jfree.chart.renderer.DefaultPolarItemRenderer; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 

/** 
* @see http://en.wikipedia.org/wiki/Polar_coordinate_system 
* @see https://stackoverflow.com/questions/3458824 
* @see https://stackoverflow.com/questions/6540390 
* @see https://stackoverflow.com/questions/6576911 
* @see https://stackoverflow.com/a/10227275/230513 
*/ 
public class ArchimedesSpiral extends JFrame { 

    private static final String title = "Archimedes' Spiral"; 

    public ArchimedesSpiral(String title) { 
     super(title); 
     JFreeChart chart = createChart(createDataset()); 
     ChartPanel panel = new ChartPanel(chart); 
     panel.setPreferredSize(new Dimension(500, 500)); 
     panel.setMouseZoomable(false); 
     this.add(panel); 
    } 

    private static XYDataset createDataset() { 
     XYSeriesCollection result = new XYSeriesCollection(); 
     XYSeries series = new XYSeries(title); 
     for (int t = 0; t <= 3 * 360; t++) { 
      series.add(t, t); 
     } 
     result.addSeries(series); 
     return result; 
    } 

    private static JFreeChart createChart(XYDataset dataset) { 
     ValueAxis radiusAxis = new NumberAxis(); 
     radiusAxis.setTickLabelsVisible(false); 
     DefaultPolarItemRenderer renderer = new DefaultPolarItemRenderer(); 
     renderer.setShapesVisible(false); 
     PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer); 
     plot.setCounterClockwise(true); 
     plot.setAxisLocation(PolarAxisLocation.EAST_BELOW); 
     plot.setAngleOffset(0); 
     plot.setBackgroundPaint(new Color(0x00f0f0f0)); 
     plot.setRadiusGridlinePaint(Color.gray); 
     plot.addCornerTextItem("r(θ) = θ; 0 < θ < 6π"); 
     JFreeChart chart = new JFreeChart(
      title, JFreeChart.DEFAULT_TITLE_FONT, plot, true); 
     chart.setBackgroundPaint(Color.white); 
     return chart; 
    } 

    public static void main(String[] args) { 
     ArchimedesSpiral demo = new ArchimedesSpiral(title); 
     demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     demo.pack(); 
     demo.setLocationRelativeTo(null); 
     demo.setVisible(true); 
    } 
} 
+0

Merci pour la mise à jour! – mort

+0

+1 pour l'utilisation de la nouvelle API; mort: n'hésitez pas à accepter cette réponse. – trashgod