2013-04-19 9 views
7

Niedawno zacząłem używać JFreeChart i jest coś, co chciałbym robić, ale nie jestem pewien, czy to możliwe. Mój program powinien narysować spektrogram (wykres dźwiękowy) z pliku WAV. Więc udało mi się pobrać dane z mojego pliku wav na podwójną listę i wyświetlić na wykresie. Ale teraz chciałbym móc wybrać obszar mojego spektrogramu (z tym samym narzędziem do powiększania) bez powiększania i być w stanie odtwarzać tylko wybraną część na moim dźwięku. Ale po prostu nie mogę znaleźć żadnego sposobu na odniesienie sukcesu. Oto mój kod mojego wykresu:JFreeChart wybierz obszar bez powiększania

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

A ja dzwonię klasę Chart i używając go:

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() zwraca ChartPanel. Czy masz pomysł, jak rozwiązać mój problem? Thanks a lot (i przepraszam, jeśli mój angielski nie jest zawsze dokładna: /)

Odpowiedz

12

nie rób tego przez powiększenie, używać MouseListener dodany do ChartPanel dodać Marker do osi Domain.

W tym przykładzie podzieliłem tak, że po naciśnięciu myszy wartość domeny zostanie przechwycona (markerStart), a po zwolnieniu myszy pozycja końcowa zostanie zaktualizowana ("markerEnd"), a znacznik zostanie dodany do wykresu (updateMarker)

będziesz wtedy dostać wykres tak:

Chart with Domain Marker

Należy zauważyć, że w tym przykładzie mam faktycznie wyłączył powiększanie.

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

} 
+0

Dzięki za szybki anwser! Spróbuję tego w tym tygodniu, żeby sprawdzić, czy działa z moim kodem – user2299206