Weird rendering artefacts #458
-
Plotting At first I thought these happened when multiple series are drawn on top of each other, but there only one data set at these points. There are other data sets in the same chart, and the colour of the artefacts sometimes changes when the series in the chart change or when their order changes. So far I've not been able to find out how the colour is determined, e.g. it is not the colour of the topmost series. The artefacts appear even when all other series are hidden (not visible), in which case they seem to always appear in the original colour of the series. Weirdly, if I make only a single other data set visible in the chart, the colour changes, but to a third, different colour which is not that of either of the two visible data sets. Artefacts hide and re-appear together with their data set when I toggle its visibility, but are not present when I zoom in further (via the Environment:
|
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 3 replies
-
@domenicquirl do you have an MVP to reproduce these effects? That would help a lot for debugging. |
Beta Was this translation helpful? Give feedback.
-
I spent some time on reproducing this and managed to catch it in a reasonably simplified chart: It's very consistent if you zoom in on the first two periods and then adjust the window with to become smaller. When I set the scene width to 400 instead of 800 I can reproduce it with only the zoom and without changing anything about the window. Note that this happens even if the cosine function is the only data set in the chart. Adding a sine function, it shows artefacts as well for me. I could not get the colour of the artefacts to switch though in this small example, probably because it is not very dynamic. Java Code:package com.mindmotiv.arttest.signalplot.chart;
import com.mindmotiv.arttest.signalplot.plugins.DataPointHoverInfo;
import de.gsi.chart.XYChart;
import de.gsi.chart.axes.spi.DefaultNumericAxis;
import de.gsi.chart.plugins.Panner;
import de.gsi.chart.plugins.Zoomer;
import de.gsi.chart.renderer.LineStyle;
import de.gsi.chart.renderer.spi.ErrorDataSetRenderer;
import de.gsi.dataset.testdata.spi.CosineFunction;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class DemoChart extends Application {
public static void main( String [] args ) {
Application.launch( args );
}
@Override
public void start( Stage primaryStage ) throws Exception {
var xAxis = new DefaultNumericAxis();
var yAxis = new DefaultNumericAxis();
yAxis.setAutoRangePadding( 0.05 );
var baseChart = new XYChart( xAxis, yAxis );
baseChart.updateAxisRange();
baseChart.setLegendVisible( false );
var renderer = new ErrorDataSetRenderer();
renderer.setPolyLineStyle( LineStyle.STAIR_CASE );
renderer.getAxes().add( yAxis );
baseChart.getRenderers().add( renderer );
baseChart.getPlugins().addAll( new DataPointHoverInfo(), new Panner(), new Zoomer() );
var cos = new CosineFunction( "cos", 500 );
cos.setStyle( "strokeColor=darkblue;fillColor=darkblue;" );
renderer.getDatasets().add( cos );
// var sine = new SineFunction( "sin", 500 );
// sine.setStyle( "strokeColor=red;fillColor=red;" );
// renderer.getDatasets().add( sine );
final Scene scene = new Scene( new StackPane( baseChart ), 400, 600 );
String style = DemoChart.class.getResource( "Demo.css" ).toExternalForm();
scene.getStylesheets().add( style );
primaryStage.setTitle( getClass().getSimpleName() );
primaryStage.setScene( scene );
primaryStage.show();
primaryStage.setOnCloseRequest( evt -> Platform.exit() );
}
} CSS:* {
-fx-font-size: 11;
-fx-text-fill: #ededed;
}
.chart-plot-background {
-fx-background: #323232; /*#202124;*/
}
.chart-datapoint-tooltip-label {
-fx-background-color: #424242;
-fx-border-color: #adadad;
-fx-border-width: 1px;
}
.axis {
-fx-tick-label-fill: #CC893A;
}
.chart-horizontal-grid-lines, .chart-vertical-grid-lines {
-fx-stroke: #353C42;/*#41454c; */
} |
Beta Was this translation helpful? Give feedback.
-
While working on #457 I've just seen it in the (it's a bit hard to see in the preview, if you open the image on its own the lines are less blurry) |
Beta Was this translation helpful? Give feedback.
-
I can recommend the ErrorDataSetRendererStylingSample for such Investigations, because it has a lot of knobs for the Renderer. I could reproduce it there (Using the MIX_TRIGONOMETRIC datasets, increasing the number of samples and zooming in to a similar setting that you provided). Then you can disable the error surfaces or disable the point reduction algorithm. I'm not completely sure if this is a bug in the data reduction algorithm, the ErrorDataSetRenderer or if it is just the result for this kind of data and data reduction settings (maybe the default threshold distance for reduction should be reduced?). |
Beta Was this translation helpful? Give feedback.
-
@domenicquirl this is not a bug but by design. 😄 The In the case of the (default) If you want to change, you can opt for one of the following options:
The default ErrorDataSetRenderer parameters are optimised for large DataSets and a behaviour to follow common mathematical/scientific practices. Still, there are certainly corner use-cases where there are other constraints. ... feel free to experiment or adjust the above parameters to your needs. Hope this helps and explains a bit your observations. Thanks again for your interest and for using chart-fx. |
Beta Was this translation helpful? Give feedback.
-
Thank you both of you for taking the time! I could not get the artefacts to disappear with any setting for the Note that I was not able to try a
Since you mentioned reducing the number to 1 this is probably not supposed to happen? Anyways, I'll go ahead without point reduction for now and come back to this if it turns out the performance is indeed too noticeable. Thanks again for your help! |
Beta Was this translation helpful? Give feedback.
@domenicquirl this is not a bug but by design. 😄
The
ErrorDataSetRenderer
performs a point reduction algorithm if the points overlap within a non-discernable 'n x n' pixel area (default is '5x5', but can be adjusted viaminRequiredReductionSizeProperty
) and replaces these points with a visual (-only) replacement at the mean position and adds some error-bars that correspond to the point-spread of the replaced points. This is a visual optimization only and disappears when zooming-in and can change when shifting the DataSet.In the case of the (default)
ErrorStyle.ERRORCOMBO
error style these error bars (aka. whiskers) are converted to error surfaces which -- since there are apparently no ot…