【问题标题】:JavaFX: Position Axis' tick label in the middle of tick marksJavaFX:将轴的刻度标签放在刻度线的中间
【发布时间】:2017-04-24 08:04:08
【问题描述】:

我需要移动轴中所有刻度线的标签 (Text),以使文本正好位于其自己的刻度线和下一个刻度线的中间。

我在 X 轴上使用 Roland 的 GanttChart 控件(经过一些修改)和 Christian Schudt 的 DateAxis。我的目标是根据日期值绘制甘特图(忽略时间;所有时间值都被截断)。

我的甘特图对每一个任务都有一个“开始日期”和一个“结束日期”(即在图表上它由一个条形表示)。

考虑一下:

我有一个任务从 2 月 1 日开始,并在同一天(2 月 1 日)结束。我有两种方法可以在图表上呈现它:

  1. 从 2 月 1 日开始渲染,到 2 月 1 日结束。这个栏实际上是隐藏的,因为它的宽度为 0。
  2. 从 2 月 1 日开始渲染,栏的右边缘触摸 2 月 2 日。这可能会使用户感到困惑,因为它看起来像是从 2 月 1 日开始到 2 月 2 日结束.

为了解决方法2引起的问题,我需要将文本标签向右移动半个刻度线宽度。这样做会让用户非常清楚。

我试过这样做:

final DateAxis xAxis = (DateAxis) this.ganttchart.getXAxis();
xAxis.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>()
{
    @Override
    public void onChanged(javafx.collections.ListChangeListener.Change<? extends Node> c)
    {
        final List<Node> labels = xAxis.getChildrenUnmodifiable().filtered(node -> node instanceof Text);

        for (Node label : labels)
        {
            label.setTranslateX(xAxis.getWidth() / (labels.size() - 1) / 2);
        }
    }
});

但是,这样做似乎根本不会将Text 标签向右移动。

【问题讨论】:

    标签: java javafx charts javafx-8 gantt-chart


    【解决方案1】:

    我尝试过的方法确实有效,但我遇到了竞态条件问题。如果我使用Platform.runLater(),它会正确移动。但是,每当我调整图表大小时,位置都会闪烁(它会在原始位置和移动位置之间跳转)。

    这是完整的工作版本,我需要在DateAxis 中覆盖layoutChildren()

    @Override
    protected void layoutChildren()
    {
        if (!isAutoRanging())
        {
            currentLowerBound.set(getLowerBound().getTime());
            currentUpperBound.set(getUpperBound().getTime());
        }
        super.layoutChildren();
    
        /*
         * Newly added codes.
         */
        final List<Node> labels = this.getChildrenUnmodifiable().filtered(node -> node instanceof Text);
        for (Node label : labels)
        {
            if (this.getSide() == Side.LEFT || this.getSide() == Side.RIGHT)
                label.setTranslateY(this.getHeight() / (labels.size() - 1) / 2);
            else if (this.getSide() == Side.TOP || this.getSide() == Side.BOTTOM)
                label.setTranslateX(this.getWidth() / (labels.size() - 1) / 2);
        }
        /*
         * End of new codes.
         */
    }
    

    更新

    仍有一些布局错误。这与Axis.positionTextNode() 使用getBoundsInParent() 定位文本有关,这考虑了翻译。

    这是新的工作版本,希望有一天它会对某人有所帮助。

    @Override
    protected void layoutChildren()
    {
        if (!isAutoRanging())
        {
            currentLowerBound.set(getLowerBound().getTime());
            currentUpperBound.set(getUpperBound().getTime());
        }
        super.layoutChildren();
    
        /*
         * Newly added codes.
         */
        final List<Node> labels = this.getChildrenUnmodifiable().filtered(node -> node instanceof Text);
        for (Node label : labels)
        {
            if (this.getSide().isHorizontal())
            {
                if (label.getTranslateX() == 0)
                    label.setTranslateX(this.getWidth() / (labels.size() - 1) / 2);
                else
                {
                    label.setLayoutX(label.getLayoutX() + label.getTranslateX());
                }
            }
            else if (this.getSide().isVertical())
            {
                if (label.getTranslateY() == 0)
                    label.setTranslateY(this.getHeight() / (labels.size() - 1) / 2);
                else
                {
                    label.setLayoutY(label.getLayoutY() + label.getTranslateY());
                }
            }
        }
        /*
         * End of new codes.
         */
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 2021-06-14
      • 2017-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多