0

I need to move the label (Text) of all tick marks in an Axis such that the text is right in the middle of its own tick mark and the next tick mark.

I am using Roland's GanttChart control (with some modifications) and Christian Schudt's DateAxis for my X-axis. My objective is to plot a gantt chart based on Date values (ignoring time; all time values are truncated).

My gantt chart has a "start date" and an "end date" for every single task (i.e. visually on the chart it is represented by a single bar).

Consider this:

I have a task starting on 1st Feb, and it ends on the same day (1st Feb). I have two ways to render this on the chart:

  1. Render it starting from 1st Feb, and ends at 1st Feb. This bar is effectively hidden, because its width is 0.
  2. Render it starting from 1st Feb, with the right-edge of the bar touching 2nd Feb. This can potentially confuse the users because it would look like it starts from 1st Feb and ends on 2nd Feb.

To solve the problem caused by method 2, I need to shift the text labels by half a tick mark width to the right. Doing this would make it very clear to the user.

I have tried doing this:

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);
        }
    }
});

However, doing so does not seem to shift the Text labels to the right at all.

Community
  • 1
  • 1
Jai
  • 8,165
  • 2
  • 21
  • 52

1 Answers1

0

The method I had tried actually works, but I was having problem with race condition. If I used Platform.runLater(), it would shift correctly. However, the position flickers whenever I resize the chart (it would jump between original position and shifted position).

This is the complete working version, which I need to override layoutChildren() in DateAxis.

@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.
     */
}

Update

There was still some layout bugs. It has to do with the fact that Axis.positionTextNode() positions the texts using getBoundsInParent(), which takes into consider the translation.

This is the new working version, hopefully someday it would be helpful to someone.

@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.
     */
}
Jai
  • 8,165
  • 2
  • 21
  • 52