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?

gerin
  • 392
  • 1
  • 3
  • 11

2 Answers2

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.

Angelo Bellocco
  • 121
  • 1
  • 5
  • 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 question – luchaos Oct 02 '18 at 06:28
  • 1
    as reference: https://github.com/swimlane/ngx-charts/issues/261#issuecomment-399131418 – luchaos Oct 02 '18 at 06:34
  • 1
    @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 @luchaos suggested might work. I will try this out and update. – gerin Oct 18 '18 at 04:55
3

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>
gerin
  • 392
  • 1
  • 3
  • 11