Which dataset to use

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
raj_jfree
Posts: 20
Joined: Tue Sep 29, 2009 8:32 am
antibot: No, of course not.

Which dataset to use

Post by raj_jfree » Tue Oct 20, 2009 3:35 am

Hi,
Which dataset i need to use to create bubble chart where my domainAxix are Strings,RangeAxis is double .
help me out to proceed.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: Which dataset to use

Post by paradoxoff » Tue Oct 20, 2009 7:15 am

Since a XYBubbleRenderer is the only renderer which can draw bubbles you will have to use an XYZDataset, e. g. a DefaultXYZDataset. In order to have strings in your domain axis, you can use a SymbolAxis as domain axis (short use case here). Make sure that you use 0,1,2,3,... as x values for your data.

raj_jfree
Posts: 20
Joined: Tue Sep 29, 2009 8:32 am
antibot: No, of course not.

Re: Which dataset to use

Post by raj_jfree » Tue Oct 20, 2009 10:49 am

Hi,
I have used DefaultXYZDataset and XYBubbleRender these is the class i have written.

I have values double ad[] = { 50,100,150,200 }; // i don't have this array just for testing i have used it
double ad1[] = { 10, 20, 30, 40 }; // y axis
double ad2[] = { 20, 25, 30, 39 }; // total (count inside bubble)

can any one help me where i am going wrong.

Code: Select all

package com.jasper.web;

import java.awt.Color;
import java.awt.GradientPaint;
import java.io.File;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.labels.BubbleXYItemLabelGenerator;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBubbleRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.urls.XYURLGenerator;
import org.jfree.data.DomainOrder;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.DatasetChangeListener;
import org.jfree.data.general.DatasetGroup;
import org.jfree.data.xy.AbstractXYZDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYZDataset;
import org.jfree.ui.TextAnchor;
import org.jfree.util.PublicCloneable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class BubbleChartController implements Controller {
	

	 static class LabelGenerator extends StandardXYItemLabelGenerator
	 {
		private static final long serialVersionUID = 1L;

		public String generateLabel(DefaultXYZDataset xyzdataset, int i, int j) {
				
			 return xyzdataset.getSeriesKey(i).toString();
		 }

		 LabelGenerator() {
			 
			 System.out.println("in label");
		 }
	 }

	private String successView;

	public String getSuccessView() {
		return successView;
	}

	public void setSuccessView(String successView) {
		this.successView = successView;
	}

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		response.setContentType("text/html");

		JFreeChart jfreechart = createChart(createDataset());
		try {
			final ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());

			final File file = new File(request.getRealPath("/BubbleChart.png"));
			ChartUtilities.saveChartAsPNG(file, jfreechart, 600, 400, info);

			final PrintWriter writer = response.getWriter();
			writer.println("<HTML>");
			writer.println("<HEAD><TITLE>Bubble Chart</TITLE><script type=\"text/JavaScript\"  src=\"overlib.js\"></script></HEAD>");
			writer.println("<BODY>");
			ChartUtilities.writeImageMap(writer, "chart", info, true);
			writer.println("<IMG SRC=\"BubbleChart.png\" " + "WIDTH=\"600\" HEIGHT=\"400\" BORDER=\"0\" USEMAP=\"#chart\">");
			writer.println("</BODY>");
			writer.println("</HTML>");
			writer.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	public static DefaultXYZDataset createDataset() {
		DefaultXYZDataset defaultxyzdataset = new DefaultXYZDataset();
	     String as[] = {"one","two","three","four"};
	     double ad[] = { 50,100,150,200 };
	     double ad1[] = { 10, 20, 30, 40 };// y axis
	     double ad2[] = { 20, 25, 30, 39 }; // no of pipe line
	     double ad3[][] = {
	         ad, ad1, ad2
	     };
	     defaultxyzdataset.addSeries("PipeLine", ad3,as);
		return defaultxyzdataset;
	}

	private static JFreeChart createChart(DefaultXYZDataset xyzdataset) {
		JFreeChart jfreechart = ChartFactory.createBubbleChart("Pipeline Bubble", "", "", xyzdataset, PlotOrientation.HORIZONTAL, true, true, true);

		
		 XYPlot xyplot = (XYPlot) jfreechart.getPlot();
		xyplot.setForegroundAlpha(0.65F);
		xyplot.setDomainPannable(true);
		xyplot.setRangePannable(true);
		xyplot.setDomainGridlinesVisible(true);
		XYItemRenderer xyitemrenderer = xyplot.getRenderer();
		final GradientPaint gp0 = new GradientPaint(0.0f, 0.0f, Color.blue, 0.0f, 0.0f, Color.blue);
		xyitemrenderer.setSeriesPaint(0, gp0);

		NumberAxis numberaxis = (NumberAxis) xyplot.getDomainAxis();
		numberaxis.setRange(0,300);
		NumberAxis numberaxis1 = (NumberAxis) xyplot.getRangeAxis();
		numberaxis.setRange(0,50);
[color=#FF0000][b]//		ValueAxis xAxis = new SymbolAxis("Symbol", new String[] { "One", "Two", "Three", "Four" });
//		xyplot.setRangeAxis(xAxis)[/b];[/color]    [color=#FF0000]          // when i use this my bubble chart is generated with out any bubbles[/color]
		xyitemrenderer.setBaseItemLabelGenerator(new BubbleXYItemLabelGenerator());
		xyitemrenderer.setBaseItemLabelsVisible(true);
	    ItemLabelPosition itemlabelposition = new ItemLabelPosition(ItemLabelAnchor.INSIDE12, TextAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT, -1.5707963267948966D);
	    xyitemrenderer.setBasePositiveItemLabelPosition(itemlabelposition);

		

		return jfreechart;
	}
}



class DefaultXYZDataset extends AbstractXYZDataset implements XYZDataset, PublicCloneable {

	private static final long serialVersionUID = 1L;

	public DefaultXYZDataset() {
		seriesKeys = new ArrayList();
		seriesList = new ArrayList();
		seriesList1 = new ArrayList();
	}

	public int getSeriesCount() {
		return seriesList.size();
	}

	public Comparable getSeriesKey(int series) {
		if (series < 0 || series >= getSeriesCount())
			throw new IllegalArgumentException("Series index out of bounds");
		else
			return (Comparable) seriesKeys.get(series);
	}

	public int indexOf(Comparable seriesKey) {
		return seriesKeys.indexOf(seriesKey);
	}

	public DomainOrder getDomainOrder() {
		return DomainOrder.NONE;
	}

	public int getItemCount(int series) {
		if (series < 0 || series >= getSeriesCount()) {
			throw new IllegalArgumentException("Series index out of bounds");
		} else {
			double seriesArray[][] = (double[][]) (double[][]) seriesList.get(series);
			return seriesArray[0].length;
		}
	}

	public String getNameValue(int series, int item) {
		String seriesData[] = (String[]) seriesList1.get(series);
		return seriesData[item];
	}
	public String getName(int series, int item) {
		return new String(getNameValue(0, item));
	}

	public double getXValue(int series, int item) {
		double seriesData[][] = (double[][]) (double[][]) seriesList.get(series);
		return seriesData[0][item];
	}
	

	public Number getX(int series, int item) {
		return new Double(getXValue(series, item));
	}

	public double getYValue(int series, int item) {
		double seriesData[][] = (double[][]) (double[][]) seriesList.get(series);
		return seriesData[1][item];
	}

	public Number getY(int series, int item) {
		return new Double(getYValue(series, item));
	}

	public double getZValue(int series, int item) {
		double seriesData[][] = (double[][]) (double[][]) seriesList.get(series);
		return seriesData[2][item];
	}

	public Number getZ(int series, int item) {
		return new Double(getZValue(series, item));
	}
	



	public void addSeries(Comparable seriesKey, double data[][],String as[]) {
		
		if (seriesKey == null)
			throw new IllegalArgumentException("The 'seriesKey' cannot be null.");
		if (data == null)
			throw new IllegalArgumentException("The 'data' is null.");
		if (data.length != 3)
			throw new IllegalArgumentException("The 'data' array must have length == 2.");
		if (data[0].length != data[1].length || data[0].length !=data[2].length)
			throw new IllegalArgumentException("The 'data' array must contain three arrays all having the same length.");
		int seriesIndex = indexOf(seriesKey);
		if (seriesIndex == -1) {
			seriesKeys.add(seriesKey);
			seriesList.add(data);
			seriesList1.add(as);
			
		} else {
			seriesList.remove(seriesIndex);
			seriesList.add(seriesIndex, data);
			seriesList1.add(seriesIndex,as);
		}
		notifyListeners(new DatasetChangeEvent(this, this));
	}
	

	public void addSeries(Comparable seriesKey, double data[][]) {
		
		if (seriesKey == null)
			throw new IllegalArgumentException("The 'seriesKey' cannot be null.");
		if (data == null)
			throw new IllegalArgumentException("The 'data' is null.");
		if (data.length != 3)
			throw new IllegalArgumentException("The 'data' array must have length == 2.");
		if (data[0].length != data[1].length || data[0].length !=data[2].length)
			throw new IllegalArgumentException("The 'data' array must contain three arrays all having the same length.");
		int seriesIndex = indexOf(seriesKey);
		if (seriesIndex == -1) {
			seriesKeys.add(seriesKey);
			seriesList.add(data);
			
		} else {
			seriesList.remove(seriesIndex);
			seriesList.add(seriesIndex, data);
		}
		notifyListeners(new DatasetChangeEvent(this, this));
	}

	

	private List seriesKeys;
	private List seriesList;
	private List seriesList1;

	public void addChangeListener(DatasetChangeListener datasetchangelistener) {
		// TODO Auto-generated method stub

	}

	public DatasetGroup getGroup() {
		// TODO Auto-generated method stub
		return null;
	}

	public void removeChangeListener(DatasetChangeListener datasetchangelistener) {
		// TODO Auto-generated method stub

	}

	public void setGroup(DatasetGroup datasetgroup) {
		// TODO Auto-generated method stub

	}
}

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

XYBubbleChart with domain tick labels as strings

Post by paradoxoff » Tue Oct 20, 2009 7:10 pm

Though I haven´t checked your code very carefully:
here you are giving the x-values that you have used,
raj_jfree wrote: I have values double ad[] = { 50,100,150,200 }; // i don't have this array just for testing i have used it
but
I wrote: Make sure that you use 0,1,2,3,... as x values for your data.
Moreover, there is already a class DefaultXYZDataset in JFreeChart, and I recommend to use it. Your class has a couple of bugs, for example you have overwritten addChangeListener(DatasetChangeListener datasetchangelistener) with an empty method body, and you will thus never manage to register a DatasetChangeListener with your dataset.
I would also recommend to change the name of this thread to something more meaningful and add a hint to your other threads here and here (which deal with the same topic) to let other interested people know that there is a discussion of the question (posting the same question in several threads is a bad idea and scatters the discussion).

raj_jfree
Posts: 20
Joined: Tue Sep 29, 2009 8:32 am
antibot: No, of course not.

Re: Which dataset to use

Post by raj_jfree » Thu Oct 22, 2009 6:34 am

Thanks paradoxoff ... i have done with it below is my final code for generating....

Code: Select all

package com.iam.controllers;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.io.File;
import java.io.PrintWriter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.UIManager;

import org.apache.commons.lang.ArrayUtils;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.labels.BubbleXYItemLabelGenerator;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.labels.StandardXYZToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBubbleRenderer;
import org.jfree.chart.urls.XYURLGenerator;
import org.jfree.data.xy.DefaultXYZDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.TextAnchor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.iam.bm.IamBM;

public class BubbleChartController implements Controller {
	private IamBM iambm;
	

	public void setIamManager(IamBM IamManager) {
		this.iambm = IamManager;
	}

	static class LabelGenerator extends StandardXYItemLabelGenerator
	 {
		private static final long serialVersionUID = 1L;

		public String generateLabel(DefaultXYZDataset xyzdataset, int i, int j) {
			 return xyzdataset.getSeriesKey(i).toString();
		 }
		 LabelGenerator() {
		 }
	 }

	private String successView;

	public String getSuccessView() {
		return successView;
	}

	public void setSuccessView(String successView) {
		this.successView = successView;
	}

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		response.setContentType("text/html");
//		JFreeChart jfreechart = createChart(createDataset());
		JFreeChart jfreechart = createChart();
		try {
			final ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());

			final File file = new File(request.getRealPath("/BubbleChart.png"));
			ChartUtilities.saveChartAsPNG(file, jfreechart, 600, 400, info);

			final PrintWriter writer = response.getWriter();
			writer.println("<HTML>");
			writer.println("<HEAD><TITLE>Bubble Chart</TITLE><script type=\"text/JavaScript\"  src=\"overlib.js\"></script></HEAD>");
			writer.println("<BODY>");
			ChartUtilities.writeImageMap(writer, "chart", info, true);
			writer.println("<IMG SRC=\"BubbleChart.png\" " + "WIDTH=\"600\" HEIGHT=\"400\" BORDER=\"0\" USEMAP=\"#chart\">");
			writer.println("</BODY>");
			writer.println("</HTML>");
			writer.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	public  JFreeChart createChart() {
		DefaultXYZDataset defaultxyzdataset = new DefaultXYZDataset();
		
    	
    	
//		double ad[] = { 0,1,2,3}; // For X-axis
//		double ad1[] = { 0, 5, 10, 15 };// y axis
//		double ad2[] = { 2D,3D,4D,5D}; // no of pipe line
		
		List bubbleList = new ArrayList();
		
		bubbleList = (List) iambm.getBubbleChartInfo("GINGERCHENG");
		
	 	List listPipelineCount = new ArrayList();
    	List listAmount = new ArrayList();
		Collection listCasestatus = new ArrayList();
		Iterator iter = bubbleList.iterator();
		while(iter.hasNext()){
			Object[] row = (Object[]) iter.next();
			listCasestatus.add(row[0]);
			listPipelineCount.add(Double.parseDouble(row[1].toString())); 
			listAmount.add(Double.parseDouble(row[2].toString())/100000000); 
		}

		double ad[] = { 0,1,2,3}; // For X-axis
		double ad1[] = ArrayUtils.toPrimitive((Double[]) listAmount.toArray(new Double[0]));
//		double ad2[] = ArrayUtils.toPrimitive((Double[]) listPipelineCount.toArray(new Double[0]));
		double ad2[]={ 5D,7D,4D,10D};
		
		double data[][] = { ad, ad1, ad2 };
		
		defaultxyzdataset.addSeries("No of Pipelines", data);
		ValueAxis yAxis = new NumberAxis(" ");
		yAxis.setLabelPaint(new Color(47,109,193));
		yAxis.setLabel("In Millions");
		yAxis.setTickLabelPaint(new Color(47,109,193));
		yAxis.setAutoRange(true);
		ValueAxis xAxis = new SymbolAxis(" ", new String[] { "Application", "Approval", "Acceptance", "Activation" });
		xAxis.setTickLabelPaint(new Color(47,109,193));
		XYBubbleRenderer renderer = new XYBubbleRenderer(XYBubbleRenderer.SCALE_ON_RANGE_AXIS);
		renderer.setBaseItemLabelGenerator(new BubbleXYItemLabelGenerator());
		renderer.setBaseItemLabelsVisible(true);
		final GradientPaint gp1 = new GradientPaint(0.0f, 0.0f, new Color(183,211,56), 0.0f, 0.0f, new Color(183,211,56));
		renderer.setSeriesPaint(0, gp1);
		ItemLabelPosition itemlabelposition = new ItemLabelPosition(ItemLabelAnchor.INSIDE12, TextAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT,	-1.5707963267948966D);
		renderer.setBasePositiveItemLabelPosition(itemlabelposition);
		renderer.setBaseLegendTextFont(new Font("Tahoma", 1, 10));
		renderer.setBaseLegendTextPaint(new Color(47,109,193));
		renderer.setBaseToolTipGenerator(new StandardXYZToolTipGenerator());
		renderer.setURLGenerator(new StandardXYZURLGenerator(" ", "series","status"));
		renderer.setBaseItemLabelPaint(new Color(47,109,193));
		renderer.setBaseOutlinePaint(new Color(183,211,56));
		XYPlot plot = new XYPlot(defaultxyzdataset, xAxis, yAxis, renderer);
		JFreeChart jfreechart = new JFreeChart("", new Font("Tahoma", 0, 18), plot, true);
		return jfreechart;
	}
}

//Class for overriding the generateURL method for returning the action name alone ... 
class StandardXYZURLGenerator implements XYURLGenerator, Cloneable, Serializable {
	private static final long serialVersionUID = 1L;
	@SuppressWarnings("unused")
	private String actionName;
	private String seriesParameterName;
	private String categoryParameterName;

	public StandardXYZURLGenerator(String actionName, String seriesParameterName, String categoryParameterName) {
		if (actionName != null)
			this.actionName = actionName;
		this.seriesParameterName = seriesParameterName;
		this.categoryParameterName = categoryParameterName;

	}

	public StandardXYZURLGenerator(String actionName, int x, int y) {
		if (actionName != null)
			this.actionName = actionName;

	}

	public StandardXYZURLGenerator() {
		// TODO Auto-generated constructor stub
	}

	public String generateURL(XYDataset dataset, int series, int category) {
		String url;
		Comparable categoryKey = dataset.getXValue(series, category);
		Comparable categoryKey1 = dataset.getYValue(series, category);
		if(categoryKey.equals(0.0)){
			categoryKey ="Application";
		}
		else if(categoryKey.equals(1.0)){
			categoryKey ="Approval";
		}
		else if(categoryKey.equals(2.0)){
			categoryKey ="Acceptance";
		}
		else if(categoryKey.equals(3.0)){
			categoryKey ="Activation";
		}
		
		url = this.seriesParameterName + "=" + series;
		url += "&" + this.categoryParameterName + "=" + categoryKey.toString();
		url += "&" + "Value" + "=" + categoryKey1;

		String javaScript = "javascript:alert('" + url + "')";
		url = javaScript;
		return url;
	}

}

Mich
Posts: 9
Joined: Mon Nov 09, 2009 2:33 pm
antibot: No, of course not.

Re: Which dataset to use

Post by Mich » Mon Nov 18, 2013 11:01 am

Or you have to write your own CategoryBubbleRenderer, I post here what I have done as example

Code: Select all


/**
 * Title: CategoryBubbleRenderer
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:
 *
 * Based on XYBubbleRenderer and BarRenderer
 *
 */



import org.jfree.chart.LegendItem;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.AbstractCategoryItemRenderer;
import org.jfree.chart.renderer.category.CategoryItemRendererState;
import org.jfree.data.category.CategoryDataset;
import org.jfree.ui.RectangleEdge;
import org.jfree.util.PublicCloneable;

import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

  /**
   * A renderer that draws a circle at each data point with a diameter that is
   * determined by the z-value in the dataset.
   */
  public class CategoryBubbleRenderer extends AbstractCategoryItemRenderer
          implements Cloneable, PublicCloneable/*, Serializable*/ {

    /** For serialization. */
    //public static final long serialVersionUID = -5221991598674249125L;



    public CategoryBubbleRenderer() {
      super();
      setBaseLegendShape(new Ellipse2D.Double(-4.0,-4.0,8.0,8.0));
    }



    /*public void drawItem(Graphics2D g2, XYItemRendererState state,
                         Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
                         ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
                         int series, int item, CrosshairState crosshairState, int pass) {*/
    public void drawItem(Graphics2D g2,
                         CategoryItemRendererState state,
                         Rectangle2D dataArea,
                         CategoryPlot plot,
                         CategoryAxis domainAxis,
                         ValueAxis rangeAxis,
                         CategoryDataset dataset,
                         int row,
                         int column,
                         int pass) {



      // nothing is drawn if the row index is not included in the list with
      // the indices of the visible rows...
      int visibleRow = state.getVisibleSeriesIndex(row);
      if (visibleRow < 0) {
        return;
      }
      // nothing is drawn for null values...
      Number dataValue = dataset.getValue(row, column);
      if (dataValue == null) {
        return;
      }
      int series = row;
      int item = column;

      PlotOrientation orientation = plot.getOrientation();

      // get the data point...
      //double x = dataset.getXValue(series, item);
      //double y = dataset.getYValue(series, item);
      double y = dataValue.doubleValue();
      double z = Double.NaN;


      double d1 = rangeAxis.getUpperBound();
      double d2 = rangeAxis.getLowerBound();
      z = (d2-d1)/10;//just an attempt to calculate  a good default value
      
      if (!Double.isNaN(z)) {
        RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
        RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
        //double transX = domainAxis.valueToJava2D(x, dataArea, domainAxisLocation);
        //double transX = domainAxis.getCategoryStart(column, getColumnCount(), dataArea, plot.getDomainAxisEdge());
        double transX = domainAxis.getCategoryMiddle(column, getColumnCount(),
                dataArea, plot.getDomainAxisEdge()) - state.getBarWidth()
                / 2.0;
        double transY = rangeAxis.valueToJava2D(y, dataArea, rangeAxisLocation);


        double zero2 = rangeAxis.valueToJava2D(0.0, dataArea,
                rangeAxisLocation);
        double transRange = zero2 - rangeAxis.valueToJava2D(z, dataArea,
                rangeAxisLocation);
        double transDomain = transRange;


        transDomain = Math.abs(transDomain);
        transRange = Math.abs(transRange);
        Ellipse2D circle = null;
        if (orientation == PlotOrientation.VERTICAL) {
          circle = new Ellipse2D.Double(transX - transDomain / 2.0,
                  transY - transRange / 2.0, transDomain, transRange);
        }
        else if (orientation == PlotOrientation.HORIZONTAL) {
          circle = new Ellipse2D.Double(transY - transRange / 2.0,
                  transX - transDomain / 2.0, transRange, transDomain);
        }
        g2.setPaint(getItemPaint(series, item));
        g2.fill(circle);
        g2.setStroke(getItemOutlineStroke(series, item));
        g2.setPaint(getItemOutlinePaint(series, item));
        g2.draw(circle);

        if (isItemLabelVisible(series, item)) {
          if (orientation == PlotOrientation.VERTICAL) {
            drawItemLabel(g2, orientation, dataset, series, item,
                    transX, transY, false);
          }
          else if (orientation == PlotOrientation.HORIZONTAL) {
            drawItemLabel(g2, orientation, dataset, series, item,
                    transY, transX, false);
          }
        }

        // add an entity if this info is being collected

        /*EntityCollection entities = null;
        if (info != null) {
          entities = info.getOwner().getEntityCollection();
          if (entities != null && circle.intersects(dataArea)) {
            addEntity(entities, circle, dataset, series, item,
                    circle.getCenterX(), circle.getCenterY());
          }
        }

        int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
        int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
        updateCrosshairValues(crosshairState, x, y, domainAxisIndex,
                rangeAxisIndex, transX, transY, orientation);
        */
      }

    }


    /**
     * Returns a legend item for the specified series.  The default method
     * is overridden so that the legend displays circles for all series.
     *
     * @param datasetIndex  the dataset index (zero-based).
     * @param series  the series index (zero-based).
     *
     * @return A legend item for the series.
     */
    public LegendItem getLegendItem(int datasetIndex, int series) {
      LegendItem result = null;
      CategoryPlot plot = getPlot();
      if (plot == null) {
        return null;
      }

      CategoryDataset dataset = plot.getDataset(datasetIndex);
      if (dataset != null) {
        if (getItemVisible(series, 0)) {
          String label = getLegendItemLabelGenerator().generateLabel(
                  dataset, series);
          String description = label;
          String toolTipText = null;
          if (getLegendItemToolTipGenerator() != null) {
            toolTipText = getLegendItemToolTipGenerator().generateLabel(
                    dataset, series);
          }
          String urlText = null;
          if (getLegendItemURLGenerator() != null) {
            urlText = getLegendItemURLGenerator().generateLabel(
                    dataset, series);
          }
          Shape shape = lookupLegendShape(series);
          Paint paint = lookupSeriesPaint(series);
          Paint outlinePaint = lookupSeriesOutlinePaint(series);
          Stroke outlineStroke = lookupSeriesOutlineStroke(series);
          result = new LegendItem(label, description, toolTipText,
                  urlText, shape, paint, outlineStroke, outlinePaint);
          result.setLabelFont(lookupLegendTextFont(series));
          Paint labelPaint = lookupLegendTextPaint(series);
          if (labelPaint != null) {
            result.setLabelPaint(labelPaint);
          }
          result.setDataset(dataset);
          result.setDatasetIndex(datasetIndex);
          //result.setSeriesKey(dataset.getSeriesKey(series));
          result.setSeriesKey(dataset.getRowKey(series));
          result.setSeriesIndex(series);
        }
      }
      return result;
    }


    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      }
      if (!(obj instanceof CategoryBubbleRenderer)) {
        return false;
      }
      CategoryBubbleRenderer that = (CategoryBubbleRenderer) obj;
      return super.equals(obj);
    }


    public Object clone() throws CloneNotSupportedException {
      return super.clone();
    }

  }



Locked