com.loadcoder.load.chart.jfreechart.ChartFrame Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of loadcoder-chart Show documentation
Show all versions of loadcoder-chart Show documentation
This project contains the chart feature of Loadcoder
/*******************************************************************************
* Copyright (C) 2018 Stefan Vahlgren at Loadcoder
*
* This file is part of Loadcoder.
*
* Loadcoder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Loadcoder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
******************************************************************************/
package com.loadcoder.load.chart.jfreechart;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartTheme;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.LegendItem;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.LegendItemEntity;
import org.jfree.chart.entity.PlotEntity;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.urls.StandardXYURLGenerator;
import org.jfree.chart.util.ParamChecks;
import org.jfree.data.xy.XYDataItem;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.loadcoder.load.LoadUtility;
import com.loadcoder.load.chart.data.DataSet;
import com.loadcoder.load.chart.logic.Chart;
import com.loadcoder.load.chart.menu.AboutPopup;
import com.loadcoder.load.jfreechartfixes.XYLineAndShapeRendererExtention;
public class ChartFrame extends ApplicationFrame {
private static final long serialVersionUID = 1L;
public static Logger log = LoggerFactory.getLogger(ChartFrame.class);
JFrame chartFrame = this;
private JMenuBar menuBar;
/** The chart theme. */
private static ChartTheme currentTheme = new StandardChartTheme("JFree");
JFreeChart chart;
ChartPanel chartPanel;
XYPlotExtension plot;
XYLineAndShapeRendererExtention renderer;
Map seriesVisible = new HashMap();
XYSeriesCollectionExtention seriesCollection = new XYSeriesCollectionExtention();
List dataSetUsers = new ArrayList();
JPanel panelForButtons;
public JFreeChart getChart() {
return chart;
}
public XYPlotExtension getPlot() {
return plot;
}
public XYLineAndShapeRendererExtention getRenderer() {
return renderer;
}
public Map getSeriesVisible() {
return seriesVisible;
}
public interface DataSetUser {
void useDataSet(List dataSets);
}
public ChartFrame use(DataSetUser dataSetUser) {
dataSetUsers.add(dataSetUser);
return this;
}
public static XYPlotExtension createXYPlotExtension(String yAxisLabel, String xAxisLabel, XYDataset dataset, XYLineAndShapeRendererExtention renderer) {
NumberAxis yAxis = new NumberAxis(yAxisLabel);
NumberAxis xAxis = new NumberAxis(xAxisLabel);
xAxis.setAutoRangeIncludesZero(false);
XYPlotExtension plot = new XYPlotExtension(dataset, xAxis, yAxis, renderer);
return plot;
}
public ChartFrame(boolean linesVisible, boolean shapesVisible) {
super("");
renderer = new LoadcoderRenderer(linesVisible, shapesVisible, seriesCollection);
plot = createXYPlotExtension("X", "Y", seriesCollection, renderer);
plot.setRenderer(renderer);
plot.getDomainAxis().setAutoRange(true);
plot.getRangeAxis().setAutoRange(true);
showChart();
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_C) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
chartPanel.doCopy();
}
}
@Override
public void keyReleased(KeyEvent e) {
}
});
}
XYDataItem xgetDataItem(XYSeriesExtension series, long x) {
int index = series.indexOf(x);
XYDataItem existing = (XYDataItem) series.getItems().get(index);
return existing;
}
public XYSeriesCollectionExtention getSeriesCollection() {
return seriesCollection;
}
public int getTotalSize(){
List l = seriesCollection.getSeries();
int totalSize = 0;
for(Object o : l){
XYSeriesExtension series = (XYSeriesExtension)o;
int seriesSize = series.getItemCount();
totalSize = totalSize + seriesSize;
}
return totalSize;
}
public static JFreeChart createXYLineChart(String title, PlotOrientation orientation, boolean legend,
boolean tooltips, boolean urls, XYPlot plot) {
ParamChecks.nullNotPermitted(orientation, "orientation");
plot.setOrientation(orientation);
XYItemRenderer renderer = plot.getRenderer();
if (tooltips) {
renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator());
}
if (urls) {
renderer.setURLGenerator(new StandardXYURLGenerator());
}
JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
currentTheme.apply(chart);
return chart;
}
JMenuBar createMenu(){
JMenuBar menuBar = new JMenuBar(); // Window menu bar
JLabel about = new JLabel("About");
about.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) {
AboutPopup.showAboutPopup(chartFrame);
}
});
menuBar.add(about);
return menuBar;
}
public ChartFrame showChart() {
panelForButtons = new JPanel();
panelForButtons.setBackground(Color.WHITE);
panelForButtons.setLayout(new BoxLayout(panelForButtons, BoxLayout.PAGE_AXIS));
chart = createXYLineChart(null, PlotOrientation.VERTICAL, true, true, false, plot);
//using this constructor in order to get rid of jcharts right click popup menu
chartPanel = new ChartPanelExtension(chart,
ChartPanel.DEFAULT_WIDTH,
ChartPanel.DEFAULT_HEIGHT,
ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH,
ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT,
ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH,
ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT,
ChartPanel.DEFAULT_BUFFER_USED, false, false, false, false, false, false);
menuBar = createMenu();
setJMenuBar(menuBar);
DateAxis dateAxis = new DateAxis();
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("GMT"));
dateAxis.setDateFormatOverride(format);
plot.setDomainAxis(dateAxis);
chartPanel.addChartMouseListener(new ChartMouseListener() {
public void chartMouseClicked(ChartMouseEvent e) {
int button = e.getTrigger().getButton();
Object entity = e.getEntity();
handleClick(button, entity, seriesCollection);
}
public void chartMouseMoved(ChartMouseEvent e) { }
});
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
chartPanel.setZoomAroundAnchor(true);
panelForButtons.add(chartPanel);
panelForButtons.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
scrolling(e);
plot.panDomainAxes(30, null, null);
}
});
setContentPane(panelForButtons);
plot.setDomainGridlinePaint(Color.BLACK);
plot.setRangeGridlinePaint(Color.BLACK);
plot.setBackgroundPaint(Color.WHITE);
pack();
RefineryUtilities.centerFrameOnScreen(this);
return this;
}
void setVisibility(XYSeriesExtension clickedSeries, int iterator, LegendItem legend, boolean visible){
if (clickedSeries instanceof XYDottedSeriesExtension) {
renderer.setSeriesShapesVisible(iterator, visible);
} else {
renderer.setSeriesLinesVisible(iterator, visible);
}
seriesVisible.put(clickedSeries.getKey(), visible);
clickedSeries.setVisible(visible);
legend.setLineVisible(visible);
}
public void handleClick(int button, Object clickedObject, XYSeriesCollectionExtention serieses) {
synchronized (plot) {
if (clickedObject instanceof PlotEntity) {
chart.setNotify(false);
if (button == 1) {
} else {
chartPanel.restoreAutoBounds();
}
chart.setNotify(true);
serieses.fireChange();
}else if (clickedObject instanceof LegendItemEntity) {
chart.setNotify(false);
LegendItemEntity legendItemEntity = (LegendItemEntity) clickedObject;
Comparable pushedLegend = legendItemEntity.getSeriesKey();
List lista = serieses.getSeries();
int iterator = 0;
XYSeriesExtension clickedSeries = null;
for (XYSeriesExtension xy : lista) {
Comparable c = xy.getKey();
if (pushedLegend.compareTo(c) == 0) {
clickedSeries = xy;
break;
}
iterator++;
}
LegendItem clickedLegend = clickedSeries.getLegend();
if (button == 1) {
boolean visible = !clickedSeries.isVisible();
setVisibility(clickedSeries, iterator, clickedLegend, visible);
} else {
int iterator2 = 0;
for (XYSeriesExtension xy : lista) {
LegendItem legend = xy.getLegend();
boolean visible = false;
if (xy.equals(clickedSeries))
visible = true;
setVisibility(xy, iterator2, legend, visible);
iterator2++;
}
}
chart.setNotify(true);
serieses.fireChange();
}
}
}
public void copy(){
chartPanel.doCopy();
}
void addPanel(JPanel resultChartPanel) {
panelForButtons.add(resultChartPanel);
}
public JMenuBar getMenu(){
return menuBar;
}
public void scrolling(MouseWheelEvent e) {
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
return;
if (e.getWheelRotation() < 0)
increaseZoom(chartPanel, true);
else
decreaseZoom(chartPanel, true);
}
public void increaseZoom(JComponent chart, boolean saveAction) {
synchronized (plot) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, true);
}
}
public void decreaseZoom(JComponent chart, boolean saveAction) {
synchronized (plot) {
ChartPanel ch = (ChartPanel) chart;
zoomChartAxis(ch, false);
}
}
private void zoomChartAxis(ChartPanel chartP, boolean increase) {
int width = chartP.getMaximumDrawWidth() - chartP.getMinimumDrawWidth();
int height = chartP.getMaximumDrawHeight() - chartP.getMinimumDrawWidth();
if (increase) {
chartP.zoomInBoth(width / 2, height / 2);
} else {
chartP.zoomOutBoth(width / 2, height / 2);
}
}
public void waitUntilClosed() {
while (isDisplayable())
LoadUtility.sleep(1000);
}
}