Javafx ArcNode to ("DonutNode")

Scrolling through the javafx documentation stumbled upon the Arc class,I had an idea of  building a DonutNode with a label at the center that show percentage.I tried this with a line well,didn't turn out as i wanted cause calculating the angular extent was the problem.

The Arc class to the rescue it has a method that is setLength() which define the angular extent of the arc,what i had to do is just convert from degrees to percentage.







The Node
This class DonutNode extends Region

        Arc arc = new Arc();
        arc.setCenterX(40.0f);
        arc.setCenterY(40.0f);
        arc.setRadiusX(35.0f);
        arc.setRadiusY(35.0f);
        arc.setStartAngle(0.0f);
        arc.setStroke(arc_stroke);
        arc.setFill(Color.TRANSPARENT);
        arc.setStrokeWidth(5);
        arc.setType(ArcType.OPEN);
       
        Label  label =new Label();
        label.setText("0");
        label.setFont(Font.font(16));
        label.setLayoutX(CENTER-12);
        label.setLayoutY(CENTER-16);
        label.setContentDisplay(ContentDisplay.CENTER);
        label.setTextFill(label_fill);
        label.setLabelFor(arc);
       
        Circle c=new Circle();
        c.setRadius(30);
        c.setFill(circle_fill);
        c.setLayoutX(arc.getCenterX());
        c.setLayoutY(arc.getCenterY());

        this.setStyle("-fx-background-color:black;");
        this.setPrefSize(80,80);

        this.getChildren().addAll(arc,c,label);//adding children to the  Region

The Conversion

   public void setPercentage(double percent){
        double angle=(18*percent)/5;//from percentage to degrees
        arc.setLength(angle);
        label.setText(String.valueOf(percent));
    }

The Animation

The animation moves the stroke from angle/percent 0 to the setPercentage value,or if in enum Motion.REVERSE  from setPercentage to 0.

   private void playForwardAnimation(Duration duration){
           
     final Animation animation = new Transition() {
         double i=0;
         double lenght=getLength();
     {
         setCycleDuration(duration);
     }
     @Override
     protected void interpolate(double frac) {
       
         if(i==lenght+1){
             stop();
         }else{
           arc.setLength(i);
           label.setText(String.valueOf((5*i)/18).split("\\.")[0]);//display percentage
           i++;
         }
    }
 };    
         animation.setRate(0.5);
         animation.play();
     

    }
Some DonutNode examples

//i did this just to style the node differently

    DonutNode arc=new DonutNode(Color.PINK,Color.YELLOW,Color.TRANSPARENT);
    arc.setPercentage(75);
    arc.playAnimation(Duration.seconds(5),Motion.FORWARD);
   
    DonutNode arc2=new DonutNode(Color.CYAN,Color.BLUE,Color.TRANSPARENT);
    arc2.setPercentage(45);
    arc2.playAnimation(Duration.seconds(9),Motion.FORWARD);
   
    DonutNode arc3=new DonutNode(Color.GRAY,Color.MAROON,Color.TAN);
    arc3.setPercentage(50);
    arc3.playAnimation(Duration.seconds(19),Motion.FORWARD);
   
    DonutNode arc4=new DonutNode(Color.YELLOW,Color.TOMATO,Color.TRANSPARENT);
    arc4.setPercentage(90);

    arc4.playAnimation(Duration.seconds(29),Motion.FORWARD);

The  DonutNode class here

The Results


Comments

Popular Posts