2011-08-26 2 views
3

JFreechart에서 xybubblerenderer를 사용하여 카테고리 플롯을 구현하는 방법은 무엇입니까? 각 카테고리에 대해 여러 가지 거품을 표시하는 카테고리 플롯이 필요합니다. 이 버블은 버블의 x 값을 사용하여 플롯의 y 축에 배치되고 버블의 y 값은 해당 영역을 결정합니다. 그래서 각 카테고리 안에 거품이 있습니다. 줄거리상의 x 위치는 임의적 일 수 있습니다. 한 값은 플롯에서 y 위치를 제어하고 다른 값은 영역을 제어합니다.xybubblerenderer를 사용하여 categoryplot을 구현하는 방법

답변

0

SymbolAxis 및 XYBubbleRenderer를 사용하여 수행 할 수 있습니다. 기포의 x 값이 범위 [0, n]과 [0, n]에 있음이 기호 축에 적절한 레이블로 지정되었는지 확인해야합니다.

0

그렇지 않으면 당신은, 내가 이렇게 한 자신의 CategoryBubbleRenderer를 작성해야 그리고 여기, 내 코드를 작동

/** 
* 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(); 
    } 

    } 
관련 문제