Luke
Luke

Reputation: 3872

JFreeChart Histogram with constant number of bins while zooming

I'd like to make a JFreeChart Histogram that maintains a constant number of bins while zooming in and out. For example, maybe zoomed way out you can see 12 years, and there would be 1 bin for each year. When you zoom in a little more you might see 12 months and there would be a bin for each month. Zooming in even further maybe there are 1 bin for each day, each hour, etc. They don't have to be such clean bin sizes, but you get the idea.

I'm using HistogramDataset.addSeries to add my data to the histogram. The bins parameter, is the number of bins for the entire set and doesn't take zooming into consideration.

I've observed that I can use a ChartPanel and override its zoom method. In here I could potentially alter the number of bins. However, I'm having a hard time figuring out where I can alter the number of bins and what it should be altered to.

EDIT:

There are a few parts of this problem that I am interested in that I believe are critical to a solution:

  1. How best to tell that the user has zoomed. My current approach is to override zoom.
  2. How to determine the bounds that the user has zoomed to. I'm still not sure how to do this.
  3. How to change the number of bins in the data model so that zooming maintains the same number of shown bins.

For some context, my end goal is to create a Google finance style control: Google Finance style control for Java?

Upvotes: 1

Views: 968

Answers (2)

Luke
Luke

Reputation: 3872

To answer my individual questions above:

  1. I continued to override zoom on the ChartPanel class.
  2. In order to determine the range that the user zoomed to I used the windowToRatio and ratioToModel functions below, as the zoom function is given window coordinates.
  3. To change the number of bins, I actually kept the number of bins the same and simply changed the dataset passed into the chart. I used a SortedMap for my data model that I could easily get subMap's from.

Functions:

private double windowToRatio(double window) {
    Rectangle2D scaledDataArea = getScreenDataArea();
    return (window - scaledDataArea.getMinX()) / scaledDataArea.getWidth();
}

private double ratioToModel(double ratio) {
    Range domainRange = getChart().getXYPlot().getDomainAxis().getRange();
    return domainRange.getLowerBound() + ratio * domainRange.getLength();
}

Upvotes: 1

trashgod
trashgod

Reputation: 205855

Overloading the zoom feature is appealing, but perhaps confusing. As an alternative, consider adding a control that updates the data model, as shown in this example. Instances of an enum are particularly convenient for populating a JComboBox, as shown here.

Upvotes: 2

Related Questions