package pl.edu.fuw.fid.signalanalysis.waveform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import org.apache.commons.math.complex.Complex;
import org.signalml.math.fft.WindowType;
import pl.edu.fuw.fid.signalanalysis.SingleSignal;
/**
* Chart for the signal displayed in interactive time-frequency map window.
* Allows to overlay waveform over the signal, in distinctive colour.
*
* @author ptr@mimuw.edu.pl
*/
public class SignalChart extends LineChart<Number, Number> {
private static final String SIGNAL_STYLE = "-fx-stroke-width: 1; -fx-stroke: #000000;";
private static final String WAVEFORM_STYLE = "-fx-stroke-width: 2; -fx-stroke: #FF0000;";
private final double[] data;
private final double samplingFrequency;
private final ObservableList<XYChart.Series<Number,Number>> series;
public SignalChart(SingleSignal signal, double tMin, double tMax, NumberAxis xAxis, NumberAxis yAxis) {
super(xAxis, yAxis);
int nMin = (int) Math.round(tMin * signal.getSamplingFrequency());
int nMax = (int) Math.round(tMax * signal.getSamplingFrequency());
this.data = new double[nMax - nMin];
this.samplingFrequency = signal.getSamplingFrequency();
signal.getSamples(nMin, nMax-nMin, data);
ObservableList<XYChart.Data<Number,Number>> signalData = FXCollections.observableArrayList();
for (int i=0; i<data.length; ++i) {
double t = tMin + (tMax - tMin) * i / data.length;
signalData.add(new XYChart.Data<Number,Number>(t, data[i]));
}
ObservableList<XYChart.Data<Number,Number>> waveformData = FXCollections.emptyObservableList();
this.series = FXCollections.observableArrayList(
createDataSeries(signalData, SIGNAL_STYLE),
new XYChart.Series<Number, Number>(waveformData)
);
setAnimated(false);
setCreateSymbols(false);
setLegendVisible(false);
setPrefHeight(100);
setData(series);
}
private static XYChart.Series<Number, Number> createDataSeries(ObservableList<XYChart.Data<Number,Number>> data, final String style) {
XYChart.Series<Number, Number> serie = new XYChart.Series<Number, Number>(data);
serie.nodeProperty().addListener(new ChangeListener<Node>() {
@Override
public void changed(ObservableValue<? extends Node> observable, Node oldValue, Node newValue) {
if (newValue != null) {
newValue.setStyle(style);
}
}
});
return serie;
}
public void setWaveform(Waveform wf, WindowType windowType, double t0, Complex coeff) {
ObservableList<XYChart.Data<Number,Number>> waveformData = WaveformRenderer.compute(wf, t0, windowType, coeff, samplingFrequency);
series.set(1, createDataSeries(waveformData, WAVEFORM_STYLE));
}
public void clearWaveform() {
ObservableList<XYChart.Data<Number,Number>> waveformData = FXCollections.emptyObservableList();
series.set(1, new XYChart.Series<Number, Number>(waveformData));
}
}