io.fair_acc.chartfx.ui.css.DataSetNodeParameter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of chartfx Show documentation
Show all versions of chartfx Show documentation
This charting library ${project.artifactId}- is an extension
in the spirit of Oracle's XYChart and performance/time-proven JDataViewer charting functionalities.
Emphasis was put on plotting performance for both large number of data points and real-time displays,
as well as scientific accuracies leading to error bar/surface plots, and other scientific plotting
features (parameter measurements, fitting, multiple axes, zoom, ...).
The newest version!
package io.fair_acc.chartfx.ui.css;
import java.util.List;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.css.*;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.shape.StrokeLineJoin;
import io.fair_acc.chartfx.marker.DefaultMarker;
import io.fair_acc.chartfx.marker.Marker;
import io.fair_acc.chartfx.renderer.spi.utils.FillPatternStyleHelper;
import io.fair_acc.chartfx.utils.PropUtil;
/**
* Holds the styleable parameters of the DataSetNode
*
* @author ennerf
*/
public abstract class DataSetNodeParameter extends Parent implements StyleUtil.StyleNode {
// ======================== State properties ========================
private final LongProperty changeCounter = new SimpleLongProperty(0);
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty localIndex = new SimpleIntegerProperty();
private final IntegerProperty globalIndex = new SimpleIntegerProperty();
private final IntegerProperty colorIndex = addOnChange(new SimpleIntegerProperty());
private final DoubleProperty intensity = addOnChange(css().createDoubleProperty(this, "intensity", 100));
private final BooleanProperty showInLegend = addOnChange(css().createBooleanProperty(this, "showInLegend", true));
private final DoubleProperty hatchShiftByIndex = addOnChange(css().createDoubleProperty(this, "hatchShiftByIndex", 1.5));
{
addOnChange(visibleProperty());
}
// ======================== Marker properties (ignored if markerSize is zero) ========================
// The CSS enum property can't be set to the base interface, so we provide a user binding that overrides the CSS
private final ObjectProperty markerType = css().createEnumProperty(this, "markerType", DefaultMarker.DEFAULT, true, DefaultMarker.class);
private final ObjectProperty userMarkerType = new SimpleObjectProperty<>(null);
private final ObjectBinding actualMarkerType = addOnChange(Bindings.createObjectBinding(() -> {
return userMarkerType.get() != null ? userMarkerType.get() : markerType.get();
}, userMarkerType, markerType));
private final DoubleProperty markerLineWidth = addOnChange(css().createDoubleProperty(this, "markerLineWidth", 0.5));
private final DoubleProperty markerSize = addOnChange(css().createDoubleProperty(this, "markerSize", 1.5));
private final ObjectProperty markerColor = addOnChange(css().createPaintProperty(this, "markerColor", Color.BLACK));
protected final ObjectBinding intensifiedMarkerColor = intensifiedColor(markerColor);
private final ObjectProperty markerLineDashArray = addOnChange(css().createNumberArrayProperty(this, "markerLineDashArray", null));
private final ObjectBinding markerLineDashes = StyleUtil.toUnboxedDoubleArray(markerLineDashArray);
// ======================== Line properties (ignored if lineWidth is zero) ========================
private final DoubleProperty lineWidth = addOnChange(css().createDoubleProperty(this, "lineWidth", 1.0));
private final ObjectProperty lineColor = addOnChange(css().createPaintProperty(this, "lineColor", Color.BLACK));
protected final ObjectBinding intensifiedLineColor = intensifiedColor(lineColor);
private final ObjectBinding lineFillPattern = hatchFillPattern(intensifiedLineColor);
private final ObjectProperty lineDashArray = addOnChange(css().createNumberArrayProperty(this, "lineDashArray", null));
private final ObjectBinding lineDashes = StyleUtil.toUnboxedDoubleArray(lineDashArray);
private final DoubleProperty lineMiterLimit = addOnChange(css().createDoubleProperty(this, "lineMiterLimit", 1d));
private final ObjectProperty lineJoin = addOnChange(css().createEnumProperty(this, "lineJoin", StrokeLineJoin.BEVEL, true, StrokeLineJoin.class));
private final ObjectProperty lineCap = addOnChange(css().createEnumProperty(this, "lineCap", StrokeLineCap.BUTT, true, StrokeLineCap.class));
// ======================== Overriden accessors ========================
public Paint getMarkerColor() {
return intensifiedMarkerColor.get();
}
public Paint getLineColor() {
return intensifiedLineColor.get();
}
public Marker getMarkerType() {
return markerTypeProperty().get();
}
public ObjectBinding markerTypeProperty() {
return actualMarkerType;
}
public void setMarkerType(Marker marker) {
this.userMarkerType.set(marker);
}
// ======================== Generated accessors ========================
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
return name;
}
public void setName(String name) {
// TODO: the name may revert to the dataSet name. Should this set the underlying dataSet name? may be shared?
this.name.set(name);
}
public int getLocalIndex() {
return localIndex.get();
}
public IntegerProperty localIndexProperty() {
return localIndex;
}
public void setLocalIndex(int localIndex) {
this.localIndex.set(localIndex);
}
public int getGlobalIndex() {
return globalIndex.get();
}
public IntegerProperty globalIndexProperty() {
return globalIndex;
}
public void setGlobalIndex(int globalIndex) {
this.globalIndex.set(globalIndex);
}
public int getColorIndex() {
return colorIndex.get();
}
public IntegerProperty colorIndexProperty() {
return colorIndex;
}
public void setColorIndex(int colorIndex) {
this.colorIndex.set(colorIndex);
}
public double getIntensity() {
return intensity.get();
}
public DoubleProperty intensityProperty() {
return intensity;
}
public void setIntensity(double intensity) {
this.intensity.set(intensity);
}
public boolean isShowInLegend() {
return showInLegend.get();
}
public BooleanProperty showInLegendProperty() {
return showInLegend;
}
public void setShowInLegend(boolean showInLegend) {
this.showInLegend.set(showInLegend);
}
public double getHatchShiftByIndex() {
return hatchShiftByIndex.get();
}
public DoubleProperty hatchShiftByIndexProperty() {
return hatchShiftByIndex;
}
public void setHatchShiftByIndex(double hatchShiftByIndex) {
this.hatchShiftByIndex.set(hatchShiftByIndex);
}
@Override
public long getChangeCounter() {
return changeCounter.get();
}
public void setChangeCounter(long changeCounter) {
this.changeCounter.set(changeCounter);
}
public void setMarkerType(DefaultMarker markerType) {
this.markerType.set(markerType);
}
public Marker getUserMarkerType() {
return userMarkerType.get();
}
public ObjectProperty userMarkerTypeProperty() {
return userMarkerType;
}
public void setUserMarkerType(Marker userMarkerType) {
this.userMarkerType.set(userMarkerType);
}
public Marker getActualMarkerType() {
return actualMarkerType.get();
}
public ObjectBinding actualMarkerTypeProperty() {
return actualMarkerType;
}
public double getMarkerLineWidth() {
return markerLineWidth.get();
}
public DoubleProperty markerLineWidthProperty() {
return markerLineWidth;
}
public void setMarkerLineWidth(double markerLineWidth) {
this.markerLineWidth.set(markerLineWidth);
}
public double getMarkerSize() {
return markerSize.get();
}
public DoubleProperty markerSizeProperty() {
return markerSize;
}
public void setMarkerSize(double markerSize) {
this.markerSize.set(markerSize);
}
public ObjectProperty markerColorProperty() {
return markerColor;
}
public void setMarkerColor(Paint markerColor) {
this.markerColor.set(markerColor);
}
public Paint getIntensifiedMarkerColor() {
return intensifiedMarkerColor.get();
}
public ObjectBinding intensifiedMarkerColorProperty() {
return intensifiedMarkerColor;
}
public Number[] getMarkerLineDashArray() {
return markerLineDashArray.get();
}
public ObjectProperty markerLineDashArrayProperty() {
return markerLineDashArray;
}
public void setMarkerLineDashArray(Number[] markerLineDashArray) {
this.markerLineDashArray.set(markerLineDashArray);
}
public double[] getMarkerLineDashes() {
return markerLineDashes.get();
}
public ObjectBinding markerLineDashesProperty() {
return markerLineDashes;
}
public double getLineWidth() {
return lineWidth.get();
}
public DoubleProperty lineWidthProperty() {
return lineWidth;
}
public void setLineWidth(double lineWidth) {
this.lineWidth.set(lineWidth);
}
public ObjectProperty lineColorProperty() {
return lineColor;
}
public void setLineColor(Paint lineColor) {
this.lineColor.set(lineColor);
}
public Paint getIntensifiedLineColor() {
return intensifiedLineColor.get();
}
public ObjectBinding intensifiedLineColorProperty() {
return intensifiedLineColor;
}
public Paint getLineFillPattern() {
return lineFillPattern.get();
}
public ObjectBinding lineFillPatternProperty() {
return lineFillPattern;
}
public Number[] getLineDashArray() {
return lineDashArray.get();
}
public ObjectProperty lineDashArrayProperty() {
return lineDashArray;
}
public void setLineDashArray(Number[] lineDashArray) {
this.lineDashArray.set(lineDashArray);
}
public double[] getLineDashes() {
return lineDashes.get();
}
public ObjectBinding lineDashesProperty() {
return lineDashes;
}
public double getLineMiterLimit() {
return lineMiterLimit.get();
}
public DoubleProperty lineMiterLimitProperty() {
return lineMiterLimit;
}
public void setLineMiterLimit(double lineMiterLimit) {
this.lineMiterLimit.set(lineMiterLimit);
}
public StrokeLineJoin getLineJoin() {
return lineJoin.get();
}
public ObjectProperty lineJoinProperty() {
return lineJoin;
}
public void setLineJoin(StrokeLineJoin lineJoin) {
this.lineJoin.set(lineJoin);
}
public StrokeLineCap getLineCap() {
return lineCap.get();
}
public ObjectProperty lineCapProperty() {
return lineCap;
}
public void setLineCap(StrokeLineCap lineCap) {
this.lineCap.set(lineCap);
}
// ======================== Utility methods ========================
/**
* Sets all styles that apply to a gc.strokeLine() call.
*
* @param gc target context
*/
public void applyLineStrokeStyle(GraphicsContext gc) {
gc.setMiterLimit(getLineMiterLimit());
gc.setLineJoin(getLineJoin());
gc.setLineCap(getLineCap());
gc.setLineWidth(getLineWidth());
gc.setLineDashes(getLineDashes());
gc.setStroke(getLineColor());
}
protected ObjectBinding intensifiedColor(ObservableValue base) {
return Bindings.createObjectBinding(() -> getIntensifiedColor(base.getValue()), base, intensity);
}
protected ObjectBinding hatchFillPattern(ObservableValue base) {
return Bindings.createObjectBinding(() -> {
var color = base.getValue();
if (color instanceof Color) {
color = ((Color) color).brighter();
}
// start at 1 to look better
var hatchShift = getHatchShiftByIndex() * (getGlobalIndex() + 1);
return FillPatternStyleHelper.getDefaultHatch(color, hatchShift);
}, base, globalIndex, hatchShiftByIndex);
}
protected Paint getIntensifiedColor(Paint color) {
if (getIntensity() >= 100 || !(color instanceof Color)) {
return color;
}
if (getIntensity() <= 0) {
return Color.TRANSPARENT;
}
var scale = getIntensity() / 100d;
return ((Color) color).deriveColor(0, scale, 1.0, scale);
}
@Override
public ReadOnlyLongProperty changeCounterProperty() {
return changeCounter;
}
protected void incrementChangeCounter() {
changeCounter.set(changeCounter.get() + 1);
}
protected > T addOnChange(T observable) {
PropUtil.runOnChange(this::incrementChangeCounter, observable);
return observable;
}
@Override
public Node getStyleableNode() {
return this;
}
protected CssPropertyFactory css() {
return CSS;
}
@Override
public List> getCssMetaData() {
return css().getCssMetaData();
}
private static final CssPropertyFactory CSS = new CssPropertyFactory<>(Parent.getClassCssMetaData());
}