Javafx and Swing DashBoard("Kenya Terror Attacks 1992 to 2014")

Long since i posted a javafx data viz project,i have been getting familiarized with javafx in IOT,my device of choice is the Raspberry PI.I will be posting my javafx IOT projects in the same blog spot no need for another blog since everything here is done in java only.

As any dataviz post the data can be found here,Global Terrorism Database has data for Kenya from 1992 to 2014,had to filter only incidents from Kenya.
The columns that i used are date,lat,lon,city,weapon type,kill,wounded.

The Visuals

the map WorldWindJava library Swing
the rest are Javafx nodes

Setting up the Map

        WorldWindowGLJPanel wwd =new WorldWindowGLJPanel ();
        RenderableLayer rl = new RenderableLayer();

        BasicModel basicModel=new BasicModel();
        EarthFlat ef=new EarthFlat();
        BasicView bsv=new BasicView();
        bsv.setGlobe(ef);

        wwd.setModel(basicModel);
        wwd.getModel().setGlobe(ef);
        wwd.getModel().getLayers().removeAll();
        wwd.getModel().getLayers().add(rl);

         //zoom to area with points

        Sector bounds = Sector.boundingSector(pos);
        BasicOrbitView fov = (BasicOrbitView) wwd.getView();
        fov.setCenterPosition(Position.fromDegrees(bounds.getCentroid().getLatitude().degrees,                      bounds.getCentroid().getLongitude().degrees));
        double radii = wwd.getModel().getExtent().getRadius();
        double viewRange = Math.sqrt(Math.pow(bounds.getMaxLatitude().degrees-                       bounds.getMinLatitude().degrees,3)+Math.pow(bounds.getMaxLongitude().degrees-bounds.getMinLongitude().degrees, 3));
        double altitude = radii * Math.sin(Math.toRadians(viewRange * 0.5));
        wwd.setPreferredSize(new Dimension(800,650));
        fov.setZoom(altitude);

Marker 

   int MAX_VAL=241;

   int MAX_RADIUS=60000;

private SurfaceCircle addKills(String item[]){

        double lat=Double.valueOf(item[0]);
        double lon=Double.valueOf(item[1]);
       
       double killed=Double.valueOf(item[2]);

        LatLon latlon=new LatLon(Angle.fromDegreesLatitude(lat)),
                                  Angle.fromDegreesLongitude(lon));
       
         d=Math.sqrt(Math.pow(MAX_RADIUS,2) *killed /MAX_VAL);

         kills+=Double.valueOf(item[2]);
       
         Platform.runLater(() -> {
             dead_txt.setText("Dead       : "+kills);

        });
 
        double radius=d==0?1000:d;
       
        SurfaceCircle sp=new SurfaceCircle(latlon,radius);
        BasicShapeAttributes sb=new BasicShapeAttributes();
        sb.setInteriorMaterial(Material.RED);
        sb.setOutlineMaterial(Material.RED);
        sb.setEnableAntialiasing(true);
        sb.setOutlineOpacity(0.2);
        sb.setInteriorOpacity(0.2);
        sp.setAttributes(sb);
        return sp;

}
Animate

private Timer animate() throws Exception{
     javax.swing.Timer timer=new Timer(1, (ActionEvent e) -> {
           if(i==lines.size()-1){
               tm.stop();
               i=0;
           }
         
        String s=lines.get(i);
        String item[]=s.split(",");
       
        SurfaceCircle attacks= addKills(item);
        SurfaceCircle injuries= addInjuries(item);

        rl.addRenderable(injuries);
        rl.addRenderable(attacks);
        rl.firePropertyChange(AVKey.LAYER, null, this);//redraw layer
       
        Platform.runLater(() -> {
            Label label=(Label) root.lookup("#"+item[4]);
            label.setFont(Font.font("arial", 9));
            label.setTextFill(Color.WHITE);
            incidents_txt.setText("No of Incidents : "+i);
        });
     
        i++;

        });
return timer;

My log listcell class

public class LogListCell extends ListCell<String>{
   
   GridPane root;
 
   Text date_txt;
   Text weapon_txt;
   Text kill_txt;
   Text wound_txt;
   Text city_txt;
 
        LogListCell (){
     
        root=new GridPane();
        root.setAlignment(Pos.TOP_LEFT);
        root.setHgap(5);
        root.setVgap(5);
        root.setId("gridPane");
       
        date_txt=new Text("Date : ");
        date_txt.setFill(Color.WHITE);
        root.add(date_txt, 0, 0);
       
        city_txt=new Text("City : ");
        city_txt.setFill(Color.WHITE);
        root.add(city_txt, 0, 1);
   
        weapon_txt=new Text("Weapon : ");
        weapon_txt.setFill(Color.WHITE);
        root.add(weapon_txt, 0, 2);
       
        kill_txt=new Text("Dead : ");
        kill_txt.setFill(Color.RED);
        root.add(kill_txt, 0, 3);
       
        wound_txt=new Text("Injured : ");
        wound_txt.setFill(Color.ORANGE);
        root.add(wound_txt, 0, 4);

    }
     @Override
  public void updateItem(String item, boolean empty) {
      super.updateItem(item, empty);

      if(!empty){
        setGraphic(root);
        String rry[]=item.split(",");
        date_txt.setText("Date : "+rry[4]);
        city_txt.setText("City : "+rry[3]);
        weapon_txt.setText("Weapon : "+rry[6]);
        kill_txt.setText("Dead : "+rry[2]);
        wound_txt.setText("Injured : "+rry[5]);
      }
  }
}

setting custom cell to the  listview

list_view.setCellFactory((ListView<String> list1) -> new LogListCell ());

Year Labels

private void onYearClicked(){

        for(int year=1992;year<2015;year++){
            Label label=new Label();
            label.setId(String.valueOf(year));
            label.setFont(Font.font("arial", 9));
            label.setTextFill(Color.GREY);
         
            label.setOnMouseClicked((MouseEvent event) -> {
            label.setTextFill(Color.WHITE);
 
            temp_data=lines.stream()
                      .filter(s->s.contains(label.getText()))
                      .collect(toList());
           
            incidents+=temp_data.size();
           
            incidents_txt.setText("No of Incidents : "+incidents);
           
            list_view_data.addAll(temp_data);
            list_view.setItems(list_view_data);

                for(String s:temp_points){
                      String item[]=s.split(",");
                      SurfaceCircle attacks= addKills(item);
                      SurfaceCircle injuries=addInjuries(item);
                      rl.addRenderable(injuries);
                      rl.addRenderable(attacks);
                      rl.firePropertyChange(AVKey.LAYER, null, this);
                }
            });
            label.setText(String.valueOf(year));
            label.setLayoutX(y_axis);
            label.setLayoutY(660);
            y_axis+=30;
            root.getChildren().add(label);
        }


    }
Since i want the dashboard to be interactive in any way,i wouldn't say that its a finished project and the data still has some columns i would like to add,and the list view isn't interactive yet.



Results
1998 bomb blast

2010,2011,2012,2013,2014 attacks

2014 attacks

1992_2014 attacks

Video

Comments

Post a Comment

Popular Posts