JFreeChart 选择一个区域而不缩放 [英] JFreeChart select an area without zooming

查看:23
本文介绍了JFreeChart 选择一个区域而不缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I recently started using JFreeChart and there is something i would like to do but i'm not sure if it's possible. My program is supposed to draw a spectrogram (a sound graph) from a wav file. So i managed to get the data from my wav file in a double arraylist and to display it in a chart. But now i would like to be able to select an area of my spectrogram (with the same tool used for zooming) without zooming and to be able to play only the selected part on my sound. But i simply can't find any way to succeed. Here is my code of my chart:

    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 类并使用它:

And here i'm calling the Chart class and using it:

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.你能知道如何解决我的问题吗?非常感谢(对不起,如果我的英语并不总是准确的:/)

vue.getChartPanelUn() returns a ChartPanel. Would you have an idée how to solve my problem? Thanks a lot (And sorry if my english is not always exact :/)

推荐答案

不要通过缩放来做到这一点,使用添加到 ChartPanelMouseListener 来添加 MarkerDomain 轴.

Don't do this by zooming, use a MouseListener added to your ChartPanel to add a Marker to the Domain axis.

在这个例子中,我对 MouseAdapter 进行了子类化,这样当你按下鼠标时,域值被捕获(markerStart),当你松开鼠标时,鼠标结束位置被更新('markerEnd') 并将一个标记添加到绘图中 (updateMarker)

In this example I have subclassed MouseAdapter so that when you press the mouse down the domain value is captured (markerStart) and when you release the mouse end postition is updated ('markerEnd') and a Marker is added to the plot (updateMarker)

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

You will then get a chart like this:

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

Note that in this example I've actually turned off the zooming.

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);
    }

}

这篇关于JFreeChart 选择一个区域而不缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆