Saturday, November 21, 2020

Arc charts...

Aloha,

I really need to post more often, it's already November...

When I was looking for some interesting charts that I might add to my JavaFX charts library I stumbled upon an arc diagram. It's a chart that is very specific and cannot be used to visualize all kinds of data but it's great to visualize interactions or flows between items. More info about this diagram can be found at wikipedia.

As always this chart was just created for the fun of it and not because I really need it, so I always try to make it as useful as possible but I don't know the special needs in the industry. So whenever you find something that can improve the handling of these charts, please let me know and I will try to make it better.

The hardest part is always to find some data to play with and this time I've found an interesting dataset about the interactions between the characters in the movie Star Wars Episode I.

So I gave it a try and here are some results by using my new arcchart:





As you can see there are different options one can enable/disable in this chart.

Each connection between two items can have a value which can be used to weight the connection (wider strokes mean bigger values => stronger connection). One could also weight the dots of each item by the sum of their connection values. If you click on an item it will highlight all it's connections.

In the last image you see that you can also make use of the full circle for connections. In this case you read the chart clockwise, meaning to say outgoing connections to the right will be in the upper part and outgoing connections to the left will be in the lower part.

The items are sorted by the sum of their connection values from left to right. As you can see in the image above, Anakin has the most interactions in Episode I, followed by Jar Jar and Qui Gon.

The most interesting part is that creating the whole new chart took not longer than 3-4h last night which again shows how productive you can be by using JavaFX...love it :)

In addition one could also create a cluster to group items. For this I've simply created another chart without any meaning just to show the clustering. So in this case the clusters are europe and asia. The items in each cluster are sorted by the sum of their connection values from left to right.


If you have clustered items all connections from the cluster will get the color of the cluster. A cluster will be created as follows:

Cluster europe = new Cluster("Europe", Color.BLUE, germany, france, italy, spain);

Where germany, france, italy and spain are PlotItems that can be created as follows:

PlotItem germany = new PlotItem("GERMANY", 1_250_000, Color.RED);

The connections between the items can be created as follows:

germany.addToOutgoing(india, 150_000);

If you would like to highlight a specific connection you can get it as follows:

arcChart.getConnection(germany, india).setFill(Color.GREEN);

Oh and the new ArcChart is part of the last release of my charts library which you can find at:

So that's it for today...enjoy the upcoming weekend and...keep coding...


Thursday, June 11, 2020

TouchSlider control

Aloha,

Yesterday evening and this morning I've spent some time on creating a new control...a touch slider. To be honest I can't remember why I had the idea to create one but who cares...now it's ready :)
So here is a screenshot of it...


So it's not really fancy but it works and is customizable in many ways. So first of all one can set the orientation to either horizontal or vertical. 
You can set a name and you can also define if that name should be visible or not. In addition you can define if the current value should be visible or not.
The color of the bar background, the bar itself, the thumb, the value text, the name text and the zero indicator are also adjustable.
This control is based on the JavaFX Canvas node which means it does not use a lot of nodes. But even if it is based on the Canvas node it is still styleable by CSS. If you take a look at the Demo class in the github repo you will figure out that the black and blue sliders are styled using code but the red slider on the right side ist styled using CSS.
This works because JavaFX offers so called StyleableProperties which bridge the gap between code and CSS.
The plan is to use this slider in a specific Tile for TilesFX for control e.g. IoT projects.
Here is a little video of the slider in action...


In addition to the above mentioned features you can also define if the bar should start at the zero position, this might come in handy if you have to control values that go from a negative to a positive value.
In this control I've used a little bit different approach to set the min and max values. Here you can define the min value and the range. The value property of the slider will always be in the range from 0 - 1 but if you call the getSliderValue you will get the "real" value based on the min value and the range back.
The slider will fire TouchSliderEvents when you drag it so that you can attach an observer to it and react on the events.
Well that's in principle it and as always you can find the code at github...

That's it for today...so keep coding...

Friday, June 5, 2020

And another one...TilesFX 11.38

Aloha,

Here we go again...the last couple of evenings/nights I've spend creating new skins for TilesFX and because in the meantime I have 4 new skins it's time for another release of TilesFX :)

So let's take a look at the new skins that I have added.

ColorTileSkin
This skin always visualizes the current value in percentage and the background color will change according to the value.
The different colors that will be used are predefined by using sections.
The default sections that will be used if nothing else is defined are:
new Section(0.00, 0.25, ColorSkin.GREEN),
new Section(0.25, 0.50, ColorSkin.YELLOW),
new Section(0.50, 0.75, ColorSkin.ORANGE),
new Section(0.75, 1.00, ColorSkin.RED)
With this sections in place the color will for example be orange if the value is between 50% and 75% of the range that is defined by minValue and maxValue of the tile.
Of course you can override the sections with your own sections but keep in mind that the values of the sections should be in the range of 0.0 to 1.0 as shown in the example above.
That's fine but sometimes you would prefer having more finegrained colors for the values. One solution would be to define lot's of sections but you could also make use of the gradientStops feature in TilesFX.
For this you simply define the color stops you would like to use for the interpolation as follows in the TileBuilder:

tile1 = TileBuilder.create().skinType(SkinType.COLOR)
.prefSize(WIDTH, HEIGHT)
.title("Color (Sections)")
.description("CPU temp")
.text("Text")
.unit("\u0025C")
.animated(true)
.build();

tile2 = TileBuilder.create().skinType(SkinType.COLOR)
.prefSize(WIDTH, HEIGHT)
.title("Color (Gradient)")
.description("CPU temp")
.text("Text")
.unit("\u0025C")
.animated(true)
.gradientStops(new Stop(0.0, Medium.GREEN),
new Stop(0.2, Medium.GREEN_YELLOW),
new Stop(0.4, Medium.YELLOW_ORANGE),
new Stop(0.6, Medium.ORANGE),
new Stop(0.8, Medium.ORANGE_RED),
new Stop(1.0, Medium.RED))
.fillWithGradient(true)
.build();
In principle it would also have been enough to define the 0.0, 0.5 and 1.0 values with for example green, yellow and red to get a similar result.
Long story short, here is a little video of the result where the section approach is on the left side and the gradient approach on the right side:



TurnoverTileSkin
The next new skin that I have added is the TurnoverTileSkin. This skin can be used to show an image with a value and a text and visualize a ranking and a special effect if the given threshold was reached.
The effect I'm talking about is the RotationEffect that I also have added to the library. To make use of the ranking you have to use the Rank class to define the ranks you need.
As an example let's define the ranks, first, second and third as follows:
Rank first  = new Rank(Ranking.FIRST, Color.GOLD);
Rank second = new Rank(Ranking.SECOND, Color.SILVER);
Rank third = new Rank(Ranking.THIRD, Color.web("#cd7f32"));
So each rank has a ranking (the Ranking enum goes from first to tenth) and with a color.
In the following little video I created 5 tiles for some persons and put them in an HBox container. As you will see in the video the ranking changes and will be visualized when the values change. 
In addition you will see the rotation effect kick in as soon as one of the person value reaches the threshold of 500. So here is the video to give you an idea...


Here is some code that gives you an idea how I handle the ranking in the video above.
private Tile createPersonTile(final String title, final String name, final Image image) {
return TileBuilder.create()
.skinType(SkinType.TURNOVER)
.prefSize(300, 300)
.title(title)
.unit("$")
.image(image)
.text(name)
.maxValue(2000)
.threshold(500) // Will trigger the rotationEffect when reached
.animated(true)
.build();
}

private void checkHighscores(final List<Tile> persons) {
List<Tile> sorted = persons.stream()
.sorted(Comparator.comparingDouble(Tile::getValue).reversed())
.collect(Collectors.toList());
sorted.get(0).setRank(first);
sorted.get(0).setValueColor(first.getColor());
sorted.get(0).setUnitColor(first.getColor());

sorted.get(1).setRank(second);
sorted.get(1).setValueColor(second.getColor());
sorted.get(1).setUnitColor(second.getColor());

sorted.get(2).setRank(third);
sorted.get(2).setValueColor(third.getColor());
sorted.get(2).setUnitColor(third.getColor());

for (int i = 3 ; i < sorted.size() ; i++) {
sorted.get(i).setRank(Rank.DEFAULT);
sorted.get(i).setValueColor(Tile.FOREGROUND);
sorted.get(i).setUnitColor(Tile.FOREGROUND);
}
}
The createPersonTile method is used to create the tile for each person and the checkHighscores method is always called after the values have been set.

FluidTileSkin
The next new skin that was added is the FluidTileSkin. This skin shows the current value and visualizes it by filling the background of the tile with a fluid like effect.
The code that is used in the following video looks as follows:

tile = TileBuilder.create().skinType(SkinType.FLUID)
.prefSize(WIDTH, HEIGHT)
.title("Fluid")
.text("Waterlevel")
.unit("\u0025")
.decimals(0)
.barColor(Tile.BLUE) // defines the fluid color
.animated(true)
.build();

If you would like to see a more colorful fluid you can make use of sections or the gradientStops like shown above in the ColorTileSkin example.
Here is how it looks like in action...



FireSmokeTileSkin
The last skin I have added is the FireSmokeTileSkin. Well this is another fun skin to visualize the point where the value exceeds the defined threshold.
As you might guess by the name the preferred usage for this skin might be visualizing a temperature value. 
The code used for the next video looks as follows...
tile = TileBuilder.create().skinType(SkinType.FLUID)
.prefSize(WIDTH, HEIGHT)
.title("Fire Smoke")
.text("CPU temp")
.unit("\u00b0C")
.threshold(70) // triggers the fire and smoke effect
.decimals(0)
.animated(true)
.build();
The best way to describe this skin is to see it in action...so here you go...


As you can see the fire and smoke starts when the value exceeds the threshold of 70 and stops when the value falls back below 70.

Well that was a lot of new stuff and as always you can find the latest version of TilesFX at




That's it for today...so keep coding and stay healthy...

Tuesday, June 2, 2020

Touch me...

Aloha,

Last weekend I've spend a lot of time in front of the TV to follow the flight of SpaceX Crew Dragon to the International Space Station.
It's great to see that finally a commercial company is able to send people to the lower orbit and to the ISS.
When I saw the touch user interface of the Crew Dragon I've got the idea to create a little touch joystick control in JavaFX.
I've did not spend a lot of time to think through the functionality so there is as always room for improvement :)
So I took my standard approach, first draw the control in a vector program which looked like this:


As you can see it's not a hyper fancy control but it should be useful first :)
The idea was to have a touch point that can be dragged around. A little ring outside that indicates that you touched the control (because your finger might block your view on the touch point itself).
8 buttons around the control that can be used to make small adjustments with given directions.
I've also added an indicator made out of chevron shapes. The more you drag the point to one direction the longer the bar of chevrons will get. First I thought to let it go from the center of the control to the touch point but if you use your finger to drag the point, your hand might block your view and so I've decided to put the chevron bar on the opposite side of the touch point to make it as visible as possible.
I've created a little video that shows how the control works...


As always you can find the code over at github...

If you would like to start the demo you just have to make sure you are on Java 11 and then you can execute gradle Demo on the console.

That's it for today...so keep coding...

Friday, May 29, 2020

TilesFX 11.37

Aloha,

Time for some new stuff...
Last weekend I've stumbled upon some dashboards that had some interesting visualizations. The first one was a visualization of sales cycle steps that looked as follows:


The interesting part here for me is the chart where each bar starts where the last bar ended. I took a look at TilesFX but did not found something that made stuff like this possible in an easy way. So I decided to add a new skin that I called CycleStepTileskin (I know I'm not good in naming things). Here is how it looks like:


To be honest I'm not sure if this is useful but you never know right :)

The other tile I've found was nothing really special but I realized it has something that I missed in TilesFX...flags. This is what I'm talking about...


Not everyone needs flags but sometimes they come in really handy and so I was looking for flag images that I could use. Lucky me I've found free flags over at flaticon and added them to TilesFX. I've added them as enum and control.
So if you need an icon image you can now simply do something like follows:

ImageView flagImage = new ImageView(Flag.GERMANY.getImage(48));

The Flag enum has two methods to get an image, the standard getImage() method always returns a flag image with the size of 30x30 px. If you need a different size you can simply call the getImage(SIZE) method to get the flag in the size you want it.
The flag images are always square!
The other class I've added is called FlagIcon which is more or less a wrapper around an ImageView of the given image. Meaning to say it behaves like a control, so it will be resized automatically BUT it will resize the image based on the given flagSize. So if you have a flag of size 48 px and you increase the size of the FlagIcon it will get pixelated.
So if you would like to avoid pixelation you need to set the FlagSize to a bigger value but that will also increase memory consumption...so it's up to you.
In the end the FlagIcon is just a convenience class that comes in handy if you simply need a flag somewhere. You can use it as follows:

FlagIcon flagIcon = new FlagIcon(Flag.SINGAPORE, 24);

This will give you a control that shows a flag that is based on an image with 24px.

As an example of what you can do with that I've simply added a tile that shows the Covid-19 cases of some countries based on data from Mai 26th 2020. For this tile I simply used the custom tile skin and added a VBox with some HBoxes. If you are interested in how I did that, please take a look at the Demo class in the TilesFX project.



Here is a little bigger screenshot of it...


That's it for today so as always you can find the code over at github and the binary either at bintray or at maven central.

That's it for today...so keep coding and stay healthy...

Sunday, May 17, 2020

MatrixIcon Tile Skin

Aloha,

This morning when I took a shower I got the idea that it might be nice to have some kind of animated icons in TilesFX. I own two lametric clocks and on this clocks you have the ability to have an icon and a text. They provide the ability to animate the icon by simply having multiple 8x8 pixel images that will shown in an animation.
So why not having such a feature in TilesFX?

Well just tooks a bit more than 1h to implement it and here is the result...



If you take a look at the Demo class in the TilesFX sources you can see how this was done.

As always you can find the latest version (11.35) over at

github

bintray

maven central

That's it for today...so keep coding...

Friday, May 15, 2020

TilesFX update

Aloha,

You might have heard that Darksky has joined Apple. Well I used the darksky weather api for the WeatherTileSkin and therefor had a dependency to the json-simple library to be able to parse the json data from darksky correctly. I never was a big fan of having TilesFX depending on other libraries and 2 weeks ago there was an issue on github where someone asked to remove the dependency because of jlink problems.
Well after Darksky moved to Apple and won't probably be available in the future any more I've decided to remove the WeatherTileSkin and the Darksky objects from the library.
So from version 11.33 you won't find the WeatherTileSkin any longer in TilesFX but I've created an addon library called tilesfxweather which will make it possible to continue using the WeatherTileSkin as a custom skin in combination with the Darksky api.
If you take a look at the Demo class in the tilesfxweather project you will see how to use the WeatherTileSkin. Because Darksky might go away I've also removed the dependencies from the skin to the Darksky object so that you now only have to provide a DataPoint object that could contain data from where ever you want. But as I mentioned everything is in the Demo class of the tilesfxweather project.
In addition to the above things the new release also contains some bugfixes and a new property called fixedYScale which will be used in the SparkLineTileSkin when set to true.
The y-axis in the SparkLineTileSkin will usually automatically be adjusted to the min- and maxMeasured values of the current view but if fixedYScale=true the y-axis will always be based on the min- and maxValue from the tile.

Oh and you can find both libraries on maven central:

TilesFX

TilesFXWeather

Well in principle that's it for now...so stay healthy and...keep coding...