How to change xAxisTickFormatting in ngx-charts-line-chart based on timeline selection?
Asked Answered
A

2

10

By default, ticks are formatted based on time range selection in timeline. If it pans across days it shows month and if it is with in a day, it shows only time. This is great!

Now I want to localize these ticks. I could provide xAxisTickFormatting to get this done but I want to have the formatting based on the time range selection. "MMM DD" or "HH:MM" based on the current time range selection.

For this I need to change the formatting function dynamically on time range selection event. Is there such an event? Or is there any other way to achieve this?

Antigorite answered 26/6, 2018 at 5:23 Comment(0)
A
4

It looks like, date is formatted based on the d3 logic. It uses the precision available to that tick. So if date is 12/15/2020 11:30:00, precision is at minute level. Similarly if date is 12/15/2020 00:00:00, precision is at day level. Now we can choose the format options accordingly.

var locale = 'fr-FR'; // 'en-US'
function formatDate(value) {
  let formatOptions;
  if (value.getSeconds() !== 0) {
    formatOptions = { second: '2-digit' };
  } else if (value.getMinutes() !== 0) {
    formatOptions = { hour: '2-digit', minute: '2-digit' };
  } else if (value.getHours() !== 0) {
    formatOptions = { hour: '2-digit' };
  } else if (value.getDate() !== 1) {
    formatOptions = value.getDay() === 0 ? { month: 'short', day: '2-digit' } : { weekday: 'short', day: '2-digit' };
  } else if (value.getMonth() !== 0) {
    formatOptions = { month: 'long' };
  } else {
    formatOptions = { year: 'numeric' };
  }
  return new Intl.DateTimeFormat(locale, formatOptions).format(value);
}

var dates = ['12/15/2020 11:30:30', '12/15/2020 11:30:00', '12/15/2020 11:00:00', '12/15/2020 00:00:00', '12/13/2020 00:00:00', '12/01/2020 00:00:00', '01/01/2020 00:00:00'];
for (date of dates) {
  console.log(date, '=>', formatDate(new Date(date)));
}

Now this function can be used as

<ngx-charts-line-chart 
    [xAxis]="true" 
    [xAxisTickFormatting]="formatDate">
</ngx-charts-line-chart>
Antigorite answered 14/4, 2020 at 9:47 Comment(0)
M
12

In your chart, among the other attributes, you can declare

<ngx-charts-bar-horizontal-normalized
    ...
    [xAxis]="true"
    [xAxisTickFormatting]='formatPercent'
    ...
</ngx-charts-bar-horizontal-normalized>

formatPercent is a function declared in your .ts file (I'm using Angular) written like

formatPercent(val) {
    if (val <= 100) {
      return val + '%';
    }
  } 

For any reference check the documentation here

Hope this helps.

Mcbrayer answered 8/9, 2018 at 8:15 Comment(3)
if you change it to a function like this formatPercent = (val) => { // access to local variables now } then you have access to the local variable scope as well. which is needed to be able to have conditional formatting. otherwise this answer doesn't fully address the questionCooksey
as reference: github.com/swimlane/ngx-charts/issues/…Cooksey
@angelo, I am aware of xAxisTickFormatting as mentioned in the question. I am looking to format based on the time range (same day - HH:MM, across days - MMM DD). For this I need to access to local variables. I think what @Cooksey suggested might work. I will try this out and update.Antigorite
A
4

It looks like, date is formatted based on the d3 logic. It uses the precision available to that tick. So if date is 12/15/2020 11:30:00, precision is at minute level. Similarly if date is 12/15/2020 00:00:00, precision is at day level. Now we can choose the format options accordingly.

var locale = 'fr-FR'; // 'en-US'
function formatDate(value) {
  let formatOptions;
  if (value.getSeconds() !== 0) {
    formatOptions = { second: '2-digit' };
  } else if (value.getMinutes() !== 0) {
    formatOptions = { hour: '2-digit', minute: '2-digit' };
  } else if (value.getHours() !== 0) {
    formatOptions = { hour: '2-digit' };
  } else if (value.getDate() !== 1) {
    formatOptions = value.getDay() === 0 ? { month: 'short', day: '2-digit' } : { weekday: 'short', day: '2-digit' };
  } else if (value.getMonth() !== 0) {
    formatOptions = { month: 'long' };
  } else {
    formatOptions = { year: 'numeric' };
  }
  return new Intl.DateTimeFormat(locale, formatOptions).format(value);
}

var dates = ['12/15/2020 11:30:30', '12/15/2020 11:30:00', '12/15/2020 11:00:00', '12/15/2020 00:00:00', '12/13/2020 00:00:00', '12/01/2020 00:00:00', '01/01/2020 00:00:00'];
for (date of dates) {
  console.log(date, '=>', formatDate(new Date(date)));
}

Now this function can be used as

<ngx-charts-line-chart 
    [xAxis]="true" 
    [xAxisTickFormatting]="formatDate">
</ngx-charts-line-chart>
Antigorite answered 14/4, 2020 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.