2010-08-11 167 views
1

我想創建一個極座標圖,其中數據以數學方向繪製(因此,該系列開始,而東部並繼續逆時針)。 JFreeChart's PolarPlot的默認行爲是從北開始並順時針繼續該系列。JFreeChart極座標極座標:數學方向

PolarPlot類中是否有任何支持?我知道如何轉換數據以達到目標,但這種方法相當麻煩,因爲我需要修改角度標籤。

回答

4

順便說一句,org.jfree.chart.plot.PolarPlot似乎已經designednavigationalgeodetic應用程序。

使用變換θ」 =π/ 4 - θ和壓倒一切refreshAngleTicks(),如通過suggested @mort,產生合理的結果。

附錄:另請參閱此variation使用新的PolarPlot API。

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

不幸的是,似乎沒有內置的支持。角標記可以通過重寫refreshAngleTicks()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

什麼改造? – trashgod 2010-08-12 12:16:40

+0

我想在數學或電子學中使用極座標圖...數據應從東(從x軸的右側)開始繪製,然後按逆時針方向繼續繪製。請參閱http://en.wikipedia.org/wiki/Polar_coordinate_system圖例。用於'refreshAngleTicks()'的 – mort 2010-08-12 12:31:22

+0

+1。我的意思是轉換爲θ'=π/ 4 - θ。 – trashgod 2010-08-12 17:15:08

3

JFreeChart目前的版本似乎解決了這個問題容易得多: 有三種方法:改編自here

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

完整的示例:

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

感謝您的更新! – mort 2012-04-19 14:49:23

+0

+1使用新的API;莫:毫不猶豫地接受這個答案。 – trashgod 2012-12-05 22:39:36