B4J Library jCharts

Discussion in 'B4J Libraries & Classes' started by Informatix, Oct 13, 2016.

  1. Informatix

    Informatix Expert Licensed User

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

    Attached Files:

    Last edited: Nov 30, 2016
  2. Harris

    Harris Well-Known Member Licensed User

    Sweet....

    Can you make this work with ABMaterial? ()wrapper, plugin, etc)..

    I am using the Chartist lib with ABM but it is not giving the results I need.
    Particularly, the X axis labels don't (can't) show the date/times that need to be displayed so one has a reference to the x grid. And if it did, it is not rotated to 90 degrees where it wont overlap the next label.

    My data shows second by second the activity for a period (hour, 4 hours, 12 hours or 24 hours). Granted, this is a huge amount of data to stuff in a line graph (each hour is (60*60 data points)).

    The y axis is fine (speed in MPH), the x axis doesn't show the (date/time - rotated 90 degrees - left or right) to tell the time of day this data point occurred. They are simply (i incs) for each data point accumulated - with no reference to date/time.

    Thanks



    chart1.jpg
     
    jinyistudio likes this.
  3. Informatix

    Informatix Expert Licensed User

    I don't know ABMaterial yet and I create only libraries that I need so...
    Moreover Chartist is a Javascript lib, so if ABMaterial expects something in Javascript, what you ask will never happen.
     
    Peter Simpson likes this.
  4. alwaysbusy

    alwaysbusy Well-Known Member Licensed User

    Yes, this is the case. However, if your lib can output to an image, it could be useful for static charts in ABMaterial (using an ABMImage).
     
  5. Informatix

    Informatix Expert Licensed User

    Unfortunately, the Snapshot feature does not grab the whole chart (axis and plotted data are missing). I didn't look yet at what that function does exactly so it's maybe possible to improve it.
     
  6. Informatix

    Informatix Expert Licensed User

    Problem solved. Fixed for the next version.
     
    Peter Simpson, Harris and alwaysbusy like this.
  7. Informatix

    Informatix Expert Licensed User

    Finally, I removed my solution for snapshots in the new version because it didn't work in a particular case. So my solution for snapshots is just an advice:
    To take a snapshot of a chart, set its animated property to False before adding the data or wait until all animations are over.
     
  8. Harris

    Harris Well-Known Member Licensed User

    I like your example 3 - and all of jChart.

    Is it possible to zoom in on the entire data - to show a selected section within the subset?

    Your example shows the slider growing from small to all. When all, I would like to "rubber band" a section (to zoom in) and show it within screen width.
    This would, for example, show when Y (speed in MPH) was greater than company limits (for how long and how high).

    Hope you get my meaning.

    Thanks
     
  9. Informatix

    Informatix Expert Licensed User

    I modified a little bit my example Chart3 so the slider now sets the zoom factor. Use the MouseDragged event to select the data to zoom in on and create the series to draw from the full series like I do in sldLimitX_ValueChange, but with two boundaries (If XY.X >= value_drag_begin and XY.X <= value_drag_end Then).
     

    Attached Files:

    fredo likes this.
  10. Harris

    Harris Well-Known Member Licensed User

    Going good so far...

    Following your new EX 3 sample. Learning plenty... Got Zooming in and out of FullSeries cased (however a learning curve for sure - using pressed and released since no drag events would expose down / up??).

    When form is first presented, it is sized per primary screen. When I drag to second screen, which is much larger, I click the button "Fit Graph to Screen" - which expands the graph to width and height of new screen - nice...

    Been struggling with this: How to convert X (Time values - long) to DateTime.Date & Time to show as labels (as string) rotated to 90 degrees.
    There must be a way... Need code? Can supply...

    EDIT:

    Actually, there are two ways to accomplish this question above. Use Dim XAxisL As CategoryAxis or

    Code:
    'LINE CHART
        Dim XAxisL As NumberAxis
        XAxisL.Initialize(
    "XAxisL")
        XAxisL.Label = 
    "Time"
        XAxisL.AutoRanging = 
    True
        XAxisL.ForceZeroInRange = 
    False
        XAxisL.TickLabelRotation = 
    90
        XAxisL.TickMarkVisible = 
    False
        XAxisL.TickLength = 
    5


    ' This converts the number to a time string!
    Sub XAxisL_ToString(Number As Object) As String
        
    Dim LngNbr As Long = Number
        
    Return DateTime.Time(LngNbr)
    End Sub
    With some CSS, and much more learning, I can make this presentable - rather than basic desktop drab... (examined some posts already)
    Like a friend use to say, "Make it work, you can always make it pretty later"...

    Thanks
     

    Attached Files:

    Last edited: Oct 27, 2016
    Johan Hormaza and ilan like this.
  11. Harris

    Harris Well-Known Member Licensed User

    Now closer with styling...
    The following code styles the X axis... How to style the Y?

    I have referred to:
    https://docs.oracle.com/javafx/2/charts/css-styles.htm

    for styling advice, but they only go so far...

    Is there a doc which shows all the styling that can be performed?

    Each of the 11 (pages), for the day selected in the table, will plot an hours worth of data (for each second of the hour).
    I tried to load the entire day (35000 points in many cases), but it took over 10 minutes to load.
    This works well - loading a smaller subset. One can zoom in on any plot, down to the second. Sweet!!!

    Thanks


    Code:
    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)

        
    Dim FirstLineStyle As Map = LineChart.GetChildStyleMap(".axis")
        FirstLineStyle.Put(
    "-fx-font-size""20px" )
        FirstLineStyle.Put(
    "-fx-tick-length""15" )
        FirstLineStyle.Put(
    "-fx-tick-label-fill""blue" )
        FirstLineStyle.Put(
    "-fx-tick-label-font-size""1.2em" )
        FirstLineStyle.Put(
    "-fx-font-family""Tahoma" )
        FirstLineStyle.Put(
    "-fx-minor-tick-length""10" )
        LineChart.SetChildStyleMap(
    ".axis", FirstLineStyle)


        
    Dim FirstLineStyle As Map = LineChart.GetChildStyleMap(".axis-tick-mark")
        FirstLineStyle.Put(
    "-fx-stroke","black")
        FirstLineStyle.Put(
    "-fx-stroke-width","2")
        LineChart.SetChildStyleMap(
    ".axis-tick-mark", FirstLineStyle)


        
    Dim FirstLineStyle As Map = LineChart.GetChildStyleMap(".axis-minor-tick-mark")
        FirstLineStyle.Put(
    "-fx-stroke","black")
        FirstLineStyle.Put(
    "-fx-stroke-width","1")
        LineChart.SetChildStyleMap(
    ".axis-minor-tick-mark", FirstLineStyle)

    jchart1.jpg
     
    Last edited: Oct 30, 2016
  12. Harris

    Harris Well-Known Member Licensed User

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

    Note: I can't image what I would have to learn in order to do this with Google Charts - in JavaScript! I know it can, but it is well beyond my abilities. Need wrapper in ABM for Google charts - so THIS stuff can be accomplished (OR wrap jCharts).

    jchart1_zoom.jpg

    jchart1_zoomed_in.jpg
     
    Last edited: Oct 30, 2016
    raphaelcno likes this.
  13. Informatix

    Informatix Expert Licensed User

    Please note that some settings can be done via the class properties (Axis.TickLabelFont, Axis.MinorTickLength, etc.).
    All CSS settings can be found here: https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html#charts
     
    Harris likes this.
  14. rbghongade

    rbghongade Active Member Licensed User

    Dear Informatix,
    Does this library support real-time plotting? If so how can this be done?
     
  15. Informatix

    Informatix Expert Licensed User

    Yes, just add your data to the graph when they are available. Set Animated to false for the chart or it will perform an animation for each new data.
     
    rbghongade likes this.
  16. Informatix

    Informatix Expert Licensed User

    I just realized that the file for the new version of jCharts does not contain the version 1.0 of the library but a draft of this library, so the examples do not work. I will include the right files and re-publish the version 1.0 as soon as I'm at home in a few hours.
     
  17. dk9uv

    dk9uv Member Licensed User

    Hi Harris,

    I am struggling with your example to show nicely formatted time labels at the x axis instead of plain numbers. Could you please give me a more detailed explanation?

    Thanks very much

    Chris
     
  18. Harris

    Harris Well-Known Member Licensed User

    It is shown in post 10 above.

    Dim XAxisL As NumberAxis '(uses number values)


    - add this to your code....
    ' This converts the number to a time string!
    ' XAxisL.Initialize("XAxisL") - param defines the event name

    Sub XAxisL_ToString(Number As Object) AsString
    Dim LngNbr As Long = Number
    Return DateTime.Time(LngNbr)
    End Sub

    Add long values to the X list - the event above will convert it to a time string (XAxisL_ToString)
    Dim dt As Long
    dt = mp.Get("1") ' 1 = datetime for X axis
    rngdate.Add(dt) ' add it to list


    The axis font size, color and tick marks are in post 11.

    There is an example of formatting numbers in the Chart2 example. That is where I discovered it.
     
    Last edited: Nov 8, 2016
    Informatix likes this.
  19. dk9uv

    dk9uv Member Licensed User


    Hi Harris,

    great, I forgot the initialization with the event name prefix. No it works prefectly.

    Thanks
    Chris
     
    Harris likes this.
  20. dk9uv

    dk9uv Member Licensed User

    Another question about formatting axes:

    There are 3 possibilities (example):

    a.) XAxisL.TickLabelFont=fx.DefaultFont(20) but not all properties available

    b.) CSSUtils.SetStyleProperty(XAxisL,"-fx-tick-label-font-size","20px")

    c.) Dim FirstLineStyle As Map = LineChartSensorData.GetChildStyleMap(".axis")
    FirstLineStyle.Put("-fx-tick-label-font-size", "20px" )
    LineChartSensorData.SetChildStyleMap(".axis", FirstLineStyle)

    I wonder how to access some styles of the YAxisL (child axis-tick-mark)
    e.g. axis-tick-mark fx-stroke-width

    (XAxisL works see post #11, but how to access the YAxisL?)
     
Loading...