amcharts / amcharts4

The most advanced amCharts charting library for JavaScript and TypeScript apps.
https://www.amcharts.com/
1.16k stars 322 forks source link

Even gap labels with fixed start and end dates based on provided data #4310

Closed gedithejedi closed 1 year ago

gedithejedi commented 1 year ago

Question I have a Codepen linked below that needs to have the first and last dates that are the first and last dates in the data object. The main idea being that the labels need to be evenly spaced even after a new entry is added (which is done monthly). I have done it in the way its done (link 1) but that (hardcodes) the values in meaning the labels are mostly never evenly spaced. Something like the image below:

image

As I do not need zoom and values are updated monthly so hardcoding all is not an option, are there any other ways to approach this? I would appreciate any pointings in the right direction.

link 1. https://www.amcharts.com/docs/v4/tutorials/force-first-and-last-labels-on-axis/

CodePen (https://codepen.io/)

Environment (if applicable)

martynasma commented 1 year ago

You can add first and last labels using axis ranges like in the demo you linked to.

However, there's no way to ensure that labels in-between will be evenly spaced out.

The only option would be to calculate specific dates you want label to be displayed for, and add an axis range for each of those: https://www.amcharts.com/docs/v4/tutorials/using-axis-ranges-to-place-labels-at-arbitrary-values-or-dates/

gedithejedi commented 1 year ago

supratau, pasižiurėsiu ačiu :)

gedithejedi commented 1 year ago

For anyone else looking at this in the future

const firstDate = modifiedData[0];
const lastDate = modifiedData[modifiedData.length - 1];

let firstPoint = dateAxis.axisRanges.create();
firstPoint.date = firstDate.date;
firstPoint.label.text = firstDate.label;

let lastPoint = dateAxis.axisRanges.create();
lastPoint.date = lastDate.date;
lastPoint.label.text = lastDate.label;

// Calculate the time interval between the first and last date
const timeInterval = (lastDate.date - firstDate.date) / 8; // Divide by 8 to get 7 intervals

// Custom date formatting function with '.' separator
const dateFormatter = new Intl.DateTimeFormat('DE-de', { day: '2-digit', month: '2-digit', year: 'numeric' });

// Loop to create 7 evenly spaced intermediate points
for (let i = 1; i <= 7; i++) {
  const intermediateDate = new Date(firstDate.date.getTime() + i * timeInterval);

  var range = dateAxis.axisRanges.create();
  range.date = intermediateDate;
  range.label.text = dateFormatter.format(intermediateDate);
}