【问题标题】:JFreeChart select an area without zoomingJFreeChart 选择一个区域而不缩放
【发布时间】:2013-04-12 21:15:21
【问题描述】:

我最近开始使用 JFreeChart,有一些我想做的事情,但我不确定它是否可能。 我的程序应该从 wav 文件中绘制频谱图(声音图)。所以我设法从双数组列表中的 wav 文件中获取数据并将其显示在图表中。但是现在我希望能够在不缩放的情况下选择我的频谱图的一个区域(使用用于缩放的相同工具)并且能够只播放我的声音中的选定部分。但我根本找不到任何成功的方法。 这是我的图表代码:

    package classes;

import java.awt.Color;
import java.awt.Paint;
import java.awt.Rectangle;
import java.io.File;
import java.io.IOException;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleInsets;

public class Chart{
    JFreeChart chart;
    Plot plot;

    //Constructeur de la classe Chart
    public Chart(double[][] bs, int channel, int framesLength, float frameRate)
    {
        // Création d'un XY chart
        XYSeries series = new XYSeries("XYGraph");
        int i=0,j=0;
        float k=0;
        //Ajout de tous les points du tableau de 16 bytes dans le chart
        for( i=0; i <channel;i++)
        {
            for(j=0; j< framesLength;j++)
            {
                //Division des valeurs par 2^15 pour être entre 1 et -1
                series.add(k, (bs[i][j]/32768));
                //Echelle de X
                k+=(1/frameRate);
            }
        }
        // Ajoute la série au dataset
        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);
        // Génération du graphe
        chart = ChartFactory.createXYLineChart(
        "Ajouter titre à la fonction de génération", // Titre
        "Temps (s)", // Nom de l'axe X
        "y-axis", // Nom de l'axe Y
        dataset, // Dataset
        PlotOrientation.VERTICAL, // Plot Orientation
        true, // Show Legend
        false, // Use tooltips
        false // Configure chart to generate URLs?
        );
        plot= (XYPlot) chart.getPlot();

    }
    //Renvoie le chart
    public JFreeChart getChart()
    {
        return chart;
    }

    public void color(Color c)
    {
        plot.setBackgroundPaint(c);
    }
}

我在这里调用 Chart 类并使用它:

Chart chartUn= new Chart(bs, channels  , frameLength , frameRate);
        chartUn.color(Color.pink);
        vue.setChartPanelUn(new ChartPanel(chartUn.getChart(), false));
        vue.getChartPanelUn().setRangeZoomable(false);
        vue.getChartPanelUn().setMouseWheelEnabled(true);

vue.getChartPanelUn() 返回一个 ChartPanel。 你知道如何解决我的问题吗? 非常感谢 (对不起,如果我的英语并不总是准确的:/)

【问题讨论】:

    标签: java zooming jfreechart area chartpanel


    【解决方案1】:

    不要通过缩放来执行此操作,请使用添加到 ChartPanelMouseListenerMarker 添加到 Domain 轴。

    在此示例中,我将MouseAdapter 子类化,这样当您按下鼠标时,域值会被捕获(markerStart),当您释放鼠标时,结束位置会更新('markerEnd')并添加一个标记到剧情(updateMarker)

    然后你会得到一个这样的图表:

    请注意,在此示例中,我实际上已关闭缩放功能。

    import java.awt.Color;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Point2D;
    import java.awt.geom.Rectangle2D;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.plot.IntervalMarker;
    import org.jfree.chart.plot.Marker;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    import org.jfree.ui.Layer;
    
    
    public class MouseMarkerDemo extends JFrame {
    
    
        public MouseMarkerDemo(String title) {
            super(title);
            JPanel chartPanel = createDemoPanel();
            chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
            setContentPane(chartPanel);
        }
    
    
        private final static class  MouseMarker extends MouseAdapter{
            private Marker marker;
            private Double markerStart = Double.NaN;
            private Double markerEnd = Double.NaN;
            private final XYPlot plot;
            private final JFreeChart chart;
            private  final ChartPanel panel;
    
    
            public MouseMarker(ChartPanel panel) {
                this.panel = panel;
                this.chart = panel.getChart();
                this.plot = (XYPlot) chart.getPlot();
            }
    
            private void updateMarker(){
                if (marker != null){
                    plot.removeDomainMarker(marker,Layer.BACKGROUND);
                }
                if (!( markerStart.isNaN() && markerEnd.isNaN())){
                    if ( markerEnd > markerStart){
                        marker = new IntervalMarker(markerStart, markerEnd);
                        marker.setPaint(new Color(0xDD, 0xFF, 0xDD, 0x80));
                        marker.setAlpha(0.5f);
                        plot.addDomainMarker(marker,Layer.BACKGROUND);
                    }
                }
            }
    
            private Double getPosition(MouseEvent e){
                Point2D p = panel.translateScreenToJava2D( e.getPoint());
                Rectangle2D plotArea = panel.getScreenDataArea();
                XYPlot plot = (XYPlot) chart.getPlot();
                return plot.getDomainAxis().java2DToValue(p.getX(), plotArea, plot.getDomainAxisEdge());
            }
    
            @Override
            public void mouseReleased(MouseEvent e) {
                markerEnd = getPosition(e);
                updateMarker();
            }
    
            @Override
            public void mousePressed(MouseEvent e) {
                markerStart = getPosition(e);
            }
        }
    
        private static XYDataset createDataset() {
    
            XYSeries series1 = new XYSeries("Data");
            series1.add(1.0, 1.0);
            series1.add(2.0, 4.0);
            series1.add(3.0, 3.0);
            series1.add(4.0, 5.0);
            series1.add(5.0, 5.0);
            series1.add(6.0, 7.0);
            series1.add(7.0, 7.0);
            series1.add(8.0, 8.0);
    
            XYSeriesCollection dataset = new XYSeriesCollection();
            dataset.addSeries(series1);
            return dataset;
    
        }
    
    
        private static JFreeChart createChart(XYDataset dataset) {
    
            JFreeChart chart = ChartFactory.createXYLineChart(
                "Mouse Marker",
                "X",
                "Y",
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false
            );
            XYPlot plot = (XYPlot) chart.getPlot();
            plot.setDomainPannable(true);
            plot.setRangePannable(true);
            XYLineAndShapeRenderer renderer
                    = (XYLineAndShapeRenderer) plot.getRenderer();
            renderer.setBaseShapesVisible(true);
            renderer.setBaseShapesFilled(true);
            return chart;
        }
    
        public static JPanel createDemoPanel() {
            final JFreeChart chart = createChart(createDataset());
            final ChartPanel panel = new ChartPanel(chart);
            panel.setRangeZoomable(false);
            panel.setDomainZoomable(false);
            panel.addMouseListener(new MouseMarker(panel));
            return panel;
        }
    
        public static void main(String[] args) {
            MouseMarkerDemo demo = new MouseMarkerDemo("JFreeChart: MouseMarkerDemo.java");
            demo.pack();
            demo.setVisible(true);
        }
    
    }
    

    【讨论】:

    • 感谢您的快速答复!我将在这个周末尝试一下,看看它是否适用于我的代码
    • 谢谢你,格雷厄姆,我从你的例子中摘录,第一次工作。
    猜你喜欢
    • 2015-12-21
    • 2017-10-24
    • 2020-04-29
    • 2018-02-19
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2017-06-19
    • 1970-01-01
    相关资源
    最近更新 更多