diff --git a/chartfx-chart/src/main/java/io/fair_acc/chartfx/axes/spi/AbstractAxis.java b/chartfx-chart/src/main/java/io/fair_acc/chartfx/axes/spi/AbstractAxis.java index 05eecac9a..0ceaabb11 100644 --- a/chartfx-chart/src/main/java/io/fair_acc/chartfx/axes/spi/AbstractAxis.java +++ b/chartfx-chart/src/main/java/io/fair_acc/chartfx/axes/spi/AbstractAxis.java @@ -17,7 +17,7 @@ import javafx.scene.CacheHint; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; -import javafx.scene.layout.Priority; +import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.text.Text; import javafx.scene.text.TextAlignment; @@ -542,11 +542,14 @@ private boolean isTickLabelRendered() { } private void applyOverlapPolicy(List tickMarks) { - // Default to all visible + // Start with everything being visible for (TickMark tickMark : tickMarks) { tickMark.setVisible(true); } + // Hide labels that would get cut off by the parent + hideLabelsOutsideParentBounds(tickMarks); + // Check whether any labels overlap. // Note: We technically only need to compute it for cases that // hide/modify labels, but we leave it in for diagnostics. @@ -557,7 +560,7 @@ private void applyOverlapPolicy(List tickMarks) { } // No overlap -> no need for an overlap policy - if (!labelOverlap) { + if (!labelOverlap || tickMarks.isEmpty()) { return; } @@ -573,7 +576,8 @@ private void applyOverlapPolicy(List tickMarks) { case SKIP_ALT: // make every other label visible to gain a factor 2 margin - for (int i = 1; i < tickMarks.size(); i += 2) { + int firstHidden = !tickMarks.get(0).isVisible() ? 0 : 1; + for (int i = firstHidden; i < tickMarks.size(); i += 2) { tickMarks.get(i).setVisible(false); } break; @@ -590,6 +594,43 @@ private void applyOverlapPolicy(List tickMarks) { } + /** + * Hides labels that can't be fully displayed due to the + * bounds of the parent container. This often manifests + * on the top of y axes when there is no title padding. + *

+ * Note that the layout bounds may not be available + * until the bounds phase, so we use layout x/y directly. + */ + private void hideLabelsOutsideParentBounds(List tickMarks) { + if (getParent() == null || !(getParent() instanceof Pane)) { + return; + } + if (getSide().isHorizontal()) { + final double offset = getLayoutX(); + final double parentWidth = ((Pane) getParent()).getWidth(); + for (TickMark tickMark : tickMarks) { + double width = tickMark.getWidth(); + double minLabel = tickMark.getPosition() - width / 2 + offset; + double maxLabel = tickMark.getPosition() + width / 2 + offset; + if (minLabel < 0 || maxLabel > parentWidth) { + tickMark.setVisible(false); + } + } + } else { + final double offset = getLayoutY(); + final double parentHeight = ((Pane) getParent()).getHeight(); + for (TickMark tickMark : tickMarks) { + double height = tickMark.getHeight(); + double minLabel = tickMark.getPosition() - height / 2 + offset; + double maxLabel = tickMark.getPosition() + height / 2 + offset; + if (minLabel < 0 || maxLabel > parentHeight) { + tickMark.setVisible(false); + } + } + } + } + @Deprecated // for testing purposes List computeTickMarks(AxisRange range, boolean major) { if (major) { diff --git a/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.css b/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.css index b765901e4..77046a552 100644 --- a/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.css +++ b/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.css @@ -133,9 +133,6 @@ .chart { -fx-tool-bar-side: TOP; } -.chart .chart-content { - -fx-padding: 5 0 0 0px; -} .chart .chart-title { visibility: visible; -fx-side: top; diff --git a/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.scss b/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.scss index 60e404394..6a3c084c8 100644 --- a/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.scss +++ b/chartfx-chart/src/main/resources/io/fair_acc/chartfx/chart.scss @@ -179,11 +179,6 @@ $null: null; // null gets removed from Sass. Maybe create a placeholder and repl // TODO: they don't seem to work and maybe we should create panes with a side property? deprecate these? -fx-tool-bar-side: TOP; - .chart-content { - // leave some top-axis overdraw-padding if there is no title - -fx-padding: 5 0 0 0px - } - .chart-title { visibility: visible; -fx-side: top;