0

Here is the code:

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
      }
    }
  }

}

Expected behavior:

  1. When the app runs, it should display a piechart of primary groups. (Good.)

  2. When you click on the any slice of the pie, you should get a piechart of the secondary groups of that primary group. (Good.)

  3. When you click any slice in the piechart of the secondary group, you should be taken back to the primary piechart. (Not working.)

It compiles and runs without a problem, the drilling down is also working as expected, but the climbing up is not. Why?

qed
  • 22,298
  • 21
  • 125
  • 196

1 Answers1

0

I should have set the level-2 piechart data to the PieChart object first before setting the mouse click listener:

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"))
}
qed
  • 22,298
  • 21
  • 125
  • 196