当前位置: 首页 > 知识库问答 >
问题:

JavaFX:将轴的刻度标签放在刻度线的中间

韦胜泫
2023-03-14

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

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

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

考虑一下:

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

    < li >从2月1日开始渲染,到2月1日结束。此栏实际上是隐藏的,因为其宽度为0。 < li >从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);
        }
    }
});

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

共有1个答案

秦哲瀚
2023-03-14

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

这是完整的工作版本,我需要在< code>DateAxis中覆盖< code>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()使用getBoundsInPart()定位文本,这将考虑翻译。

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

@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.
     */
}
 类似资料:
  • 问题内容: 我可以用 但这也会删除标签。我可以以任何方式绘制刻度标签,但不能绘制刻度和书脊 问题答案: 您可以使用(http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.tick_params)将刻度长度设置为0 :

  • 如何在下面的屏幕截图中获得由红色附件突出显示的部分的宽度? 我试过了 是刻度的列表,但没有任何返回刻度宽度的方法,例如或任何此类方法。

  • 问题内容: 我有一个始终从x = 0开始的JFree XY折线图。然后,根据属性文件中用户定义的设置,应用程序将根据该数字(以分钟为单位)递增。 例如,x = 0开始时,用户定义的设置为5,因此刻度变为0、5、10、15、20…,或者用户设置为3,因此变为0、3、6、9、12…非常简单。 我遇到的问题是图表开始的方式。如果我从0开始,则0在图形的中间,而不是在左下角的-0.0000005,-0.0

  • 我正在利用SDSS(斯隆数字天空测量)的数据来绘制和分析恒星的光谱。为此,我从他们的网站下载了一个.csv文件,从中提取每一行及其数据,然后绘制这些数据。数据的格式是波长、通量、最佳拟合、天空通量,但我只对波长和最佳拟合感兴趣。我只是想提一下,这样我的代码就更有意义了。我试着每10个和100个数据点运行一次,但我无法解决我的问题。任何帮助都将不胜感激。SDSS网站上有一张想要的结果图,我将其粘贴在

  • 我正在使用JFreeChart创建y轴为“对数”的XylineChart,但我遇到了一个我似乎无法解决的错误。 在某些情况下,我的值非常低(在一个这样的情况下,y轴值的范围在4.5e-8到1.7112之间)。我在XYLineChart上绘制这些值,使用y轴的对数轴(并使用LogAxis.createLogTickUnits(区域设置)。在y轴上创建指数刻度单位)。我设定了我的范围从4.5e-8到1

  • 问题内容: 我已经用JFreeChart制作了以下图表: 替代文字 是否有可能(如果可以的话)在x轴上扩展日期,使其包含年份,例如。2010年4月2日,2010年5月2日,…,2010年6月3日? 问题答案: 目前尚不清楚,你现在是如何格式化日期,但 在 允许你指定一个合适的。 如果还没有,你应该能够覆盖 在 为罗马数字。 附录:为进行正确的本地化,执行以下操作可能会更容易