Frank
Frank

Reputation: 31086

In JFreeChart how to make tooltip work for XYBarRenderer?

I have the following code :

import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.date.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.IntervalXYDataset;
import org.jfree.data.xy.XYDataset;
 
public class PriceVolume_Chart extends JPanel                                       // A demonstration application showing how to create a price-volume chart.   
{
  static boolean EXIT_ON_CLOSE_B=true;

  public PriceVolume_Chart(String title)
  {
    JFreeChart chart=createChart();
    ChartPanel panel=new ChartPanel(chart,true,true,true,false,true);
    panel.setPreferredSize(new java.awt.Dimension(1000,500));
    add(panel);
  }

  private JFreeChart createChart()
  {
    XYDataset priceData=createPriceDataset();
    String title="Eurodollar Futures Contract (MAR03)";
    JFreeChart chart=ChartFactory.createTimeSeriesChart(title,
                                                        "Date",
                                                        getYLabel("Price ( $ )"),
                                                        priceData,
                                                        true,
                                                        true,
                                                        true
                                                       );
    XYPlot plot=chart.getXYPlot();
    NumberAxis rangeAxis1=(NumberAxis)plot.getRangeAxis();
    rangeAxis1.setLowerMargin(0.40);  // to leave room for volume bars   
    DecimalFormat format=new DecimalFormat("00.00");
    rangeAxis1.setNumberFormatOverride(format);

    NumberAxis rangeAxis2=new NumberAxis("Volume");
    rangeAxis2.setUpperMargin(1.00);  // to leave room for price line   
    plot.setRangeAxis(1,rangeAxis2);
    plot.setDataset(1,createVolumeDataset());
    plot.setRangeAxis(1,rangeAxis2);
    plot.mapDatasetToRangeAxis(1,1);
    XYBarRenderer renderer2=new XYBarRenderer(0.20);
    renderer2.setShadowVisible(false); 
    /*
            renderer2.setToolTipGenerator(   
                new StandardXYToolTipGenerator(   
                    StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,   
                    new SimpleDateFormat("d-MMM-yyyy"), new DecimalFormat("0,000.00")   
                )   
            );   
     */
    plot.setRenderer(1,renderer2);
    return chart;
  }

  private static XYDataset createPriceDataset()
  {
    // create dataset 1...
    TimeSeries series1=new TimeSeries("Price");

    series1.add(new Day(2,MonthConstants.JANUARY,2002),95.565);
    series1.add(new Day(3,MonthConstants.JANUARY,2002),95.640);
    series1.add(new Day(4,MonthConstants.JANUARY,2002),95.710);

    series1.add(new Day(7,MonthConstants.JANUARY,2002),95.930);
    series1.add(new Day(8,MonthConstants.JANUARY,2002),95.930);
    series1.add(new Day(9,MonthConstants.JANUARY,2002),95.960);
    series1.add(new Day(10,MonthConstants.JANUARY,2002),96.055);
    series1.add(new Day(11,MonthConstants.JANUARY,2002),96.335);
    return new TimeSeriesCollection(series1);
  }

  private static IntervalXYDataset createVolumeDataset()
  {
    // create dataset 2...
    TimeSeries series1=new TimeSeries("Volume");

    series1.add(new Day(2,MonthConstants.JANUARY,2002),41020);
    series1.add(new Day(3,MonthConstants.JANUARY,2002),45586);
    series1.add(new Day(4,MonthConstants.JANUARY,2002),81672);

    series1.add(new Day(7,MonthConstants.JANUARY,2002),81975);
    series1.add(new Day(8,MonthConstants.JANUARY,2002),79692);
    series1.add(new Day(9,MonthConstants.JANUARY,2002),53187);
    series1.add(new Day(10,MonthConstants.JANUARY,2002),87929);
    series1.add(new Day(11,MonthConstants.JANUARY,2002),107047);
    return new TimeSeriesCollection(series1);
  }

  String getYLabel(String Text)
  {
    String Result="";
    
    for (int i=0;i<Text.length();i++) Result+=Text.charAt(i)+(i<Text.length()-1?"\u2009":"");
//    Out(Result);
    return Result;
  }

  private static void out(String message) { System.out.print(message); }
  private static void Out(String message) { System.out.println(message); }

  // Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
  static void Create_And_Show_GUI()
  {
    final PriceVolume_Chart demo=new PriceVolume_Chart("Price Volume Chart Demo");

    JFrame frame=new JFrame("Time_Series_Chart Frame");
    frame.add(demo);
    frame.addWindowListener( new WindowAdapter()
    {
      public void windowActivated(WindowEvent e) { }
      public void windowClosed(WindowEvent e) { }
      public void windowClosing(WindowEvent e) { if (EXIT_ON_CLOSE_B) System.exit(0); }
      public void windowDeactivated(WindowEvent e) { }
      public void windowDeiconified(WindowEvent e) { demo.repaint(); }
      public void windowGainedFocus(WindowEvent e) { demo.repaint(); }
      public void windowIconified(WindowEvent e) { }
      public void windowLostFocus(WindowEvent e) { }
      public void windowOpening(WindowEvent e) { demo.repaint(); }
      public void windowOpened(WindowEvent e) { }
      public void windowResized(WindowEvent e) { demo.repaint(); }
      public void windowStateChanged(WindowEvent e) { demo.repaint(); }
    });
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }

  public static void main(String[] args)
  {
    // Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
    SwingUtilities.invokeLater(new Runnable() { public void run() { Create_And_Show_GUI(); } });
  }
}

The tooltip for "Price" is working, but I don't know how to make the tooltip for "Volume" work or how to customize the "Price" tooltip format so it won't show 12:00 AM. Can someone show me?

Upvotes: 1

Views: 443

Answers (1)

trashgod
trashgod

Reputation: 205785

It looks like your example derives from PriceVolumeDemo1.java, a variation of which is seen here. Dating to 2002, the example uses a much earlier API.

Invoking the current version's setDefaultToolTipGenerator() method works as expected. Modifying renderer2 is straightforward; but "to customize the Price tooltip format so it won't show 12:00 AM" requires accessing the generator installed by your chosen ChartFactory. Note the use of format factories to simplify localization for both tool tips and axes.

XYToolTipGenerator generator = new StandardXYToolTipGenerator(
    StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,
    DateFormat.getDateInstance(), NumberFormat.getCurrencyInstance()
);
…
plot.getRenderer().setDefaultToolTipGenerator(generator);
renderer2.setDefaultToolTipGenerator(generator);
…
rangeAxis1.setNumberFormatOverride(NumberFormat.getCurrencyInstance());
rangeAxis2.setNumberFormatOverride(NumberFormat.getNumberInstance());

image

Upvotes: 1

Related Questions