1

I've got a box plot (CategoryPlot) with a customBoxAndWhiskerRenderer`. A series of bins forms the categories. I want to mark the transition from one category to another with a vertical line.

For example in the following figure, a line marks the sixth category, however I want it to appear between the fifth and sixth category:

enter image description here

  val mark = new CategoryMarker(splitBin)
  mark.setDrawAsLine(true)
  plot.addDomainMarker(mark, Layer.BACKGROUND)

What is the best/easiest way to achieve this?

4

1 回答 1

1

由于我已经有一个自定义渲染器,我连接到该drawDomainMarker方法,检查是否存在自定义子类型CategoryMarker

class LeftCategoryMarker(key: Comparable[_], paint: Paint, stroke: Stroke) 
  extends CategoryMarker(key, paint, stroke) {

  def this(key: Comparable[_]) = this(key, Color.gray, new BasicStroke(1.0f))
}

然后draw方法转向:

override def drawDomainMarker(g2: Graphics2D, plot: CategoryPlot, axis: CategoryAxis,
                                marker: CategoryMarker, dataArea: Rectangle2D): Unit =
  marker match {
    case _: LeftCategoryMarker => drawLeftMarker(g2, plot, axis, marker, dataArea)
    case _ => super.drawDomainMarker(g2, plot, axis, marker, dataArea)
  }

 

private def drawLeftMarker(g2: Graphics2D, plot: CategoryPlot, axis: CategoryAxis,
                           marker: CategoryMarker, dataArea: Rectangle2D): Unit = {
  val cat     = marker.getKey
  val dataset = plot.getDataset(plot.getIndexOf(this))
  val catIdx  = dataset.getColumnIndex(cat)
  if (catIdx < 0) return

  val savedComposite = g2.getComposite
  g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, marker.getAlpha))

  axis.getCategoryMargin
  val numCat      = dataset.getColumnCount
  val domainEdge  = plot.getDomainAxisEdge
  val left        = axis.getCategoryStart   (catIdx, numCat, dataArea, domainEdge)
  val gap         = calculateCategoryGapSize(axis  , numCat, dataArea, domainEdge)
  val v           = left - gap/2
  val line        = if (plot.getOrientation == PlotOrientation.HORIZONTAL)
    new Line2D.Double(dataArea.getMinX, v, dataArea.getMaxX, v)
  else
    new Line2D.Double(v, dataArea.getMinY, v, dataArea.getMaxY)

  g2.setPaint (marker.getPaint )
  g2.setStroke(marker.getStroke)
  g2.draw(line)

  g2.setComposite(savedComposite)
}

并且需要以下受保护的方法CategoryAxis来计算差距:

private def calculateCategoryGapSize(axis: CategoryAxis, categoryCount: Int,
                                     area: Rectangle2D, e: RectangleEdge): Double = {
  if (categoryCount == 0) return 0.0

  val available = if ((e == RectangleEdge.TOP) || (e == RectangleEdge.BOTTOM))
    area.getWidth
  else if ((e == RectangleEdge.LEFT) || (e == RectangleEdge.RIGHT))
    area.getHeight
  else
    0.0

  available * axis.getCategoryMargin / (categoryCount - 1)
}

在此处输入图像描述

于 2013-10-27T16:08:54.713 回答