在scalafx中向下钻取并爬上一个饼图

时间:2015-09-17 10:45:05

标签: scala scalafx

以下是代码:

package scalafx.ensemble.example.charts

import javafx.scene.chart.PieChart.Data

import scala.util.Random
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.Includes._
import scalafx.collections.ObservableBuffer
import scalafx.scene.chart.PieChart
import scalafx.scene.input.MouseEvent
import scala.collection.mutable.{HashMap => MMap}

object BasicPie extends JFXApp {

  stage = new JFXApp.PrimaryStage {
    title = "Drilldown Pie Chart Example"
    scene = new Scene {
      root = {
        val pieChartDataBuffer = ObservableBuffer(
          PieChart.Data("A", 20),
          PieChart.Data("B", 30),
          PieChart.Data("C", 10),
          PieChart.Data("D", 40)
        )
        val pieChart = new PieChart {
          data = pieChartDataBuffer
          title = "DrillDown Pie Chart"
        }

        def subPieChartData: MMap[String, ObservableBuffer[Data]] = {
          val subDataMap: MMap[String, ObservableBuffer[Data]] = MMap.empty
          for(letter <- Array("A", "B", "C", "D")) {
            val dataBuffer: ObservableBuffer[Data] = ObservableBuffer.empty
            for(i <- 1 to 10)  {
              val subLabel = letter + i
              dataBuffer.add(PieChart.Data(subLabel, Random.nextInt(100)))
            }
            subDataMap.update(letter, dataBuffer)
          }
          subDataMap
        }

        def drillDownData = (pie: PieChart, pieData: PieChart.Data) => {
          val labelPrefix = pieData.name()
          val subData = subPieChartData(pieData.name())
          pieData.node().onMouseClicked = (_: MouseEvent) => pie.data = subData
          subData.foreach(
            (data) => climbUpData(pie, data)
          )
        }

        def climbUpData = (pie: PieChart, pieData: PieChart.Data) => {
          val node = pieData.node()
          if(node != null) {
            node.onMouseClicked = (_: MouseEvent) => pie.data = pieChartDataBuffer
          }
        }

        pieChartDataBuffer.foreach((data: Data) => drillDownData(pieChart, data))

        pieChart
      }
    }
  }

}

预期行为:

  1. 当应用运行时,它应显示主要组的饼图。 (良好)。

  2. 当您单击饼图的任意切片时,您应该获得该主要组的辅助组的饼图。 (好。)

  3. 当您单击辅助组的饼图中的任何切片时,应该将您带回主饼图。 (不工作。)

  4. 它编译并运行没有问题,向下钻取也按预期工作,但爬升不是。为什么呢?

1 个答案:

答案 0 :(得分:0)

在设置鼠标点击监听器之前,我应该先将level-2饼图数据设置为PieChart对象:

package scalafx.ensemble.example.charts

import javafx.scene.chart.PieChart.Data

import scala.util.Random
import scalafx.application.JFXApp
import scalafx.scene.Scene
import scalafx.Includes._
import scalafx.collections.ObservableBuffer
import scalafx.scene.chart.PieChart
import scalafx.scene.input.MouseEvent
import scala.collection.mutable.{HashMap => MMap}

object BasicPie extends JFXApp {

  stage = new JFXApp.PrimaryStage {
    title = "Drilldown Pie Chart Example"
    scene = new Scene {
      root = {
        val pieChartDataBuffer = ObservableBuffer(
          PieChart.Data("A", 20),
          PieChart.Data("B", 30),
          PieChart.Data("C", 10),
          PieChart.Data("D", 40)
        )
        val pieChart = new PieChart {
          data = pieChartDataBuffer
          title = "DrillDown Pie Chart"
        }

        def subPieChartData: MMap[String, ObservableBuffer[Data]] = {
          val subDataMap: MMap[String, ObservableBuffer[Data]] = MMap.empty
          for (letter <- Array("A", "B", "C", "D")) {
            val dataBuffer: ObservableBuffer[Data] = ObservableBuffer.empty
            for (i <- 1 to 10) {
              val subLabel = letter + i
              dataBuffer.add(PieChart.Data(subLabel, Random.nextInt(100)))
            }
            subDataMap.update(letter, dataBuffer)
          }
          subDataMap
        }

        def drillDownData = (pie: PieChart, pieData: PieChart.Data) => {
          val labelPrefix = pieData.name()
          val subData = subPieChartData(pieData.name())
          pieData.node().onMouseClicked = {
            (_: MouseEvent) => {
              pie.data = subData
              subData.foreach(
                (data) => climbUpData(pie, data)
              )
            }
          }
        }

        def climbUpData = (pie: PieChart, pieData: PieChart.Data) => {
          val node = pieData.node()
          if (node != null) {
            node.onMouseClicked = (_: MouseEvent) => pie.data = pieChartDataBuffer
          }
        }

        pieChartDataBuffer.foreach((data: Data) => drillDownData(pieChart, data))

        pieChart
      }
    }
  }

}

object Test {
  BasicPie.main(Array("a"))
}