[email protected]
Posts: 3
Joined: Tue Sep 17, 2024 3:02 pm

X-axis show only 12 months at a time

Hi! I'd like my x-axis to show only 12 months at a time, but also to be able to scroll through the entire chart using a two finger scroll on a trackpad. I realize you get the scrollbar to have the format exactly as I want with `scrollbar` and the `max`/`min` properties on the x-axis like so:

Code: Select all

 xAxis: [
        {
          tickInterval: 1000 * 60 * 60 * 24 * 30, // 1 month
          min: Date.UTC(2024, 0, 1),
          max: Date.UTC(2024, 11, 31),
          labels: {
            allowOverlap: true,
            format: "{value:%b}",
            style: {
              color: "#000000",
              font: "12px Power Centra, Helvetica Neue, Helvetica, Arial, sans_serif",
            },
          },
          scrollbar: {
            enabled: true,
          },
          units: [["month", [1]]],
        },
However, when I do that I cannot scroll to the right and left using the trackpad with two fingers. This is something my UX team wants. So I'd either like to set the range of 12 months at a time to show on the chart and use the scrolling built into the browser OR I'd like the scrollbar to allow me to use a two finger swipe. Are either of these possible?
jakub.s
Site Moderator
Posts: 1498
Joined: Fri Dec 16, 2022 11:45 am

Re: X-axis show only 12 months at a time

Hi,

Thanks for the question!

Here's an article about scrollbars in Highcharts with multiple examples: https://www.highcharts.com/docs/chart-c ... /scrollbar

The axis width and extremes there are constant; thus, you can show the 12-month range always. Here's a demo: https://jsfiddle.net/BlackLabel/n1vkyjz0/

Please take a look at the xAxis.min and xAxis.max as well as the comment that I've added there.

If that does not work for you, please create a minimal reproducible example where I will be able to investigate what might be going wrong and potentially propose a sensible solution.

Best regards!
Jakub
Highcharts Developer
[email protected]
Posts: 3
Joined: Tue Sep 17, 2024 3:02 pm

Re: X-axis show only 12 months at a time

Hi!

Thanks for your response.

In your example, I am only able to scroll through 20-45 and not see the rest of the chart if I set the min/max at 20/45. Is there a way I am able to just see that amount of the numbers (25) at a time but still be able to scroll through the entire chart using the trackpad?

So in my chart, which I can't seem to reproduce in jsfiddle, when I set the range to Jan-Dec, I am only able to scroll through Jan-Dec and not see the rest of the chart. However, when I remove the min/max I can see the entire chart, but the entire thing loads at once, so I see more than one year's worth of information on one screen. You can see that in my attachment.

I want to see one year of information on the screen but also be able to scroll through the rest of the information using two fingers on the trackpad to swipe through it. The scrollbar feature, which does exactly what I want otherwise, does not allow a user to swipe through it on the trackpad.

To say it another way: when I have set the min/max to twelve months starting with today, I can use the trackpad to swipe through from today to 12 months from now but not through the rest of the information. I can use the scrollbar feature to get to all of the information, but I cannot swipe. Is there some way to limit the amount of information seen on the screen AND still be able to use the trackpad to swipe through all the information?

I understand if you can't help because I can't get the fiddle to work, but hopefully you at least understand what I want.

Kelly

Here's my code in case it helps:

Code: Select all

    
    chart: {
      type: "gantt",
      scrollablePlotArea: {
        minWidth: 768,
        scrollable: "x",
        scrollPositionX: 1,
      },
    },
    plotOptions: {
      series: {
        dataLabels: {
          enabled: true,
          formatter: function () {
            const maxChars = Math.floor(this.point.shapeArgs.width / 7); // 7px is the average width of a character at an average font size
            const truncatedOkr = this.point.okr.length > maxChars ? this.point.okr.substring(0, maxChars - 3) + "..." : this.point.okr;

            return truncatedOkr;
          },
        },
      },
    },
    yAxis: {
      labels: {
        style: {
          color: "black",
          font: "12px Power Centra, Helvetica Neue, Helvetica, Arial, sans_serif",
        },
      },
      categories: teamData.map(team => team.name)
    },
    xAxis: [
      {
        tickInterval: 1000 * 60 * 60 * 24 * 30, // 1 month
        min: new Date().getTime(),
        max: new Date().setMonth(new Date().getMonth() + 11),
        labels: {
          allowOverlap: true,
          format: "{value:%b}",
          style: {
            color: "#000000",
            font: "12px Power Centra, Helvetica Neue, Helvetica, Arial, sans_serif",
          },
        },
        scrollbar: {
          enabled: true,
          margin: 0,
          showFull: false,
        },
        units: [
          [
            'month',
            [1]
          ]
        ]
      },
      {
        tickInterval: 1000 * 60 * 60 * 24 * 30,
        units: [[
          'month',
          [3]
        ],],
        labels: {
          align: "center",
          allowOverlap: true,
          formatter: function AxisLabelsFormatterCallbackFunction() {
            const providedLocalDate = new Date(this.value)
            const realDate = new Date(providedLocalDate.getTime() + (providedLocalDate.getTimezoneOffset() * 60 * 1000))
            const month = realDate.getMonth()
            const year = realDate.getFullYear()

            let quarterNumber;
            if (month >= 0 && month <= 2) {
              quarterNumber = 1;
            }
            if (month >= 3 && month <= 5) {
              quarterNumber = 2;
            }
            if (month >= 6 && month <= 8) {
              quarterNumber = 3;
            }
            if (month >= 9 && month <= 11) {
              quarterNumber = 4;
            }

            return `<div style="font-weight:bold; color:black;">Q${quarterNumber} ${year}</div>`;
          },
        },
      },
    ],
    tooltip: {
      headerFormat: '<span style="font-size:12px">{point.key}</span>',
      pointFormat:
        '<br><span style="font-weight:bold">{point.okr}</span><br><span>{point.start:%b %e} - {point.end:%b %e}</span>',
    },
    series: teamData
  };
`teamData` looks like:

Code: Select all

[
  {
    "name": "Transformers",
    "data": [
      {
        "name": "First Objective",
        "start": 1726545600000,
        "end": 1729569600000,
        "okr": "First Objective",
        "y": 0
      },
      {
        "name": "Transformer's Second Objective",
        "start": 1765342800000,
        "end": 1777435200000,
        "okr": "Transformer's Second Objective",
        "y": 0
      },
      {
        "name": "Far out Objective",
        "start": 1785902400000,
        "end": 1793768400000,
        "okr": "Far out Objective",
        "y": 0
      }
    ]
  },
  {
    "name": "New Team",
    "data": [
      {
        "name": "New Team's Objective",
        "start": 1737003600000,
        "end": 1743048000000,
        "okr": "New Team's Objective",
        "y": 1
      },
      {
        "name": "New Teams's Objective 2",
        "start": 1735707600000,
        "end": 1753848000000,
        "okr": "New Teams's Objective 2",
        "y": 1
      }
    ]
  },
  {
    "name": "Another Test Team",
    "data": [
      {
        "name": "Another Test Team's Objective",
        "start": 1726545600000,
        "end": 1733806800000,
        "okr": "Another Test Team's Objective",
        "y": 2
      },
      {
        "name": "Another Test Team's Objective 3",
        "start": 1739336400000,
        "end": 1757476800000,
        "okr": "Another Test Team's Objective 3",
        "y": 2
      }
    ]
  }
]
jakub.s
Site Moderator
Posts: 1498
Joined: Fri Dec 16, 2022 11:45 am

Re: X-axis show only 12 months at a time

Thanks!

Yes, you're right, sorry for misunderstanding, now I understand that the demo that I've sent was not what you were trying to achieve.

In that case, you may want to look into Highcharts Stock which is specifically designed for date-time x-axis and has already built-in navigator and range selector. I've prepared a demo which has a fixed 12-month window which you can use to scroll all your data: https://jsfiddle.net/BlackLabel/qchkym8p/

There is actually much more that you can achieve, you can load data asynchronously when scrolling: https://www.highcharts.com/demo/stock/lazy-loading and you have many more series types (like OHLC) and indicators. You can check all of that here: https://www.highcharts.com/demo#highcha ... mo-general

For standard Highcharts scrollbar, there is no solution to achieve that out of the box. However, you can try experimenting with adjusting the width of the container or the axis programatically in the chart.events.load event. I've prepared a simple demo here: https://jsfiddle.net/BlackLabel/zd0cwnav/ which shows the idea. It will require, however, making a few decisions yourself - do you want to manipulate the chart's container width? Or do you want to reduce the distances between Highcharts points? Writing a piece of custom logic will be required.

Please do not hesitate to ask in case you have any more questions about this.

Best regards!
Jakub
Highcharts Developer
[email protected]
Posts: 3
Joined: Tue Sep 17, 2024 3:02 pm

Re: X-axis show only 12 months at a time

Thanks, Jakub! I'll take a closer look and let you know.

Return to “Highcharts Gantt”