fair-acc / chart-fx

A scientific charting library focused on performance optimised real-time data visualisation at 25 Hz update rates for data sets with a few 10 thousand up to 5 million data points.
GNU Lesser General Public License v3.0
504 stars 93 forks source link

Overhauled dataset styling #603

Closed ennerf closed 1 year ago

ennerf commented 1 year ago

Before

The styling was previously based on Strings that could be applied to datasets as well as to individual data points. Some reasons for doing it this way were that the style needs to be storable and usable without a JavaFX dependency (DataSets are not dependent on JavaFX).

Problems

After

Each renderer is now part of the SceneGraph and generates a styleable node for each dataset (a dataset can be in multiple renderers, but only once per renderer). The nodes get styled with JavaFX properties and apply the source dataSet.getStyle(), which was changed to match the JavaFX properties. The individual styles still use strings, but there is now no more overhead when they are not used.

Ways to style DataSets

1) directly on the Node

Quick way to style individual datasets

var styleNode = renderer.getStyleNode(dataSet);
styleNode.setFill(Color.RED);

2) via CSS and classes

Good way to style certain classes of data that should always look the same

dataSet.addStyleClasses("cartesian-data-x");
.cartesian-data-x {
  -fill-color: red !important;
}
.cartesian-data-y {
  -fill-color: green !important;
}
.cartesian-data-z {
  -fill-color: blue !important;
}

3) via style strings and a utility class

// generates: "visibility: visible; -fx-font: System; -fx-font-weight: bold;"
String style = DataSetStyleBuilder.instance()
    .setFontWeight("bold")
    .setFont("System")
    .setVisible(true)
    .build();
dataSet.setStyle(style);

Other Behavior changes

Bugs and things that need to be looked at after this PR

// update categories in case of category axes for the first (index == '0') indexed data set
if (dataSetIndex == 0) {
    if (getFirstAxis(Orientation.HORIZONTAL) instanceof CategoryAxis) {
        final CategoryAxis axis = (CategoryAxis) getFirstAxis(Orientation.HORIZONTAL);
        axis.updateCategories(dataSet);
    }

    if (getFirstAxis(Orientation.VERTICAL) instanceof CategoryAxis) {
        final CategoryAxis axis = (CategoryAxis) getFirstAxis(Orientation.VERTICAL);
        axis.updateCategories(dataSet);
    }
}

More styling that didn't fit into this PR

The PR is already very large as is, so I didn't want to pack in more. However, after merging there are a few more styling things that I'd like to take a look at:

pr-explainer-bot[bot] commented 1 year ago

Pull Request Review - Summary

Hey there! 👋 Here's a summary of the previous tasks and their results for the pull request review. Let's dive in!

Changes

  1. In task1, import statements were changed in various files to improve code organization and maintain consistency.
  2. In task2, suggestions were made to improve code readability and consistency at specific lines.
  3. In task3, potential bugs were identified in specific files and recommendations were provided.
  4. In task4, suggestions were made to refactor code for better readability in a specific file.

Suggestions

  1. In task2, specific lines were pointed out where improvements can be made, such as removing unnecessary empty lines and adding helpful comments.

Bugs

  1. In task3, specific files were identified with missing newlines and semicolons, which should be added to fix the issues.

Improvements

  1. In task4, a specific method in the Chart.java file was suggested to be refactored for better readability.

Rating

Unfortunately, no rating was provided for the code in task5. It would have been helpful to have a rating on a scale of 0 to 10, considering criteria like readability, performance, and security.

That's it for the summary! If you have any further questions or need more details, feel free to ask. And don't forget, we also offer a premium plan that can handle bigger pull requests with more context. 😉

Happy coding!

ennerf commented 1 year ago

I recorded a flight recording for 60 seconds running the ChartHighUpdateRateSample with an extended Buffer capacity of 75k.

Main branch before layout changes total 151 gcs, longest gc at 489ms and many old ones at >50ms. Heap grew to 8GB

image

Current main branch after layout changes total 75 gcs, longest gc at 71ms and still quite a few old ones at >30ms. Heap grew to 6GB

image

This PR total 5 gcs, longest gc 5ms (initial CSS), and 2.3ms in steady state. Heap grew to 0.2GB

image

codecov[bot] commented 1 year ago

Codecov Report

Patch coverage: 39.54% and project coverage change: -1.73% :warning:

Comparison is base (5d5f936) 49.64% compared to head (755626f) 47.91%.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #603 +/- ## ============================================ - Coverage 49.64% 47.91% -1.73% + Complexity 6239 6183 -56 ============================================ Files 379 401 +22 Lines 37579 38254 +675 Branches 6157 6087 -70 ============================================ - Hits 18657 18331 -326 - Misses 17693 18777 +1084 + Partials 1229 1146 -83 ``` | [Files Changed](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc) | Coverage Δ | | |---|---|---| | [...t/src/main/java/io/fair\_acc/chartfx/axes/Axis.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYXhlcy9BeGlzLmphdmE=) | `0.00% <ø> (ø)` | | | [...acc/chartfx/benchmark/CircularDoubleDataSet2D.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYmVuY2htYXJrL0NpcmN1bGFyRG91YmxlRGF0YVNldDJELmphdmE=) | `0.00% <0.00%> (ø)` | | | [...air\_acc/chartfx/benchmark/HdrHistogramDataSet.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYmVuY2htYXJrL0hkckhpc3RvZ3JhbURhdGFTZXQuamF2YQ==) | `0.00% <0.00%> (ø)` | | | [...ir\_acc/chartfx/benchmark/HdrHistogramRecorder.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYmVuY2htYXJrL0hkckhpc3RvZ3JhbVJlY29yZGVyLmphdmE=) | `0.00% <0.00%> (ø)` | | | [...air\_acc/chartfx/benchmark/LiveDisplayRecorder.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYmVuY2htYXJrL0xpdmVEaXNwbGF5UmVjb3JkZXIuamF2YQ==) | `0.00% <0.00%> (ø)` | | | [...ir\_acc/chartfx/benchmark/MeasurementRecorders.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYmVuY2htYXJrL01lYXN1cmVtZW50UmVjb3JkZXJzLmphdmE=) | `0.00% <0.00%> (ø)` | | | [.../io/fair\_acc/chartfx/benchmark/PercentileAxis.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvYmVuY2htYXJrL1BlcmNlbnRpbGVBeGlzLmphdmE=) | `0.00% <0.00%> (ø)` | | | [.../java/io/fair\_acc/chartfx/marker/CachedMarker.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvbWFya2VyL0NhY2hlZE1hcmtlci5qYXZh) | `0.00% <0.00%> (ø)` | | | [.../java/io/fair\_acc/chartfx/plugins/ChartPlugin.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvcGx1Z2lucy9DaGFydFBsdWdpbi5qYXZh) | `78.20% <ø> (ø)` | | | [.../java/io/fair\_acc/chartfx/plugins/EditDataSet.java](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc#diff-Y2hhcnRmeC1jaGFydC9zcmMvbWFpbi9qYXZhL2lvL2ZhaXJfYWNjL2NoYXJ0ZngvcGx1Z2lucy9FZGl0RGF0YVNldC5qYXZh) | `23.48% <ø> (+0.18%)` | :arrow_up: | | ... and [65 more](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc) | | ... and [10 files with indirect coverage changes](https://app.codecov.io/gh/fair-acc/chart-fx/pull/603/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=fair-acc)

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

sonarcloud[bot] commented 1 year ago

SonarCloud Quality Gate failed.    Quality Gate failed

Bug C 61 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 125 Code Smells

No Coverage information No Coverage information
0.9% 0.9% Duplication

idea Catch issues before they fail your Quality Gate with our IDE extension sonarlint SonarLint