Has anyone a code for a horizontal and vertikal scrollbar. I want to scroll my picture in both axis.
Thanks!!!
scrollbar
Hi,
have you tried puttin' the ChartPanel into a JScrollPane?
I haven't tried this yet, but I think this should work
KR
Florian
have you tried puttin' the ChartPanel into a JScrollPane?
Code: Select all
...
JScrollPane scroll=new JScrollPane(chartPanel)
...
KR
Florian
-
- Posts: 7
- Joined: Wed Aug 15, 2007 9:26 pm
Already done dude....
This is for panning/keyboard shifting:
public class ChartPanelShiftController implements KeyListener{
/** PAN plot by a fixed percentual of the range (eg. 1%) */
public static final int SHIFT_PERCENTUAL = 1;
/** PAN plot by a fixed number of pixels (eg. 1px) */
public static final int SHIFT_PIXEL = 2;
/** PAN plot by a fixed amout (eg. 5 range units) */
public static final int SHIFT_FIXED = 3;
/** The chart panel we're using */
protected ChartPanel chartPanel;
/** Does this plot supports shifting? Pie charts for example don't. */
protected boolean plotSupported = false;
/** The shift type. (default {@link #SHIFT_PIXEL} ) */
protected int shiftType = SHIFT_PERCENTUAL;
/** Fixed shift amount for domain axis */
protected double fixedDomainShiftUnits;
/** Fixed shift amount for range axis */
protected double fixedRangeShiftUnits;
/** By default we assume that the range axis is the vertical one (ie,
* PlotOrientation.VERTICAL (axesSwaped=false). If the range axis is the
* horizontal one (ie, PlotOrientation.HORIZONTAL) this variable should
* be set to true. */
protected boolean axesSwaped = false;
FinancialChartFrame frame;
/**
* Creates a new controller to handle plot shifts.
* @param chartPanel The panel displaying the plot.
*/
public ChartPanelShiftController(ChartPanel chartPanel,FinancialChartFrame frame) {
super();
this.chartPanel = chartPanel;
this.frame = frame;
// Check to see if plot is shiftable
Plot plot = chartPanel.getChart().getPlot();
if ((plot instanceof XYPlot) ||
(plot instanceof FastScatterPlot) ||
(plot instanceof ContourPlot)
) {
plotSupported = true;
axesSwaped = isHorizontalPlot(plot);
}
}
/**
* Returns the plot orientation.
* @return True = {@link org.jfree.chart.plot.PlotOrientation#VERTICAL VERTICAL};
* False = {@link org.jfree.chart.plot.PlotOrientation#HORIZONTAL HORIZONTAL}
*/
protected boolean isHorizontalPlot(Plot plot) {
if (plot instanceof XYPlot) {
return ((XYPlot)plot).getOrientation()==PlotOrientation.HORIZONTAL;
}
if (plot instanceof FastScatterPlot) {
return ((FastScatterPlot)plot).getOrientation()==PlotOrientation.HORIZONTAL;
}
return false;
}
/**
* Returns the ValueAxis for the plot or <code>null</code> if the plot
* doesn't have one.
* @param chart The chart
* @param domain True = get Domain axis. False = get Range axis.
* @return The selected ValueAxis or <code>null</code> if the plot doesn't
* have one.
*/
protected ValueAxis getPlotAxis(JFreeChart chart, boolean domain) {
// Where's the Shiftable interface when we need it ??
Plot plot = chart.getPlot();
if (plot instanceof XYPlot) {
return domain?((XYPlot)plot).getDomainAxis():((XYPlot)plot).getRangeAxis();
}
if (plot instanceof FastScatterPlot) {
return domain?((FastScatterPlot)plot).getDomainAxis():((FastScatterPlot)plot).getRangeAxis();
}
if (plot instanceof ContourPlot) {
return domain?((ContourPlot)plot).getDomainAxis():((ContourPlot)plot).getRangeAxis();
}
return null;
}
/**
* Pan/Shifts a plot if the arrow keys are pressed.
* @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
*/
public void keyPressed(KeyEvent e) {
if (!plotSupported) return;
int keyCode = e.getKeyCode();
// we're only interested in arrows (code 37,38,39,40)
if ((keyCode < 37) || (keyCode > 40)) return;
// The axis we're gonna shift
ValueAxis axis = null;
// Delta is the amount we'll shift in axis units.
double delta;
boolean domainShift = false; // used for PAN_FIXED
// Calculations for the domain axis
if ((keyCode == KeyEvent.VK_LEFT) || (keyCode == KeyEvent.VK_RIGHT)) {
axis = getPlotAxis(chartPanel.getChart(),!axesSwaped);
domainShift = true;
}
// Calculations for the range axis
else {
axis = getPlotAxis(chartPanel.getChart(),axesSwaped);
}
// Let's calculate 'delta', the amount by which we'll shift the plot
switch (shiftType) {
case SHIFT_PERCENTUAL:
delta = (axis.getUpperBound()-axis.getLowerBound())/100.0;
break;
case SHIFT_FIXED:
delta = (domainShift ? fixedDomainShiftUnits : fixedRangeShiftUnits);
break;
case SHIFT_PIXEL: // also the default
default:
// Let's find out what's the range for 1 pixel.
final Rectangle2D scaledDataArea = chartPanel.getScreenDataArea();
delta = axis.getRange().getLength() / (scaledDataArea.getWidth());
break;
}
// Shift modifier multiplies delta by 10
if (e.isShiftDown()) {
delta *= 10;
}
switch (keyCode) {
case KeyEvent.VK_LEFT:
case KeyEvent.VK_DOWN:
axis.setRange(axis.getLowerBound()-delta,axis.getUpperBound()-delta);
break;
case KeyEvent.VK_UP:
case KeyEvent.VK_RIGHT:
axis.setRange(axis.getLowerBound()+delta,axis.getUpperBound()+delta);
break;
}
this.frame.domain.configure();
}
/*
* @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
*/
public void keyTyped(KeyEvent e) {}
/*
* @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
*/
public void keyReleased(KeyEvent e) {}
/**
* Returns the fixed shift step for the domain axis.
* @return the fixed shift step for the domain axis.
*/
public double getFixedDomainShiftUnits() {
return fixedDomainShiftUnits;
}
/**
* Sets the fixed shift step for the domain axis.
* @param fixedDomainShiftUnits the fixed shift step for the domain axis.
*/
public void setFixedDomainShiftUnits(double fixedDomainShiftUnits) {
this.fixedDomainShiftUnits = fixedDomainShiftUnits;
}
/**
* Returns the fixed shift step for the range axis.
* @return the fixed shift step for the range axis.
*/
public double getFixedRangeShiftUnits() {
return fixedRangeShiftUnits;
}
/**
* Sets the fixed shift step for the range axis.
* @param fixedRangeShiftUnits the fixed shift step for the range axis.
*/
public void setFixedRangeShiftUnits(double fixedRangeShiftUnits) {
this.fixedRangeShiftUnits = fixedRangeShiftUnits;
}
/**
* Returns the current shift type.
* @return the current shift type.
* @see #SHIFT_FIXED
* @see #SHIFT_PERCENTUAL
* @see #SHIFT_PIXEL
*/
public int getShiftType() {
return shiftType;
}
/**
* Sets the shift type.
* @param the new shift type.
* @see #SHIFT_FIXED
* @see #SHIFT_PERCENTUAL
* @see #SHIFT_PIXEL
*/
public void setShiftType(int shiftType) {
this.shiftType = shiftType;
}
/**
* Returns whether or not the plot supports shifting.
* @return True if plot can be shifted.
*/
public boolean isPlotSupported() {
return plotSupported;
}
}
This is for both vertical and horizontal scrolling, and panning installed:
public class Example extends JFrame
{
private JScrollBar southBar = new JScrollBar(Adjustable.HORIZONTAL); private JScrollBar westBar = new JScrollBar(Adjustable.VERTICAL);
private ChangeListener southChngLstnr, westChngLstnr;
private ChartPanelShiftController controller;
public example()
{
final ChartPanel panel = new ChartPanel(createChart(createDataset(100)));
controller = new ChartPanelShiftController(panel,this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher()
{
public boolean dispatchKeyEvent(KeyEvent e)
{
if (e.getID() == KeyEvent.KEY_PRESSED)
{
controller.keyPressed(e);
}
return false;
}
});
getContentPane().setLayout( new BorderLayout());
getContentPane().add(panel,BorderLayout.CENTER);
getContentPane().add(westBar,BorderLayout.WEST);
getContentPane().add(southBar,BorderLayout.SOUTH);
final BoundedRangeModel southModel = southBar.getModel();
panel.getChart().getXYPlot().getDomainAxis().setUpperBound(60);
southModel.setExtent(60);
panel.getChart().addChangeListener(new ChartChangeListener()
{
public void chartChanged(ChartChangeEvent event)
{
ValueAxis axis = panel.getChart().getXYPlot().getDomainAxis();
southModel.removeChangeListener(southChngLstnr); //avoids recursion
southModel.setValue((int) axis.getLowerBound());
southModel.setExtent((int) axis.getRange().getLength());
southModel.addChangeListener(southChngLstnr);
}
});
final BoundedRangeModel westModel = westBar.getModel();
panel.getChart().getXYPlot().getRangeAxis().setUpperBound(60);
westModel.setExtent(60);
panel.getChart().addChangeListener(new ChartChangeListener()
{
public void chartChanged(ChartChangeEvent event)
{
ValueAxis axis = panel.getChart().getXYPlot().getRangeAxis();
westModel.removeChangeListener(westChngLstnr); //avoids recursion
westModel.setValue((int) axis.getLowerBound());
westModel.setExtent((int) axis.getRange().getLength());
westModel.addChangeListener(westChngLstnr);
}
});
southModel.addChangeListener(southChngLstnr = new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
DateAxis axis = (DateAxis)panel.getChart().getXYPlot().getDomainAxis(0);
axis.setRange(southModel.getValue(),southModel.getValue()+southModel.getExtent());
}
});
westModel.addChangeListener(westChngLstnr = new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
ValueAxis axis = panel.getChart().getXYPlot().getRangeAxis();
axis.setRange(westModel.getValue(),westModel.getValue()+westModel.getExtent());
}
});
}//Example()
public XYDataset createDataset(int numPoints)
{
final XYSeries series1 = new XYSeries("Test");
for(int i=0; i<numPoints; i++)
{
series1.add(i, Math.random()*100);
}
final XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series1);
return dataset;
}
public JFreeChart createChart(final XYDataset dataset)
{
// create the chart...
String yLabel = "yLabel";
String title = "description";
final JFreeChart chart = ChartFactory.createXYLineChart(
title, // chart title
null, // x axis label
yLabel, // y axis label
dataset, // data
PlotOrientation.VERTICAL, //XYLine setting
false, // include legend
false, // tooltips
false // urls
);
// get a reference to the plot for further customisation...
plot = chart.getXYPlot();
ValueAxis axis = plot.getDomainAxis();
axis.setLowerMargin(0.0);
axis.setUpperMargin(0.0);
axis.setAutoRange(true);
chart.getTitle().setHorizontalAlignment(HorizontalAlignment.LEFT);
chart.getTitle().setFont((new Font(null,Font.BOLD,14)));
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
return chart;
}
}//Example class
Now, JFreeChart is a fine tool for generating static charts, but in regards to
anything dynamic ,out of the box, it's a house cards. It's very extensible ,
but it's underlying design was never intended for fast dynamic updating.
Currently, I am trying to figure out how to use the horizontal scroll with the TimeSeries dataset, but the problem here is that a days(hours,mintes, second, etc....tested when update Series every 1.5 seconds using the Millisecond class) worth of data is generated when you create a TimeSeries object.
What you add() to TimeSeries gets plotted on the chart but the horizontal scrollbar breaks because of the hidden range of TimeSeries ticks. Whats more frustrating is that documentation is to simplistic in regards to exemplify the full/almost full use of the API(would be nice). So in all, you're pretty much left at hacking away to get anything to work(regarding to dynamic behavior). That's my two cents.
This is for panning/keyboard shifting:
public class ChartPanelShiftController implements KeyListener{
/** PAN plot by a fixed percentual of the range (eg. 1%) */
public static final int SHIFT_PERCENTUAL = 1;
/** PAN plot by a fixed number of pixels (eg. 1px) */
public static final int SHIFT_PIXEL = 2;
/** PAN plot by a fixed amout (eg. 5 range units) */
public static final int SHIFT_FIXED = 3;
/** The chart panel we're using */
protected ChartPanel chartPanel;
/** Does this plot supports shifting? Pie charts for example don't. */
protected boolean plotSupported = false;
/** The shift type. (default {@link #SHIFT_PIXEL} ) */
protected int shiftType = SHIFT_PERCENTUAL;
/** Fixed shift amount for domain axis */
protected double fixedDomainShiftUnits;
/** Fixed shift amount for range axis */
protected double fixedRangeShiftUnits;
/** By default we assume that the range axis is the vertical one (ie,
* PlotOrientation.VERTICAL (axesSwaped=false). If the range axis is the
* horizontal one (ie, PlotOrientation.HORIZONTAL) this variable should
* be set to true. */
protected boolean axesSwaped = false;
FinancialChartFrame frame;
/**
* Creates a new controller to handle plot shifts.
* @param chartPanel The panel displaying the plot.
*/
public ChartPanelShiftController(ChartPanel chartPanel,FinancialChartFrame frame) {
super();
this.chartPanel = chartPanel;
this.frame = frame;
// Check to see if plot is shiftable
Plot plot = chartPanel.getChart().getPlot();
if ((plot instanceof XYPlot) ||
(plot instanceof FastScatterPlot) ||
(plot instanceof ContourPlot)
) {
plotSupported = true;
axesSwaped = isHorizontalPlot(plot);
}
}
/**
* Returns the plot orientation.
* @return True = {@link org.jfree.chart.plot.PlotOrientation#VERTICAL VERTICAL};
* False = {@link org.jfree.chart.plot.PlotOrientation#HORIZONTAL HORIZONTAL}
*/
protected boolean isHorizontalPlot(Plot plot) {
if (plot instanceof XYPlot) {
return ((XYPlot)plot).getOrientation()==PlotOrientation.HORIZONTAL;
}
if (plot instanceof FastScatterPlot) {
return ((FastScatterPlot)plot).getOrientation()==PlotOrientation.HORIZONTAL;
}
return false;
}
/**
* Returns the ValueAxis for the plot or <code>null</code> if the plot
* doesn't have one.
* @param chart The chart
* @param domain True = get Domain axis. False = get Range axis.
* @return The selected ValueAxis or <code>null</code> if the plot doesn't
* have one.
*/
protected ValueAxis getPlotAxis(JFreeChart chart, boolean domain) {
// Where's the Shiftable interface when we need it ??

Plot plot = chart.getPlot();
if (plot instanceof XYPlot) {
return domain?((XYPlot)plot).getDomainAxis():((XYPlot)plot).getRangeAxis();
}
if (plot instanceof FastScatterPlot) {
return domain?((FastScatterPlot)plot).getDomainAxis():((FastScatterPlot)plot).getRangeAxis();
}
if (plot instanceof ContourPlot) {
return domain?((ContourPlot)plot).getDomainAxis():((ContourPlot)plot).getRangeAxis();
}
return null;
}
/**
* Pan/Shifts a plot if the arrow keys are pressed.
* @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
*/
public void keyPressed(KeyEvent e) {
if (!plotSupported) return;
int keyCode = e.getKeyCode();
// we're only interested in arrows (code 37,38,39,40)
if ((keyCode < 37) || (keyCode > 40)) return;
// The axis we're gonna shift
ValueAxis axis = null;
// Delta is the amount we'll shift in axis units.
double delta;
boolean domainShift = false; // used for PAN_FIXED
// Calculations for the domain axis
if ((keyCode == KeyEvent.VK_LEFT) || (keyCode == KeyEvent.VK_RIGHT)) {
axis = getPlotAxis(chartPanel.getChart(),!axesSwaped);
domainShift = true;
}
// Calculations for the range axis
else {
axis = getPlotAxis(chartPanel.getChart(),axesSwaped);
}
// Let's calculate 'delta', the amount by which we'll shift the plot
switch (shiftType) {
case SHIFT_PERCENTUAL:
delta = (axis.getUpperBound()-axis.getLowerBound())/100.0;
break;
case SHIFT_FIXED:
delta = (domainShift ? fixedDomainShiftUnits : fixedRangeShiftUnits);
break;
case SHIFT_PIXEL: // also the default
default:
// Let's find out what's the range for 1 pixel.
final Rectangle2D scaledDataArea = chartPanel.getScreenDataArea();
delta = axis.getRange().getLength() / (scaledDataArea.getWidth());
break;
}
// Shift modifier multiplies delta by 10
if (e.isShiftDown()) {
delta *= 10;
}
switch (keyCode) {
case KeyEvent.VK_LEFT:
case KeyEvent.VK_DOWN:
axis.setRange(axis.getLowerBound()-delta,axis.getUpperBound()-delta);
break;
case KeyEvent.VK_UP:
case KeyEvent.VK_RIGHT:
axis.setRange(axis.getLowerBound()+delta,axis.getUpperBound()+delta);
break;
}
this.frame.domain.configure();
}
/*
* @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
*/
public void keyTyped(KeyEvent e) {}
/*
* @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
*/
public void keyReleased(KeyEvent e) {}
/**
* Returns the fixed shift step for the domain axis.
* @return the fixed shift step for the domain axis.
*/
public double getFixedDomainShiftUnits() {
return fixedDomainShiftUnits;
}
/**
* Sets the fixed shift step for the domain axis.
* @param fixedDomainShiftUnits the fixed shift step for the domain axis.
*/
public void setFixedDomainShiftUnits(double fixedDomainShiftUnits) {
this.fixedDomainShiftUnits = fixedDomainShiftUnits;
}
/**
* Returns the fixed shift step for the range axis.
* @return the fixed shift step for the range axis.
*/
public double getFixedRangeShiftUnits() {
return fixedRangeShiftUnits;
}
/**
* Sets the fixed shift step for the range axis.
* @param fixedRangeShiftUnits the fixed shift step for the range axis.
*/
public void setFixedRangeShiftUnits(double fixedRangeShiftUnits) {
this.fixedRangeShiftUnits = fixedRangeShiftUnits;
}
/**
* Returns the current shift type.
* @return the current shift type.
* @see #SHIFT_FIXED
* @see #SHIFT_PERCENTUAL
* @see #SHIFT_PIXEL
*/
public int getShiftType() {
return shiftType;
}
/**
* Sets the shift type.
* @param the new shift type.
* @see #SHIFT_FIXED
* @see #SHIFT_PERCENTUAL
* @see #SHIFT_PIXEL
*/
public void setShiftType(int shiftType) {
this.shiftType = shiftType;
}
/**
* Returns whether or not the plot supports shifting.
* @return True if plot can be shifted.
*/
public boolean isPlotSupported() {
return plotSupported;
}
}
This is for both vertical and horizontal scrolling, and panning installed:
public class Example extends JFrame
{
private JScrollBar southBar = new JScrollBar(Adjustable.HORIZONTAL); private JScrollBar westBar = new JScrollBar(Adjustable.VERTICAL);
private ChangeListener southChngLstnr, westChngLstnr;
private ChartPanelShiftController controller;
public example()
{
final ChartPanel panel = new ChartPanel(createChart(createDataset(100)));
controller = new ChartPanelShiftController(panel,this);
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher()
{
public boolean dispatchKeyEvent(KeyEvent e)
{
if (e.getID() == KeyEvent.KEY_PRESSED)
{
controller.keyPressed(e);
}
return false;
}
});
getContentPane().setLayout( new BorderLayout());
getContentPane().add(panel,BorderLayout.CENTER);
getContentPane().add(westBar,BorderLayout.WEST);
getContentPane().add(southBar,BorderLayout.SOUTH);
final BoundedRangeModel southModel = southBar.getModel();
panel.getChart().getXYPlot().getDomainAxis().setUpperBound(60);
southModel.setExtent(60);
panel.getChart().addChangeListener(new ChartChangeListener()
{
public void chartChanged(ChartChangeEvent event)
{
ValueAxis axis = panel.getChart().getXYPlot().getDomainAxis();
southModel.removeChangeListener(southChngLstnr); //avoids recursion
southModel.setValue((int) axis.getLowerBound());
southModel.setExtent((int) axis.getRange().getLength());
southModel.addChangeListener(southChngLstnr);
}
});
final BoundedRangeModel westModel = westBar.getModel();
panel.getChart().getXYPlot().getRangeAxis().setUpperBound(60);
westModel.setExtent(60);
panel.getChart().addChangeListener(new ChartChangeListener()
{
public void chartChanged(ChartChangeEvent event)
{
ValueAxis axis = panel.getChart().getXYPlot().getRangeAxis();
westModel.removeChangeListener(westChngLstnr); //avoids recursion
westModel.setValue((int) axis.getLowerBound());
westModel.setExtent((int) axis.getRange().getLength());
westModel.addChangeListener(westChngLstnr);
}
});
southModel.addChangeListener(southChngLstnr = new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
DateAxis axis = (DateAxis)panel.getChart().getXYPlot().getDomainAxis(0);
axis.setRange(southModel.getValue(),southModel.getValue()+southModel.getExtent());
}
});
westModel.addChangeListener(westChngLstnr = new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
ValueAxis axis = panel.getChart().getXYPlot().getRangeAxis();
axis.setRange(westModel.getValue(),westModel.getValue()+westModel.getExtent());
}
});
}//Example()
public XYDataset createDataset(int numPoints)
{
final XYSeries series1 = new XYSeries("Test");
for(int i=0; i<numPoints; i++)
{
series1.add(i, Math.random()*100);
}
final XYSeriesCollection dataset = new XYSeriesCollection();
dataset.addSeries(series1);
return dataset;
}
public JFreeChart createChart(final XYDataset dataset)
{
// create the chart...
String yLabel = "yLabel";
String title = "description";
final JFreeChart chart = ChartFactory.createXYLineChart(
title, // chart title
null, // x axis label
yLabel, // y axis label
dataset, // data
PlotOrientation.VERTICAL, //XYLine setting
false, // include legend
false, // tooltips
false // urls
);
// get a reference to the plot for further customisation...
plot = chart.getXYPlot();
ValueAxis axis = plot.getDomainAxis();
axis.setLowerMargin(0.0);
axis.setUpperMargin(0.0);
axis.setAutoRange(true);
chart.getTitle().setHorizontalAlignment(HorizontalAlignment.LEFT);
chart.getTitle().setFont((new Font(null,Font.BOLD,14)));
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
return chart;
}
}//Example class
Now, JFreeChart is a fine tool for generating static charts, but in regards to
anything dynamic ,out of the box, it's a house cards. It's very extensible ,
but it's underlying design was never intended for fast dynamic updating.
Currently, I am trying to figure out how to use the horizontal scroll with the TimeSeries dataset, but the problem here is that a days(hours,mintes, second, etc....tested when update Series every 1.5 seconds using the Millisecond class) worth of data is generated when you create a TimeSeries object.
What you add() to TimeSeries gets plotted on the chart but the horizontal scrollbar breaks because of the hidden range of TimeSeries ticks. Whats more frustrating is that documentation is to simplistic in regards to exemplify the full/almost full use of the API(would be nice). So in all, you're pretty much left at hacking away to get anything to work(regarding to dynamic behavior). That's my two cents.
-
- Posts: 844
- Joined: Fri Oct 13, 2006 9:29 pm
- Location: Sunnyvale, CA
It is rude, wrong, and in some cases illegal to post code in this manner without giving credit to the original authors. In this case, the original authors are Gustavo H. Sberze Ribas (gribas) and Ben Ogle in Yet another Pan/Shift class (source included). Posting this code without the copyright and license statements is a violation of the license and is an act of plagiarism.determen77 wrote:Already done dude....
This is for panning/keyboard shifting:
In terms of logistics, please wrap all code in code tags. HTML strips leading whitespace which destroys the indentation necessary to make code comprehensible (at least in terms of parsable by humans). The code tags format the code in fixed type font and does not cause the whitespace to be striped nor emoticons to be rendered. In future, please use them.
heprom is correct when he says
There are several examples of panning support, but none of them are natively supported by JFreeChart. The panning support heprom is working on is a generic panning support for multiple, different types of charts/plots. The example you posted only works for FastScatterPlot, so it is not very generic. As it is, FastScatterPlot only (relatively) recently became fully integrated with JFreeChart.heprom wrote:scrolling/panning is not yet supported by jfreechart but it's a planned feature (I'm working on it).
Statements like this are true will all APIs/Libraries that start out as one thing and then grow to accommodate user suggestions, requests, and demands (although the latter does not get you very far). The JFreeChart library started as a primarily static plotting/graphing library focusing on flexibility and customization. As a result, the data structures are designed to be flexible and not necessarily fast. There have been numerous steps forward in making the latter true as well. Again, the FastScatterPlot is a good example of this.determen77 wrote:Now, JFreeChart is a fine tool for generating static charts, but in regards to
anything dynamic ,out of the box, it's a house cards. It's very extensible ,
but it's underlying design was never intended for fast dynamic updating.
Currently, I am trying to figure out how to use the horizontal scroll with the TimeSeries dataset, but the problem here is that a days(hours,mintes, second, etc....tested when update Series every 1.5 seconds using the Millisecond class) worth of data is generated when you create a TimeSeries object.
What you add() to TimeSeries gets plotted on the chart but the horizontal scrollbar breaks because of the hidden range of TimeSeries ticks. Whats more frustrating is that documentation is to simplistic in regards to exemplify the full/almost full use of the API(would be nice). So in all, you're pretty much left at hacking away to get anything to work(regarding to dynamic behavior). That's my two cents.
In terms of documentation, not everything was intended to be "tinker-under-the-hood"able. Some of the functionality is too low level for most users. I am sure they would understand it, but they do not really care to since it does what it is supposed to. With regards to dynamic updates, this is a relatively new addition, so you should expect the documentation to be slower to catch up to the code. I think every programmer would agree that writing code is far easier (and more fun?) than writing documentation as important as it is.
Thank you for your two cents. Here is your penny change. Please be respectful of other's hard work in the future and give credit where credit is due.
Richard West
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA
Design Engineer II
Advanced Micro Devices
Sunnyvale, CA
Scrolling chart = done
Hello
I looked at some examples from the archive that comes with the jfreechart developers guide, and found a cool thing. The example was called CompassFormatDemo2.java, and it had a scroll on the range axis. Well, the whole idea was to change the range of the axis, linked to the scroll position. I didn't want a scroll attached to the chart, but a scrolling chart (i believe there is a difference). So I attached a ChartMouseListener to the chart, and implemented the required methods like this :
dateAxis=my domain axis.
dragFlag=scroll/don't scroll the chart.
x=the X coordinate of the "clicked" point.
xNew=the current X coordinate of the mouse.
lowerBound, upperBound=the domain axis limits.
and it works kinda like this:
1.click on the chart (dragFlag=true).
2.move the mouse left/right from the original "clicked" position.
3.the range of the axis shifts left/right, accordingly to the position of the mouse.
4.click again on the chart->the scrolling stops (drag=false).
Now a problem appeared. I have some buttons used to change the ticks on the date axis. When I first start the application, the dateAxis is split on 5-to-5 minutes (e.g. 19:55-20:00-20:05 etc), but using these buttons can change this to 1-to-1 minutes, 2-to-2 hours etc. After I added the scrolling functionality, these buttons stopped working (meaning that they don't do anything or the changes wrong). If I don't scroll the chart, they are working fine. I have to mention that I used the code below to make the changes from 1-to-1 minutes to 30-to-30 minutes and so on:
Isn't there any other possibility to receive the same results but with another method? Cause I think that setFixedAutoRange(3000000) is not the right way.
I looked at some examples from the archive that comes with the jfreechart developers guide, and found a cool thing. The example was called CompassFormatDemo2.java, and it had a scroll on the range axis. Well, the whole idea was to change the range of the axis, linked to the scroll position. I didn't want a scroll attached to the chart, but a scrolling chart (i believe there is a difference). So I attached a ChartMouseListener to the chart, and implemented the required methods like this :
Code: Select all
private class ChartListener2 implements ChartMouseListener {
public void chartMouseClicked(ChartMouseEvent event) {
// TODO Auto-generated method stub
if (dragFlag==false) {
dragFlag=true;
x = event.getTrigger().getX();
}
else {
dragFlag = false;
}
}
public void chartMouseMoved(ChartMouseEvent event) {
// TODO Auto-generated method stub
if (dragFlag==true)
{
int xNew = event.getTrigger().getX();
if (x<xNew) {
long lowerBound = dateAxis.getMinimumDate().getTime();
long upperBound = dateAxis.getMaximumDate().getTime();
dateAxis.setRange(new Date(lowerBound-100000), new Date(upperBound-100000));
}
if (x>=xNew) {
long lowerBound = dateAxis.getMinimumDate().getTime();
long upperBound = dateAxis.getMaximumDate().getTime();
dateAxis.setRange(new Date(lowerBound+100000), new Date(upperBound+100000));
}
}
}
}
dragFlag=scroll/don't scroll the chart.
x=the X coordinate of the "clicked" point.
xNew=the current X coordinate of the mouse.
lowerBound, upperBound=the domain axis limits.
and it works kinda like this:
1.click on the chart (dragFlag=true).
2.move the mouse left/right from the original "clicked" position.
3.the range of the axis shifts left/right, accordingly to the position of the mouse.
4.click again on the chart->the scrolling stops (drag=false).
Now a problem appeared. I have some buttons used to change the ticks on the date axis. When I first start the application, the dateAxis is split on 5-to-5 minutes (e.g. 19:55-20:00-20:05 etc), but using these buttons can change this to 1-to-1 minutes, 2-to-2 hours etc. After I added the scrolling functionality, these buttons stopped working (meaning that they don't do anything or the changes wrong). If I don't scroll the chart, they are working fine. I have to mention that I used the code below to make the changes from 1-to-1 minutes to 30-to-30 minutes and so on:
Code: Select all
if (((Button) me.getSource()).equals(m5)) {
dateAxis.setFixedAutoRange(3000000.0); // 5 minutes
dateAxis.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss"));
}
if (((Button) me.getSource()).equals(setDomainM30Button)) {
dateAxis.setFixedAutoRange(18000000.0); // 30 minutes
dateAxis.setDateFormatOverride(new SimpleDateFormat("HH:mm:ss"));
}