hansolo / charts Goto Github PK
View Code? Open in Web Editor NEWA JavaFX library that contains different kind of charts
License: Apache License 2.0
A JavaFX library that contains different kind of charts
License: Apache License 2.0
Hello Gerrit,
Is it possible to choose the color and/or the font for the description of the PlotItems in a Circular chart?
Here is an example:
I would like to choose color and font for the names (Australia, India, China, etc...) as well as for the Tick marks and Tick mark labels.
Is there currently a way to do this?
Great work guys, much appreciated. I was wondering if it would be possible to add a neat box-plot in this collection?
Here are a couple of examples from d3.js:
I think, similar to the first example, the ability to overlay all data points and then selecting and filtering some of these (e.g., outliers or from a certain quartile) would be amazing.
Hey Gerrit,
There doesn't seem to be any good LocalDate
and LocalDateTime
axis types. Would this be something that's in scope for this library?
I'm coming across this need a lot as I play with your charts and JavaFX charts in general.
Thomas Nield
Just a suggestion - maybe the use of the discussion forum will promote more interaction. I think enabling it requires minimum effort.
Hello, i'd like to check the dynamic data performance, so i tried to add values from the other class. Values were edit, but not shown, i suppose i need to call something like - updataDataset. Is it possible?
Occurs if there is only one node in the first-level (below root) whose value is != 0.
Effect: Segment missing (if interactive). Segment to big(if not interactive and no further child nodes != 0)
Currently, whole circles cannot be drawn because (in this instance) x2 and x3 are equal in createSegment
. I guess this happens because startAngleRad == 0
and endAngleRad == 2pi
, but sin(0) = 0 ==sin(2pi)
TreeNodeEvents
if the type is not SELECTED
tree.stream().forEach(tTreeNode -> tTreeNode.getItem().valueProperty().addListener((observable -> redraw())));
Hello Gerrit,
Thanks for all your work you put in your Liberies.
I would like to know if it's possible to set a different Color for the outgoings as for the PlotItems in the CircularPlot.
Hi To the HanSolo Charts Developers,
I am interested experiment with your library of plots the polar and the radar plots in particular. I am quite new to Java. I tried to best to update my Java development environment to OpenJDK16 with javaFX-sdk-16. Latest Eclipse Oomph and grade 7.1.1 to try to run the radar chart test application. I messed with with on the fly when running into problems and trying to solve it by googling.
Had spent ~1 day on it without any luck to get the test application working. I am at a point where at least entire project is imported into Eclipse and the the radar test application is no longer showing a bunch of red lines. When run, I encountered below error:
WARNING: Unknown module: charts specified to --patch-module
Error: Could not find or load main class eu.hansolo.fx.charts.RadarChartTest
Caused by: java.lang.ClassNotFoundException: eu.hansolo.fx.charts.RadarChartTest
Also tried googling for a solution but I got no where so far.
Your vast supported plots are so valuable for the scientific community. I am wondering if there is any documentation to guide one to at least get pass the setting up of development environment (the basic toolchain required to run/develop with your library) so one can develop their FX app to consume your library.
Any help would be greatly appreciated in this regards,
Thanks,
Hello :)
I rellay like the CoxCombChart, but i see no way of customizing it (or am i wrong?!).
Basically i´d like to change the MouseEvent from MOUSE_PRESSED to MOUSE_ENTERED.
I´d also like to add something to the "...%" text on the ChartItems and change the size and text
on the canvas showing after the MOUSE_PRESSED-Event.
Hello @HanSolo ,
I try to change the font for the axis but it's not working for the moment (I've tried through css).
.axis .yaxis {
-fx-font-family: "Arial";
-fx-font-size: 18px;
}
I could change the size with the setAutoFontSize(false)
and setTickLabelFontSize()
methods but I would like to change the font also.
Do you have a sample on how to change it for the axis on a simple XYChart ?
Thanks,
Gerald
Hi,
Thanks a lot for your contribution to charts with JavaFX. It would be great if boxplot is added to this repertoire (unless it is already there and I missed it somehow).
Regards,
gunjanthesystem
You are excellent. These charts are very beautiful, but I want to ask if it is possible to add a candle chart, which is the K-line chart of stocks. Thank you!
Hi,
I have added eu.hansolo.fx:charts:17.1.21 just a few days ago in my build.gradle and it worked fine. But when I'm checking maven now, there are no more versions 17.* available and the only one is 11.0? E.g. heatmap is still there in versions 17.0.
Maybe its just too late for me today...
Do you have any plans to create a Pareto Chart? This is a very common bar chart used in industry to plot the N largest items by count or percentage decreasing left to right. A line chart showing cumulative values is superimposed on the bar chart thus increasing left to right. Clicking on a bar provides an event for "drilling down" into more detail.
To customize color of heatmap it has property typed as ColorMapping
which represented by enum
. And it has only method which is getter for JavaFX Built-in javafx.scene.paint.LinearGradient
. So why can't you just use LinearGradient
-property to set colors in HeatMap
? Enums are final so that it is impossible to set custom ColorMapping
. Extracting an interface from ColorMapping
might be the solution which won't break existing code that much.
Same for AreaHeatMap
Hi there (again) :D
Thanks again for the quick implementation of issue #74 . I am very happy with it :)
I have one more wish, if that's not too much to ask for.
I´d like to have another StringProperty on the chartitem (and another constructor).
Heres why:
i got some data that i want to show on the coxcombchart that has a very long name.
i´d like to show a "succintly name" on the chart and on a label (where obviously would be enough space of showing it), the "long name".
Basically all i´d need is a stringproperty on the chartitem, a constructor so i can fill it and a getter for the new StringProperty.
The constructor should look something like this:
public ChartItem(String NAME, double VALUE, String LONGNAME, Color FILL)
"LONGNAME" might not be the best choice of name, but i think you get what i mean :D
this seems more like an feature request (for which I did not find the possibility).
Add a PolarChart, like the one that comes with JFreeChart.
You mentioned on Twitter that you already had one you could add.
Is a gradle/maven dependency available for this project?
Hello, if i need to clear dots in chart for a while (in case of dynamic charts building via XYSeriesBuilder
with empty items and calling clear()
on items causes
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:459)
at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at eu.hansolo.fx.charts.XYPane.drawLine(XYPane.java:717)
at eu.hansolo.fx.charts.XYPane.drawChart(XYPane.java:675)
at eu.hansolo.fx.charts.XYPane.redraw(XYPane.java:636)
at eu.hansolo.fx.charts.XYPane.lambda$registerListeners$8(XYPane.java:229)
at eu.hansolo.fx.charts.series.Series.fireSeriesEvent(Series.java:467)
at eu.hansolo.fx.charts.series.Series.lambda$new$0(Series.java:134)
at javafx.base/com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at javafx.base/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.base/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.base/javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.base/javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.base/javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.base/com.sun.javafx.collections.ObservableListWrapper.clear(ObservableListWrapper.java:157)
is that normal?
Hi first of all great work!
I am not too familiar with Java9 modules, but if eu.hansolo.fx.charts.data
is not exported how can one create the necessary data-structure (e.g. a tree with TreeNode and ChartData) required for the chart (e.g. SunburstBuilder.setTree)?
Hi Gerrit!
Could you please implement a SelectionEvent for the SankeyPlot chart (like you've done for the ArcChart) so that when the user clicks a on the chart connections (or endpoints) then the event would contain the in/out connection ?
Best regards and keep up the great work !
Carstein
These are great charts (and of course, thank you very much for your effort), is it possible to add whatever is required to use these in FXML layouts / Scenebuilder
Hello Gerrit,
I know I allready asked for this and you implemented it because of me, but I have a slight problem with it.
When I try to change the color of the Connections, it only allows it for max. 1 Connection per PlotItem its coming from.
So if I have 2 Connections going from X to Y and from X to Z, I can only decide the color of one of those.
The other Connection will have the color of the PlotItem.
My wish would be to change the color of all Connections.
It would also be very helpful if the Connection would hold the value it has.
At this moment it only has incoming, outgoing and the color.
Thanks in advance :)
I ran into an issue when programming a custom chart based on the code in the XYChart and XYPane classes. It seems that if your chart has a left y and a bottom y axis, then if you remove one the graph canvas shifts to overlap the other. So, removing the y means the bottom of the canvas is the bottom of the x axis, and removing the x means the left of the canvas is the left of the y axis. In addition to this, the canvas seems to be squashed into a smaller area focused around the remaining axis.
Here are examples:
With both
First of all thanks for the library! Speed improvements against the standard implementation are great.
I would like to replace a chart that I have where the user can change the min/max X/Y Axis values by dragging, zooming, ... So far I have not found any way to do that with this XYChart. As far as I can see its using a method private void adjustChartRange()
that is using the axis values once during init to set the XYPanes bounds.
I will start fiddling around in the code now but would like to ask in parallel:
adjustChartRange()
repeatedly break anything?Hello Gerrit,
I would like to know when the next Release for the Charts Library is planned.
Thanks in advance
Greetings Gerrit,
I was recently trying out your amazing RadarChart, and for some reason I'm not able to reach any place where I can add category values to the radar. Are these coming directly from the YChartItem? If so, I would expect, for example in your RadarChartTest, that
YChartItem(RND.nextDouble() * 100, "P" + i);
would show P1, P2, etc as categories around the 'radar'. Or am I missing something?
Anyway, thanks for these amazing javafx libraries!
Cheers
Hello,
I'm not too familiar with gradle and this is the first time I've attempted download and check out the charts library. If I'm not mistaken, in order to run the demo (Debian Bullseye), I should:
./gradlew demo
But when doing so, I get the following. Is it enough to help determine the problem? Thanks in advance.
Configure project :
Project : => 'eu.hansolo.fx.charts' Java module
FAILURE: Build failed with an exception.
Where:
Build file '/testdir/charts-17.1.2/build.gradle' line: 149
What went wrong:
A problem occurred evaluating root project 'charts'.
Could not get unknown property 'ossrhUsername' for Credentials [username: null] of type org.gradle.internal.credentials.DefaultPasswordCredentials_Decorated.
E.g. could you provide some screenshots about provided chart widgets?
via AxisBuilder.create(..)
.titleFontSize()
does not change size of title
When trying to build the following axis:
xAxisElev = AxisBuilder.create(Orientation.HORIZONTAL, Position.BOTTOM)
.autoScale(false)
.type(AxisType.LINEAR)
.minorTickMarksVisible(false)
.mediumTickMarksVisible(false)
.minorTickSpace(5)
.majorTickSpace(5)
.tickLabelFontSize(16)
.title("")
.build();
I run into various points that I would like to check before trying to change code :-)
majorTickSpace
its always overwritten during redraw()
since both calcAutoScale()
and calcScale()
set minor / major tick space (in my case its always set to 20 after build() and can't be changed afterwards since setMajorTickSpace()
is protected).redraw()
(used in most setXXX methods) depends on autoScale. So I would need to set autoScale first, but AxisBuilder uses a HashMap and not a LinkedHashMap - so I can't influence the order of setting of Axis variables.build()
triggers redraw()
6 times. Especially for the builder it would be nice to have some "transactional" bracket to call redraw()
after all the setXXX have been done?Hello,
Nice work on the Charts (and JavaFX in general).
Based on your examples, I thought it would be nice to have helpers to create the axis. In each of your test you repeat the functions createABCAxis(....) for which in lot of cases it would be the same function.
I think it would be nice to have these functions directly in the lib.
Thanks
Hello Gerrit,
In the latest Release is a Bug.
In CirularPlot.java
line 674: Connection connection = getConnection(item, outgoingItem);
Is trying to get a Connection that should be there but returns null.
line 704: connection.setTooltipText(tooltipText);
Is now trying to set the Tooltip for null.
The Problem is reproducible in the CircularPlotTest class by enabling the currently commented out Outgoings.
@Override public void init() {
// Setup Data
// Wahlberechtigte 61_500_000
PlotItem australia = new PlotItem("AUSTRALIA", 1_250_000, Color.rgb(255, 51, 51));
PlotItem india = new PlotItem("INDIA", 750_000, Color.rgb(255, 153, 51));
PlotItem china = new PlotItem("CHINA", 920_000, Color.rgb(255, 255, 51));
PlotItem japan = new PlotItem("JAPAN", 1_060_000, Color.rgb(153, 255, 51));
PlotItem thailand = new PlotItem("THAILAND", 720_000, Color.rgb(51, 255, 51));
PlotItem singapore = new PlotItem("SINGAPORE", 800_000, Color.rgb(51, 255, 153));
// Travel flow
australia.addToOutgoing(india, 150_000);
australia.addToOutgoing(china, 90_000);
australia.addToOutgoing(japan, 180_000);
australia.addToOutgoing(thailand, 15_000);
australia.addToOutgoing(singapore, 10_000);
japan.addToOutgoing(australia, 70_000);
List<PlotItem> items = List.of(australia, india, china, japan, thailand, singapore );
// Register listeners to click on connections and items
items.forEach(item -> {
item.addItemEventListener(e -> {
switch (e.getEventType()) {
case SELECTED: System.out.println("Selected: " + e.getItem().getName()); break;
}
});
});
india.addToOutgoing(australia, 35_000);
india.addToOutgoing(china, 10_000);
india.addToOutgoing(japan, 40_000);
india.addToOutgoing(thailand, 25_000);
india.addToOutgoing(singapore, 8_000);
china.addToOutgoing(australia, 10_000);
china.addToOutgoing(india, 7_000);
china.addToOutgoing(japan, 40_000);
china.addToOutgoing(thailand, 5_000);
china.addToOutgoing(singapore, 4_000);
japan.addToOutgoing(australia, 7_000);
japan.addToOutgoing(india, 8_000);
japan.addToOutgoing(china, 175_000);
japan.addToOutgoing(thailand, 11_000);
japan.addToOutgoing(singapore, 18_000);
thailand.addToOutgoing(australia, 70_000);
thailand.addToOutgoing(india, 30_000);
thailand.addToOutgoing(china, 22_000);
thailand.addToOutgoing(japan, 120_000);
thailand.addToOutgoing(singapore, 40_000);
singapore.addToOutgoing(australia, 60_000);
singapore.addToOutgoing(india, 90_000);
singapore.addToOutgoing(china, 110_000);
singapore.addToOutgoing(japan, 14_000);
singapore.addToOutgoing(thailand, 30_000);
// Setup Chart
circluarPlot = CircularPlotBuilder.create()
.prefSize(500, 500)
.items(items)
.connectionOpacity(0.75)
.decimals(0)
.minorTickMarksVisible(false)
.build();
ConnectionEventListener connectionListener = e -> System.out.println("From: " + e.getConnection().getOutgoingItem().getName() + " -> to: " + e.getConnection().getIncomingItem().getName() + " -> Value: " + e.getConnection().getValue());
circluarPlot.getConnections().forEach(connection -> connection.addConnectionEventListener(connectionListener));
if (null != circluarPlot.getConnection(australia, japan)) {
circluarPlot.getConnection(australia, japan).setFill(Color.BLUE);
circluarPlot.getConnection(australia, india).setFill(Color.CHOCOLATE);
circluarPlot.getConnection(japan, australia).setFill(Color.POWDERBLUE);
}
circluarPlot.getConnections().forEach(connection -> {
System.out.println(connection.getOutgoingItem().getName() + " -> " + connection.getIncomingItem().getName() + " -> Value: " + connection.getValue() + " -> Color: " + connection.getFill());
});
}
I've got a crippling need for a Parallel Coordinates plot on our JavaFX/TornadoFX desktop application.
Parallel Coordinates Plots (PCPs) are a very simple abstraction on a standard many-column matrix. A PCP graphs each row in the table as a horizontal line across the chart. Each column is represented as a vertical axies, and where that axis intersects each horizontal line, the height of the intersection from the bottom fo the chart is proportional to that rows value at that column.
A picture is worth a thousand words:
Our applications Parallel Coordinates chart:
a D3JS implementation:
https://bl.ocks.org/jasondavies/1341281
Parallel Coordintes represents a superbly general chart as it allows you to graphically represent data at arbitrarily high dimensionality.
There is a long list of features such a chart might have, which I'll outline below.
Our implementation is not worth sharing primarily because its use of bindings is inefficient abusive. We write an optimization algorithm which can redline the CPU for prolonged periods of time, but in many cases our profiling has indicated that the actual problematic hot loop is binding updates for our PCP implementation. Thus we would very much like another one, but we simply cant afford the time it would take to re-write it.
shameless plug: find out more about this product at empowerops.com
Image a graph displaying some data from the last X days. Where some data is not available for whatever reason.
It would be great, if we could display a "broken" line etc. indicating the data point is actually missing instead of missing either a day or set the data to a zero value, so the line just drops to the bottom - which is not the same as "there is no data".
I propose to allow to set "empty" data items that specifically exist only to allow the graph to be incomplete.
Hi Gerrit,
i got the following problem ....
CircularPlot.getConnections() isEmpty() when from.addToOutgoing(to, ...) is done after CircularPlotBuilder.create()
There seams to be a dependency in order of method calls, see validateData().
Its very surprising that allthougt the appearance on screen ist totally fine, there is an empty conenctions list.
This all is upcoming only, because Connections are only internal in CircularPlot.
Another previous mistake was to create Connections outside the plot and using them.
Everything seems ok, the appearance on screen ist totally fine, but i never got the idea that these are totally unused.
I only wondered why i could not get any ConnectionEvent.
IMO it would be great to have Interfaces for PlotItem(NODE) and Connection(EDGE) in order to add own Properties
or even to use existing Graph Structures to implement PlotItem and Connection Interface for Charts.
But thanks for your work,
great FX framework!!
Download link also broken
Hi thereeee,
started using your linechart. Its simple and beautiful.
As i started playing around i couldnt get behind the following:
Questions:
why has every categorie changed to "Jan" when changing maxValue from 13 to 5?
why has maxvalue(13) nut begun at the beginning of the chart but maxvalue(5) did?
Questions:
this is basically what i want, except the fact that theres useless space in the chart because i always want to display just 5 values on the x-asis. why do i need the space in order for the categories to be kinda right?
Explanation for how i got there:
sooo... the thing is, i played around in your test and all i did was only using 1 instead of 3 series and displaying only 5 values on the x asis instead of 13.
the following code is from your LineChartTest but with my changes (i left your original code commented)
at the //TODO might be the problem or my own stupidness, lets find out
`public class LineChartTest extends Application {
private static final Random RND = new Random();
private static final Double AXIS_WIDTH = 25d;
private XYChartItem p1;
private XYChartItem p2;
private XYChartItem p3;
private XYChartItem p4;
private XYChartItem p5;
private XYChartItem p6;
private XYChartItem p7;
private XYChartItem p8;
private XYChartItem p9;
private XYChartItem p10;
private XYChartItem p11;
private XYChartItem p12;
private XYSeries xySeries1;
private XYSeries xySeries2;
private Axis xAxisBottom;
private Axis yAxisLeft;
private XYChart lineChart;
private long lastTimerCalled;
private AnimationTimer timer;
@Override public void init() {
p1 = new XYChartItem(1, RND.nextDouble() * 300 + 200, "Jan");
p2 = new XYChartItem(2, RND.nextDouble() * 300 + 200, "Feb");
p3 = new XYChartItem(3, RND.nextDouble() * 300 + 200, "Mar");
p4 = new XYChartItem(4, RND.nextDouble() * 300 + 200, "Apr");
p5 = new XYChartItem(5, RND.nextDouble() * 300 + 200, "May");
/*
p6 = new XYChartItem(6, RND.nextDouble() * 300 + 200, "Jun");
p7 = new XYChartItem(7, RND.nextDouble() * 300 + 200, "Jul");
p8 = new XYChartItem(8, RND.nextDouble() * 300 + 200, "Aug");
p9 = new XYChartItem(9, RND.nextDouble() * 300 + 200, "Sep");
p10 = new XYChartItem(10, RND.nextDouble() * 300 + 200, "Oct");
p11 = new XYChartItem(11, RND.nextDouble() * 300 + 200, "Nov");
p12 = new XYChartItem(12, RND.nextDouble() * 300 + 200, "Dec");
*/
xySeries1 = XYSeriesBuilder.create()
.items(p1, p2, p3, p4, p5)
//.items(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
.chartType(ChartType.SMOOTH_AREA)
.fill(Color.web("#00AEF520"))
.stroke(Color.web("#00AEF5"))
.symbolFill(Color.web("#00AEF5"))
.symbolStroke(Color.web("#293C47"))
.symbolSize(10)
.strokeWidth(3)
.symbolsVisible(true)
.build();
/*
xySeries2 = XYSeriesBuilder.create()
.items(new XYChartItem(1, 280, "Jan"),
new XYChartItem(2, 190, "Feb"),
new XYChartItem(3, 280, "Mar"),
new XYChartItem(4, 300, "Apr"),
new XYChartItem(5, 205, "May"),
new XYChartItem(6, 430, "Jun"),
new XYChartItem(7, 380, "Jul"),
new XYChartItem(8, 180, "Aug"),
new XYChartItem(9, 300, "Sep"),
new XYChartItem(10, 440, "Oct"),
new XYChartItem(11, 300, "Nov"),
new XYChartItem(12, 390, "Dec"))
.chartType(ChartType.SMOOTH_AREA)
.fill(Color.web("#4EE29B20"))
.stroke(Color.web("#4EE29B"))
.symbolFill(Color.web("#4EE29B"))
.symbolStroke(Color.web("#293C47"))
.symbolSize(10)
.strokeWidth(3)
.symbolsVisible(true)
.build();
*/
xAxisBottom = AxisBuilder.create(Orientation.HORIZONTAL, Position.BOTTOM)
.type(AxisType.TEXT)
.prefHeight(AXIS_WIDTH)
.categories("Jan", "Feb", "Mar", "Apr", "May")
//.categories("", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
.minValue(1)
//TODO whats wrong here? try maxValue(13), maxValue(5) and maxValue(7)
.maxValue(7)
//.maxValue(13)
.autoScale(true)
.axisColor(Color.web("#85949B"))
.tickLabelColor(Color.web("#85949B"))
.tickMarkColor(Color.web("#85949B"))
//.tickMarksVisible(false)
.build();
AnchorPane.setBottomAnchor(xAxisBottom, 0d);
AnchorPane.setLeftAnchor(xAxisBottom, AXIS_WIDTH);
AnchorPane.setRightAnchor(xAxisBottom, AXIS_WIDTH);
yAxisLeft = AxisBuilder.create(Orientation.VERTICAL, Position.LEFT)
.type(AxisType.LINEAR)
.prefWidth(AXIS_WIDTH)
.minValue(0)
.maxValue(1000)
.autoScale(true)
.axisColor(Color.web("#85949B"))
.tickLabelColor(Color.web("#85949B"))
.tickMarkColor(Color.web("#85949B"))
//.tickMarksVisible(false)
.build();
AnchorPane.setTopAnchor(yAxisLeft, 0d);
AnchorPane.setBottomAnchor(yAxisLeft, AXIS_WIDTH);
AnchorPane.setLeftAnchor(yAxisLeft, 0d);
Grid grid = GridBuilder.create(xAxisBottom, yAxisLeft)
.gridLinePaint(Color.web("#384C57"))
.minorHGridLinesVisible(false)
.mediumHGridLinesVisible(false)
.minorVGridLinesVisible(false)
.mediumVGridLinesVisible(false)
.gridLineDashes(4, 4)
.build();
XYPane lineChartPane = new XYPane(xySeries1);
//XYPane lineChartPane = new XYPane(xySeries1, xySeries2);
lineChart = new XYChart<>(lineChartPane, grid, yAxisLeft, xAxisBottom);
/*
lastTimerCalled = System.nanoTime();
timer = new AnimationTimer() {
@Override public void handle(final long now) {
if (now > lastTimerCalled + 2_000_000_000l) {
p1.setY(RND.nextDouble() * 300 + 200);
p2.setY(RND.nextDouble() * 300 + 200);
p3.setY(RND.nextDouble() * 300 + 200);
p4.setY(RND.nextDouble() * 300 + 200);
p5.setY(RND.nextDouble() * 300 + 200);
p6.setY(RND.nextDouble() * 300 + 200);
p7.setY(RND.nextDouble() * 300 + 200);
p8.setY(RND.nextDouble() * 300 + 200);
p9.setY(RND.nextDouble() * 300 + 200);
p10.setY(RND.nextDouble() * 300 + 200);
p11.setY(RND.nextDouble() * 300 + 200);
p12.setY(RND.nextDouble() * 300 + 200);
lastTimerCalled = now;
}
}
};
*/
}
@Override public void start(Stage stage) {
StackPane pane = new StackPane(lineChart);
pane.setPadding(new Insets(10));
pane.setBackground(new Background(new BackgroundFill(Color.web("#293C47"), CornerRadii.EMPTY, Insets.EMPTY)));
Scene scene = new Scene(pane);
stage.setTitle("Line Chart");
stage.setScene(scene);
stage.show();
//lineChart.getXYPane().getListOfSeries().add(createSeries());
//timer.start();
}
@Override public void stop() {
System.exit(0);
}
private XYSeries createSeries() {
XYSeries xySeries = XYSeriesBuilder.create()
.items(new XYChartItem(1, 600, "Jan"),
new XYChartItem(2, 760, "Feb"),
new XYChartItem(3, 585, "Mar"),
new XYChartItem(4, 410, "Apr"),
new XYChartItem(5, 605, "May"),
new XYChartItem(6, 825, "Jun"),
new XYChartItem(7, 595, "Jul"),
new XYChartItem(8, 300, "Aug"),
new XYChartItem(9, 515, "Sep"),
new XYChartItem(10, 780, "Oct"),
new XYChartItem(11, 570, "Nov"),
new XYChartItem(12, 620, "Dec"))
.chartType(ChartType.SMOOTH_AREA)
.fill(Color.web("#AE00F520"))
.stroke(Color.web("#AE00F5"))
.symbolFill(Color.web("#AE00F5"))
.symbolStroke(Color.web("#293C47"))
.symbolSize(10)
.strokeWidth(3)
.symbolsVisible(true)
.build();
return xySeries;
}
private Axis createLeftYAxis(final double MIN, final double MAX, final boolean AUTO_SCALE, final double AXIS_WIDTH) {
Axis axis = new Axis(Orientation.VERTICAL, Position.LEFT);
axis.setMinValue(MIN);
axis.setMaxValue(MAX);
axis.setPrefWidth(AXIS_WIDTH);
axis.setAutoScale(AUTO_SCALE);
AnchorPane.setTopAnchor(axis, 0d);
AnchorPane.setBottomAnchor(axis, AXIS_WIDTH);
AnchorPane.setLeftAnchor(axis, 0d);
return axis;
}
private Axis createCenterYAxis(final double MIN, final double MAX, final boolean AUTO_SCALE, final double AXIS_WIDTH) {
Axis axis = new Axis(Orientation.VERTICAL, Position.CENTER);
axis.setMinValue(MIN);
axis.setMaxValue(MAX);
axis.setPrefWidth(AXIS_WIDTH);
axis.setAutoScale(AUTO_SCALE);
AnchorPane.setTopAnchor(axis, 0d);
AnchorPane.setBottomAnchor(axis, AXIS_WIDTH);
AnchorPane.setLeftAnchor(axis, axis.getZeroPosition());
return axis;
}
private Axis createRightYAxis(final double MIN, final double MAX, final boolean AUTO_SCALE, final double AXIS_WIDTH) {
Axis axis = new Axis(Orientation.VERTICAL, Position.RIGHT);
axis.setMinValue(MIN);
axis.setMaxValue(MAX);
axis.setPrefWidth(AXIS_WIDTH);
axis.setAutoScale(AUTO_SCALE);
AnchorPane.setRightAnchor(axis, 0d);
AnchorPane.setTopAnchor(axis, 0d);
AnchorPane.setBottomAnchor(axis, AXIS_WIDTH);
return axis;
}
private Axis createBottomXAxis(final double MIN, final double MAX, final boolean AUTO_SCALE, final double AXIS_WIDTH) {
Axis axis = new Axis(Orientation.HORIZONTAL, Position.BOTTOM);
axis.setMinValue(MIN);
axis.setMaxValue(MAX);
axis.setPrefHeight(AXIS_WIDTH);
axis.setAutoScale(AUTO_SCALE);
AnchorPane.setBottomAnchor(axis, 0d);
AnchorPane.setLeftAnchor(axis, AXIS_WIDTH);
AnchorPane.setRightAnchor(axis, AXIS_WIDTH);
return axis;
}
private Axis createCenterXAxis(final double MIN, final double MAX, final boolean AUTO_SCALE, final double AXIS_WIDTH) {
Axis axis = new Axis(Orientation.HORIZONTAL, Position.CENTER);
axis.setMinValue(MIN);
axis.setMaxValue(MAX);
axis.setPrefHeight(AXIS_WIDTH);
axis.setAutoScale(AUTO_SCALE);
AnchorPane.setBottomAnchor(axis, axis.getZeroPosition());
AnchorPane.setLeftAnchor(axis, AXIS_WIDTH);
AnchorPane.setRightAnchor(axis, AXIS_WIDTH);
return axis;
}
private Axis createTopXAxis(final double MIN, final double MAX, final boolean AUTO_SCALE, final double AXIS_WIDTH) {
Axis axis = new Axis(Orientation.HORIZONTAL, Position.TOP);
axis.setMinValue(MIN);
axis.setMaxValue(MAX);
axis.setPrefHeight(AXIS_WIDTH);
axis.setAutoScale(AUTO_SCALE);
AnchorPane.setTopAnchor(axis, AXIS_WIDTH);
AnchorPane.setLeftAnchor(axis, AXIS_WIDTH);
AnchorPane.setRightAnchor(axis, AXIS_WIDTH);
return axis;
}
public static void main(String[] args) {
launch(args);
}
}`
Am i understanding this correctly that the JDK16 branch is a Modular JavaFX while the Master branch is non-Modular. If not, why there is such distinguish?
Thanks,
I'm trying to use MaxtrixPane for incoming data, so I add new matrixItems in to the ArrayList, but the data won't appear.
This problem is resolving with redrawing matrix with recreating the MatrixPane.
Is it possible to redraw matrix on series change event?
Hello Gerrit,
I have a Question to the CircularPlot and PlotItems.
Example:
I have 10 PlotItems and add those to the CircularPlot.
The CircularPlot gets drawn with these 10 PlotItems.
Now I want to click any PlotItem and trigger the ItemEvent of this specific PlotItem.
This way I could Identify the specific PlotItem.
Is this already possible or is it planned?
Are there any plans to support zooming with mouse? I know this can be very complex in detail but probably it can be extended in steps?
I have an idea to realize this with a zoom-able data filter, do you think this could be a working approach?
I tested the parallel coordinates charts, I really like it 👍
However as soon as the data gets bigger the performance drops quickly. On my machine, more than 500 samples take several seconds to refresh.
I changed the way drawConnections works, by using Lines instead of Paths and it greatly improved the performance. Plotting 100000 samples with Lines takes roughly the same time as plotting 500 samples with Paths.
I'll submit a pull request with this change.
Note: NO code was added, this issue occurs when adding the dependency to the POM.
After adding the dependency
<dependency>
<groupId>eu.hansolo.fx</groupId>
<artifactId>charts</artifactId>
<version>11.3</version>
<type>pom</type>
</dependency>
to the POM the application fails to start.
Immediately upon start-up (even before spring kicks in) the following exception is thrown:
java.lang.NoSuchMethodError: 'com.sun.javafx.geom.transform.GeneralTransform3D com.sun.prism.d3d.D3DContext.getPerspectiveTransformNoClone()'
at com.sun.prism.d3d.D3DContext.updateShaderTransform(D3DContext.java:290)
at com.sun.prism.impl.ps.BaseShaderContext.checkState(BaseShaderContext.java:662)
at com.sun.prism.impl.ps.BaseShaderContext.validateTextureOp(BaseShaderContext.java:583)
at com.sun.prism.impl.ps.BaseShaderContext.validateTextureOp(BaseShaderContext.java:500)
at com.sun.prism.impl.BaseGraphics.drawTexture(BaseGraphics.java:426)
at com.sun.prism.impl.ps.BaseShaderGraphics.drawTexture(BaseShaderGraphics.java:139)
at com.sun.javafx.sg.prism.NGImageView.renderContent(NGImageView.java:123)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2072)
at com.sun.javafx.sg.prism.NGImageView.doRender(NGImageView.java:103)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1964)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:270)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:578)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2072)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1964)
at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:479)
at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:328)
at com.sun.javafx.tk.quantum.PresentingPainter.run(PresentingPainter.java:91)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.base/java.lang.Thread.run(Thread.java:832)
Once the application has loaded a StackOverflowException
is eventually thrown as the above is recursively thrown.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.