B4J Library jCharts

Here's my first library for B4J. It's a wrapper of javafx.scene.chart with additional functions and classes.

jCharts.jpg
chart2.jpg


To take a snapshot of a chart, set its animated property to False before adding the data or wait until all animations are over.

Changelog:
v1.21:
- I added a workaround for a bug in OpenJDK 11 (thanks to Chris2)

v1.2:
- XAxis and YAxis created by the designer can now raise events with the default event prefix "XAxis" / "YAxis";
- I added the LegendChanged event to all charts;
- I fixed a bug (NullPointerException) in GetChildStyleMap and StyleMap.

v1.11:
- I added the SetChildStyleMap2 function;
- I modified the fourth demo to show a simple way to add the colored bands.

v1.1:
- I added the Plot event to all charts except PieChart;
- I added a demo to show how to use the Plot event (this project requires jGraphicLib);
- I modified the third demo to use a layout made with the designer.

v1.0:
- All charts can be added as custom views in the visual designer;
- I added the Width and Height properties to all charts and axis;
- I added the Series property to XYCoord;
- I added the MouseToData function to all charts and removed the EventPrefixForPlot parameter from Initialize (MouseToData is more convenient than events);
- I modified the second demo to show MouseToData in use;
- I modified the third demo so that the slider value sets the upper bound of the displayed series.

v0.9:
- I added ForceZeroInRange and TickUnit to NumberAxis;
- I added RemoveAllData to PieChart;
- I added FindNearestX to XYSeries;
- I added FindSeries and RemoveAllSeries to all charts using series;
- I added Padding to all charts;
- I added a new example and some documentation.
 

Attachments

  • jCharts_1_21.zip
    74.1 KB · Views: 661
Last edited:

Harris

Expert
Licensed User
Longtime User
Harris

Would you be willing to share some code snippets of how you implemented your -

Zoom and Zoomed in feature... Drag to zoom (left to right - creates visual canvas rect), let go and magic. How nice!
To un-zoom (restore the original view) - drag from right to left...

Thanks

Don
Sure!

If I can dig up this code... I vaguely remember working on this... Yet I saw this 2 months ago while browsing old projects...

This was a test project and then moved to ABMaterial to accomplish the same - and more.

Maybe jog my memory what I was referring to - help me along finding it...

Thanks
 

Don Cameron

New Member
Licensed User
Sure!

If I can dig up this code... I vaguely remember working on this... Yet I saw this 2 months ago while browsing old projects...

This was a test project and then moved to ABMaterial to accomplish the same - and more.

Maybe jog my memory what I was referring to - help me along finding it...

Thanks

Hi Harris

Thanks for your reply.
This is the link to the thread where you were talking to the author (Informatix) of the jCharts library.
https://www.b4x.com/android/forum/threads/jcharts.71975/
This is the image you posted showing your app with the zooming functions.
I am struggling (new to B4J) with the event handling for the zoom rectangle and then redraw at the zoomed scale. Any code snippets on this aspect would be appreciated. I am not up to exploring ABMaterial yet - thought I would start off with some simpler stuff !
Thanks
Don
 

Attachments

  • jchart1_zoom.jpg
    jchart1_zoom.jpg
    213.4 KB · Views: 411

Harris

Expert
Licensed User
Longtime User
Here is the test project. Hope you can find something in it.
For the life of me, I can't find how zooming actually worked in it... It won't even compile on my own machine now...
Setting it all up was quite complex - spent many days making it and to do pagination.

Actually, in ABM, I had to use Google Charts (implementing a custom component) since nothing else worked like I needed it for.

(new to B4J)
I have worked with B4A successfully for many years. I took a stab at pure java and was dismayed (what the heck is a JAR file?).
Then, out of necessity, I took a look at B4J and was amazed and hooked. The B4X suite is truly amazing! With thanks to all these people who support it with great libs and classes we can modify to our own specific needs.
 

Attachments

  • linechart.zip
    36.4 KB · Views: 473

Don Cameron

New Member
Licensed User
Here is the test project. Hope you can find something in it.
For the life of me, I can't find how zooming actually worked in it... It won't even compile on my own machine now...
Setting it all up was quite complex - spent many days making it and to do pagination.

Actually, in ABM, I had to use Google Charts (implementing a custom component) since nothing else worked like I needed it for.


I have worked with B4A successfully for many years. I took a stab at pure java and was dismayed (what the heck is a JAR file?).
Then, out of necessity, I took a look at B4J and was amazed and hooked. The B4X suite is truly amazing! With thanks to all these people who support it with great libs and classes we can modify to our own specific needs.

Harris

Thanks very much for sharing your code. It was most helpful for me in understanding mouse event handling better and now I should be able to apply zooming to charts.
Thanks again
Don
 

Orejana

Member
I wonder if you can tell me how did you manage to make Mouse Moved event with Time as we can see it on picture in post #10? It has to be a number on X axis. Did you convert time to number or did u used some other method?

I have the exact same question - can someone help please? :)
 

Orejana

Member
For the first series:
BarChart.GetChildStyleMap(".default-color0.chart-bar")

For the second series:
BarChart.GetChildStyleMap(".default-color1.chart-bar")

To set the color:
StyleMap.Put("-fx-bar-fill", MyColor)

I can't seem to figure out how to change the colour. I've tried all the code in this post, but it keeps telling me that Object should first be initialized (Map).
My code is as follows: (I'm trying to change the colour of Series3)

B4X:
Dim Color3 As Map
   Color3.Initialize
   Color3=BarChart.GetChildStyleMap(".default-color2.chart-bar")
   Color3.Put("-fx-bar-fill","blue")
   BarChart.SetChildStyleMap(".default-color2.chart-bar",Color3)

The same problem occurs when I try to change the color of my LineChart:
B4X:
Dim FirstLineStyle As Map = LineChart.GetChildStyleMap(".default-color0.chart-series-line")
   FirstLineStyle.Put("-fx-stroke", "black")
   FirstLineStyle.Put("-fx-stroke-width", "1px")
   LineChart.SetChildStyleMap(".default-color0.chart-series-line", FirstLineStyle)
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
I can't seem to figure out how to change the colour. I've tried all the code in this post, but it keeps telling me that Object should first be initialized (Map).
My code is as follows: (I'm trying to change the colour of Series3)

B4X:
Dim Color3 As Map
   Color3.Initialize
   Color3=BarChart.GetChildStyleMap(".default-color2.chart-bar")
   Color3.Put("-fx-bar-fill","blue")
   BarChart.SetChildStyleMap(".default-color2.chart-bar",Color3)

The same problem occurs when I try to change the color of my LineChart:
B4X:
Dim FirstLineStyle As Map = LineChart.GetChildStyleMap(".default-color0.chart-series-line")
   FirstLineStyle.Put("-fx-stroke", "black")
   FirstLineStyle.Put("-fx-stroke-width", "1px")
   LineChart.SetChildStyleMap(".default-color0.chart-series-line", FirstLineStyle)
Did you try the examples? Did you encounter an error?
 

Orejana

Member
Did you try the examples? Did you encounter an error?

Thanks for your reply! :)
The Charts.b4j works fine. The rest doesn't seem to have stuff related to colors in it, or did I miss it?
Is something wrong with my "-fx-bar-fill" or "-fx-stroke"? These are the lines it marks me as wrong. (the first code part is for a barchart btw, the second for a linechart)
 

Informatix

Expert
Licensed User
Longtime User
B4X:
Dim Color3 As Map
   Color3.Initialize
   Color3=BarChart.GetChildStyleMap(".default-color2.chart-bar")
   Color3.Put("-fx-bar-fill","blue")
   BarChart.SetChildStyleMap(".default-color2.chart-bar",Color3)
This code should work fine ONLY if there's at least three series in your chart and these series are loaded before changing the color.
Add this example to the Charts demo to colour the bar of the second series:
B4X:
    Dim Color2 As Map
    Color2=BarChart.GetChildStyleMap(".default-color1.chart-bar")
    Color2.Put("-fx-bar-fill","blue")
    BarChart.SetChildStyleMap(".default-color1.chart-bar",Color2)


B4X:
Dim FirstLineStyle As Map = LineChart.GetChildStyleMap(".default-color0.chart-series-line")
   FirstLineStyle.Put("-fx-stroke", "black")
   FirstLineStyle.Put("-fx-stroke-width", "1px")
   LineChart.SetChildStyleMap(".default-color0.chart-series-line", FirstLineStyle)
This code works fine as is.
 

Orejana

Member
This code should work fine ONLY if there's at least three series in your chart and these series are loaded before changing the color.
Add this example to the Charts demo to colour the bar of the second series:

I put it after BarChart.AddAllSeries and now it doesn't crash (progress :D), but it only colors the bar on the very left, not the rest of the series? (the color of the square next to the name of the Series hasn't changed color, either). It's the same for both diagrams.

EDIT: the linechart-line stays blue, but the color of the square next to its name is still red...
 

Informatix

Expert
Licensed User
Longtime User
(the color of the square next to the name of the Series hasn't changed color, either). It's the same for both diagrams.
EDIT: the linechart-line stays blue, but the color of the square next to its name is still red...
The color of the legend is a distinct color. You have to change it once the chart is displayed with the LegendChanged event, eg:
B4X:
Private Sub Chart_LegendChanged(Index As Int, Legend As String)
    Dim StyleMap As Map = Chart.GetChildStyleMap(".default-color0.chart-legend-item-symbol")
    If StyleMap.IsInitialized Then
        StyleMap.Put("-fx-background-color", "#998888")
        Chart.SetChildStyleMap(".default-color0.chart-legend-item-symbol", StyleMap)
    End If
End Sub
 

Orejana

Member
Use SetChildStyleMap2 instead of SetChildStyleMap.
This worked perfectly, thanks a lot!

The color of the legend is a distinct color. You have to change it once the chart is displayed with the LegendChanged event, eg:
B4X:
Private Sub Chart_LegendChanged(Index As Int, Legend As String)
    Dim StyleMap As Map = Chart.GetChildStyleMap(".default-color0.chart-legend-item-symbol")
    If StyleMap.IsInitialized Then
        StyleMap.Put("-fx-background-color", "#998888")
        Chart.SetChildStyleMap(".default-color0.chart-legend-item-symbol", StyleMap)
    End If
End Sub

So for the BarChart, the code would be the following? It's not doing anything at the moment - the map is not initialized...
B4X:
Dim StyleMap As Map = BarChart.GetChildStyleMap(".default-color2.chart-bar-legend-item-symbol")
 

Orejana

Member
The code should be the one I gave to you. Just change the color and the name of the chart.
B4X:
Sub Chart_History
   XAxisBC.Initialize("")
   XAxisBC.Label = "Tag"
   YAxisBC.Initialize("")
   YAxisBC.AutoRanging = True
   
   BarChart.Initialize(XAxisBC, YAxisBC, "BC")
   lblHeaderDia.Text="Letzte Woche"
   BarChart.VerticalGridLinesVisible = False
   BarChart.BarGap = 1
   BarChart.CategoryGap = 4
   BarChart.Animated=False

   MainForm.RootPane.AddNode(BarChart, 60, 545, 1370, 430)
'   BarChart_LegendChanged(2,"Max. Bodenfeuchtigkeit in g/m³")
   
   Series3.Initialize("Max. Temperatur in °C")
   Series4.Initialize("Min. Temperatur in °C")
   Series5.Initialize("Max. Bodenfeuchtigkeit in g/m³")

'   BarChart_LegendChanged(2,"Max. Bodenfeuchtigkeit in g/m³")
   
   DatetoGraph(7,table_max,Series3)
   DatetoGraph(7,table_min,Series4) 
   DatetoGraph(7,table_moist,Series5)
   
   BarChart.AddAllSeries(Array As XYSeries(Series3, Series4, Series5))
'   BarChart_LegendChanged(2,"Max. Bodenfeuchtigkeit in g/m³")

   Dim Color2 As Map
   Color2=BarChart.GetChildStyleMap(".default-color2.chart-bar")
   Color2.Put("-fx-bar-fill","#2E64FE")
   BarChart.SetChildStyleMap2(".default-color2.chart-bar",Color2)
'   BarChart_LegendChanged(2,"Max. Bodenfeuchtigkeit in g/m³")
End Sub

Private Sub BarChart_LegendChanged(Index As Int, Legend As String)
   Dim StyleMap As Map = BarChart.GetChildStyleMap(".default-color2.chart-legend-item-symbol")
   If StyleMap.IsInitialized Then
       StyleMap.Put("-fx-background-color", "#2E64FE")
       BarChart.SetChildStyleMap(".default-color2.chart-legend-item-symbol", StyleMap)
   End If
End Sub

I've tried calling the sub in several places, see code above, but StyleMap.IsInitialized never returns true... I don't know what I'm doing wrong :-(
 

Orejana

Member
Oh, I found my mistake! :) I had to change BarChart_LegendChanged to BC_LegendChanged, as this is my EventPrefix. Now it works perfectly, thank you so much for all the help! :)
 

Informatix

Expert
Licensed User
Longtime User
Can anyone help with this issue - https://www.b4x.com/android/forum/t...negative-values-on-stacked-bar-chart.106276/?

In short, I'm having problems getting jCharts Stacked Bar Chart to display negative values when using Open Java 11. It works OK with Java 8.
I don't have Open Java 11 on my PC but I doubt that the problem is due to my wrapper. It's a thin wrapper around the Java classes and it's almost identical for each graph type. So, if it works for bar charts, it should work also for stacked bar charts.
 

Chris2

Active Member
Licensed User
OK, many thanks Informatix.
Negative values seem to show up fine on all the other charts including the bar chart, the problem only seems to be present on the stacked bar.
I'll keep digging to see what I can find.

Thanks for all your work on this library as well!
 

h.drose

Member
Hi,

Why mi AreaChart is crooping the stroke?

1642481635632.png


As you can see the YSerie its not increasing wit the data value proived, please any body help me.
 
Top