package org.signalml.app.method.ep; import static org.signalml.app.util.i18n.SvarogI18n._; import java.awt.Color; import java.awt.Font; import java.util.List; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.LegendItemCollection; import org.jfree.chart.LegendItemSource; import org.jfree.chart.axis.AxisLocation; import org.jfree.chart.axis.AxisSpace; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.chart.title.TextTitle; import org.jfree.data.xy.DefaultXYDataset; import org.jfree.ui.HorizontalAlignment; import org.jfree.ui.RectangleEdge; import org.jfree.ui.RectangleInsets; import org.jfree.ui.VerticalAlignment; import org.signalml.app.method.ep.EvokedPotentialGraphPanel.ChartType; import org.signalml.app.method.ep.view.tags.TagStyleGroup; import org.signalml.app.view.common.components.panels.AbstractPanel; import org.signalml.domain.tag.StyledTagSet; import org.signalml.method.ep.EvokedPotentialResult; import org.signalml.plugin.export.signal.TagStyle; public class EvokedPotentialChart extends AbstractPanel { public static final int CHART_HEIGHT = 100; public static final int PREFERRED_CHART_WIDTH = 570; public static final int AXIS_SPACE = 35; public static final int LEGEND_SPACE = 20; private XYLineAndShapeRenderer normalRenderer; private ChartPanel chartPanel; private JFreeChart chart; private Font titleFont = new Font(Font.DIALOG, Font.PLAIN, 10); public EvokedPotentialChart(double[] timeValues, List<double[]> data, double minY, double maxY, String label, ChartType type, EvokedPotentialResult result) { super(); normalRenderer = new XYLineAndShapeRenderer(true, false); normalRenderer.setSeriesPaint(0, Color.BLUE); normalRenderer.setSeriesPaint(1, Color.RED); chart = createChart(timeValues, data, minY, maxY, label, type, result); int height = CHART_HEIGHT; int width = PREFERRED_CHART_WIDTH; if (type != ChartType.STRIPPED) height += AXIS_SPACE; if (type == ChartType.TOP) height += LEGEND_SPACE; chartPanel = new ChartPanel(chart, width, height, 0, 0, 1000, 1000, false, false, false, false, false, false); chartPanel.setDomainZoomable(false); chartPanel.setRangeZoomable(false); chartPanel.setMouseZoomable(false); chartPanel.setPopupMenu(null); add(chartPanel); } private JFreeChart createChart(double[] timeValues, List<double[]> data, double minY, double maxY, String label, ChartType type, EvokedPotentialResult result) { double minTime = timeValues[0]; double maxTime = timeValues[timeValues.length-1]; NumberAxis xAxis; NumberAxis yAxis; DefaultXYDataset dataset; XYPlot plot; double yTickUnit; TextTitle title; AxisSpace axisSpace; JFreeChart chart; xAxis = new NumberAxis(); xAxis.setAutoRange(false); xAxis.setRange(minTime, maxTime); yAxis = new NumberAxis(); yAxis.setAutoRange(false); // configure for nine labels, but round to 10 yTickUnit = Math.round((maxY-minY)/(8*10)) * 10.0; yAxis.setTickUnit(new NumberTickUnit(yTickUnit)); yAxis.setRange(minY, maxY); dataset = new DefaultXYDataset(); for (int i = 0; i < data.size(); i++) { TagStyleGroup tagStyleGroup = result.getData().getParameters().getAveragedTagStyles().get(i); dataset.addSeries(tagStyleGroup.toString(), new double[][] { timeValues, data.get(i) } ); } dataset.addSeries("", new double[][] { {0,0}, {minY, maxY} }); plot = new XYPlot(dataset, xAxis, yAxis, normalRenderer); title = new TextTitle(label, titleFont, Color.BLACK, RectangleEdge.LEFT, HorizontalAlignment.LEFT, VerticalAlignment.CENTER, new RectangleInsets(0,0,0,0)); setColorsForSeries(result, plot); switch (type) { case BOTTOM : xAxis.setLabel(_("Time [s]")); xAxis.setLabelFont(titleFont.deriveFont(8)); axisSpace = new AxisSpace(); axisSpace.setBottom(AXIS_SPACE); plot.setFixedDomainAxisSpace(axisSpace); title.setPadding(new RectangleInsets(0,0,AXIS_SPACE,0)); break; case TOP : xAxis.setLabel(_("Time [s]")); xAxis.setLabelFont(titleFont.deriveFont(8)); plot.setDomainAxisLocation(AxisLocation.TOP_OR_LEFT); axisSpace = new AxisSpace(); axisSpace.setTop(AXIS_SPACE); plot.setFixedDomainAxisSpace(axisSpace); title.setPadding(new RectangleInsets(AXIS_SPACE,0,0,0)); break; case STRIPPED : xAxis.setVisible(false); break; case NORMAL : default : xAxis.setLabel(_("Time [s]")); title.setPosition(RectangleEdge.TOP); title.setHorizontalAlignment(HorizontalAlignment.CENTER); title.setVerticalAlignment(VerticalAlignment.TOP); break; } boolean showLegend = type == ChartType.TOP; chart = new JFreeChart(null, null, plot, showLegend); chart.setTitle(title); chart.setBorderVisible(false); chart.setBackgroundPaint(Color.WHITE); chart.setPadding(new RectangleInsets(0,0,0,6)); if (chart.getLegend() != null) { int itemToRemove = chart.getPlot().getLegendItems().getItemCount() - 1; removeItemFromLegend(itemToRemove, chart); chart.getLegend().setPosition(RectangleEdge.TOP); chart.getLegend().setBorder(1, 1, 1, 1); } return chart; } protected void removeItemFromLegend(int itemToRemove, JFreeChart chart) { LegendItemCollection legendItems = chart.getPlot().getLegendItems(); final LegendItemCollection newLegendItems = new LegendItemCollection(); for (int i = 0; i < legendItems.getItemCount(); i++) { if (itemToRemove != i) newLegendItems.add(legendItems.get(i)); } LegendItemSource source = new LegendItemSource() { @Override public LegendItemCollection getLegendItems() { return newLegendItems; } }; chart.removeLegend(); chart.addLegend(new LegendTitle(source)); } protected static void setColorsForSeries(EvokedPotentialResult result, XYPlot plot) { List<TagStyleGroup> averagedTagStyles = result.getData().getParameters().getAveragedTagStyles(); StyledTagSet styledTagSet = result.getData().getStyledTagSet(); XYItemRenderer renderer = plot.getRenderer(); for (int i = 0; i < averagedTagStyles.size(); i++) { TagStyleGroup tagStyleGroup = averagedTagStyles.get(i); //mix colors int r = 0, g = 0, b = 0; for (int j = 0; j < tagStyleGroup.getNumberOfTagStyles(); j++) { TagStyle style = styledTagSet.getStyle(null, tagStyleGroup.getTagStyleNames().get(j)); Color color = style.getFillColor(); r += color.getRed(); g += color.getGreen(); b += color.getBlue(); } r /= tagStyleGroup.getNumberOfTagStyles(); g /= tagStyleGroup.getNumberOfTagStyles(); b /= tagStyleGroup.getNumberOfTagStyles(); Color mixedColor = new Color(r, g, b); renderer.setSeriesPaint(i, mixedColor); } } }