All Downloads are FREE. Search and download functionalities are using the official Maven repository.

morechart.chart.SplittableChartPanel.scala Maven / Gradle / Ivy

The newest version!
package morechart.chart

import java.awt.Cursor
import java.awt.event.{ MouseEvent, MouseMotionListener }
import java.awt.geom.Point2D

import javax.swing.event.MouseInputListener

import org.jfree.chart.ChartPanel

import org.jfree.chart.plot. {

  CombinedDomainXYPlot,
  CombinedRangeXYPlot,
  XYPlot

}

import scala.collection.JavaConversions
import scala.collection.mutable.Buffer

/** Extends [[org.jfree.chart.ChartPanel]] with x and y split.
 *
 * @author myst3r10n
 */
trait SplittableChartPanel extends ChartPanel {

  /** Split mode. */
  var splittable = 0

  addMouseListener(new MouseInputListener{

    def mousePressed(event: MouseEvent) {

      event.getButton match {
        case MouseEvent.BUTTON1 =>
          // Splittable.
          if(splittable > 0 &&
             (getChart.getPlot.isInstanceOf[CombinedDomainXYPlot] ||
              getChart.getPlot.isInstanceOf[CombinedRangeXYPlot])) {

            object Break extends Throwable

            try {

              for(i <- 0 to getChartRenderingInfo.getPlotInfo.getSubplotCount - 2) {

                val dataAreas = Pair(getChartRenderingInfo.getPlotInfo
                                     .getSubplotInfo(i).getPlotArea,
                                     getChartRenderingInfo.getPlotInfo
                                     .getSubplotInfo(i + 1).getPlotArea)

                if(getChart.getPlot.isInstanceOf[CombinedDomainXYPlot] &&
                   dataAreas._1.getX < event.getPoint.getX &&
                   dataAreas._2.getX < event.getPoint.getX &&
                   event.getPoint.getX < dataAreas._1.getX + dataAreas._1.getWidth &&
                   event.getPoint.getX < dataAreas._2.getX + dataAreas._2.getWidth &&
                   dataAreas._1.getY + dataAreas._1.getHeight < event.getPoint.getY &&
                   event.getPoint.getY < dataAreas._2.getY) {

                  val subplots = JavaConversions.asScalaBuffer(getChart.getPlot
                                 .asInstanceOf[CombinedDomainXYPlot].getSubplots)
                                 .asInstanceOf[Buffer[XYPlot]]

                  split.plots = (subplots(i), subplots(i + 1))
                  split.lengths = Pair(dataAreas._1.getHeight,
                                       dataAreas._2.getHeight)
                  split.weights = Pair(split.plots._1.getWeight,
                                       split.plots._2.getWeight)

                  throw Break

                } else if(getChart.getPlot.isInstanceOf[CombinedRangeXYPlot] &&
                        dataAreas._1.getX + dataAreas._1.getWidth < event.getPoint.getX &&
                        event.getPoint.getX < dataAreas._2.getX &&
                        dataAreas._1.getY < event.getPoint.getY &&
                        dataAreas._2.getY < event.getPoint.getY &&
                        event.getPoint.getY < dataAreas._1.getY + dataAreas._1.getHeight &&
                        event.getPoint.getY < dataAreas._2.getY + dataAreas._2.getHeight) {

                  val subplots = JavaConversions.asScalaBuffer(getChart.getPlot
                                 .asInstanceOf[CombinedDomainXYPlot].getSubplots)
                                 .asInstanceOf[Buffer[XYPlot]]

                  split.plots = (subplots(i), subplots(i + 1))
                  split.lengths = Pair(dataAreas._1.getWidth,
                                       dataAreas._2.getWidth)
                  split.weights = Pair(split.plots._1.getWeight,
                                       split.plots._2.getWeight)

                  throw Break

                }
              }
            } catch { case Break => }

            split.point = new Point2D.Double(event.getPoint.getX,
                                             event.getPoint.getY)

          }

        case _ =>
      }
    }

    def mouseReleased(event: MouseEvent) {

      if(split.plots != null) {

        split.plots = null
        if(getCursor.getType != Cursor.DEFAULT_CURSOR)
          setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR))

      }
    }

    def mouseMoved(event: MouseEvent) {}
    def mouseDragged(event: MouseEvent) {}
    def mouseExited(event: MouseEvent) {}
    def mouseEntered(event: MouseEvent) {}
    def mouseClicked(event: MouseEvent) {}

  } )

  addMouseMotionListener(new MouseMotionListener {

    def mouseMoved(event: MouseEvent) {

      if(splittable > 0 &&
         split.plots == null) {

        object Break extends Throwable

        try {

          for(i <- 0 to getChartRenderingInfo.getPlotInfo.getSubplotCount - 2) {

            val dataAreas = Pair(getChartRenderingInfo.getPlotInfo
                                 .getSubplotInfo(i).getPlotArea,
                                 getChartRenderingInfo.getPlotInfo
                                 .getSubplotInfo(i + 1).getPlotArea)

            if(getChart.getPlot.isInstanceOf[CombinedDomainXYPlot] &&
               dataAreas._1.getX < event.getPoint.getX &&
               dataAreas._2.getX < event.getPoint.getX &&
               event.getPoint.getX < dataAreas._1.getX + dataAreas._1.getWidth &&
               event.getPoint.getX < dataAreas._2.getX + dataAreas._2.getWidth &&
               dataAreas._1.getY + dataAreas._1.getHeight < event.getPoint.getY &&
               event.getPoint.getY < dataAreas._2.getY) {

              setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR))

              throw Break

            } else if(getChart.getPlot.isInstanceOf[CombinedRangeXYPlot] &&
                    dataAreas._1.getX + dataAreas._1.getWidth < event.getPoint.getX &&
                    event.getPoint.getX < dataAreas._2.getX &&
                    dataAreas._1.getY < event.getPoint.getY &&
                    dataAreas._2.getY < event.getPoint.getY &&
                    event.getPoint.getY < dataAreas._1.getY + dataAreas._1.getHeight &&
                    event.getPoint.getY < dataAreas._2.getY + dataAreas._2.getHeight) {

              setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR))

              throw Break

            }
          }

          if(getCursor.getType != Cursor.DEFAULT_CURSOR)
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR))

        } catch { case Break => }
      }
    }

    def mouseDragged(event: MouseEvent) {

      // Splittable.
      if(!isDomainZoomable &&
         !isRangeZoomable &&
         split.plots != null) {

        // Split domain.
        if(getChart.getPlot.isInstanceOf[CombinedDomainXYPlot] &&
           split.point.y != event.getY)
          splitting(split.plots, split.lengths, split.weights, split.point.y, event.getY)

        // Split range.
        else if(getChart.getPlot.isInstanceOf[CombinedRangeXYPlot] &&
                split.point.x != event.getY)
          splitting(split.plots, split.lengths, split.weights, split.point.x, event.getX)
      }
    }
  } )

  protected def splitting(plots: Pair[XYPlot, XYPlot],
                          lengths: Pair[Double, Double],
                          weights: Pair[Int, Int],
                          from: Double,
                          to: Double) {

    val diff = from - to
    val newWeights = Pair(weights._1 / lengths._1 * (lengths._1 - (diff)),
                          weights._2 / lengths._2 * (lengths._2 + (diff)))

    if(newWeights._1 > splittable && newWeights._2 > splittable) {
      plots._1.setWeight(newWeights._1.toInt)
      plots._2.setWeight(newWeights._2.toInt)
    } else {

      if(newWeights._1 < splittable) {

        plots._1.setWeight(splittable)
        plots._2.setWeight((newWeights._2 - (splittable - newWeights._1)).toInt)

      } else if(newWeights._2 < splittable){

        plots._1.setWeight((newWeights._1 - (splittable - newWeights._2)).toInt)
        plots._2.setWeight(splittable)
      
      }
    }
  }


  private object split {

    var plots: Pair[XYPlot, XYPlot] = null
    var lengths = Pair(0.0, 0.0)
    var weights = Pair(0, 0)
    var point: Point2D.Double = null

  }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy