如何在 amCharts5 中将日期从“Dec 01”转换为“2024-12-01”?
我正在使用 amCharts 在 Angular 中创建双轴图表。我收到的数据包括格式为“2024-12-01”的日期,但我需要将它们转换为 ISO 格式 2024-12-01,以便在图表的 X 轴上使用它们,但仍然显示 12 月 1 日和其他日期转换正常
为了解决这个问题,我使用 Date.parse 函数来转换日期。但是,我不确定这是否是最好的方法,或者是否有更有效或标准的方法可以在 JavaScript 中实现此目的。
export function createDetectionCountChart(config: any): void {
// Create root and apply theme
createRootAndSetTheme(config);
// Create chart container
let chart = config.root.container.children.push(am5xy.XYChart.new(config.root, {
panX: false, // Disable horizontal panning
panY: false, // Disable vertical panning (remove scrolling)
wheelX: 'none', // Disable wheel zooming horizontally
wheelY: 'none', // Disable wheel zooming vertically
pinchZoomX: false, // Disable pinch zooming horizontally
pinchZoomY: false, // Disable pinch zooming vertically
layout: config.root.verticalLayout,
width: am5.percent(100), // 100% width of its container
height: am5.percent(100), // 100% height of its container
background: am5.Rectangle.new(config.root, {
fill: am5.color(getTheme() == 'dark' ? '#1b1d24' : '#fff'),
fillOpacity: 1,
}),
}));
// Set global date format for the root
config.root.dateFormatter.set("dateFormat", "yyyy-MM-dd");
// Determine theme-based colors
const labelColor = getTheme() === 'dark' ? am5.color(0xFFFFFF) : am5.color(0x000000);
const gridColor = getTheme() === 'dark' ? am5.color(0xFFFFFF) : am5.color(0x000000);
const totalCountLabelColor = '#5249eb' // Total count color
const uniqueCountLabelColor = '#36CB79' // unique labels color
const data = config.data.map((item: any) => ({
date: Date.parse(item.date),
totalCount: item.totalCount,
uniqueCount: item.uniqueCount
}));
const totalCounts = data.map(item => item.totalCount);
const uniqueCounts = data.map(item => item.uniqueCount);
const totalCountMin = Math.min(...totalCounts);
const totalCountMax = Math.max(...totalCounts);
const uniqueCountMin = Math.min(...uniqueCounts);
const uniqueCountMax = Math.max(...uniqueCounts);
// Create Date axis (X-axis)
let xAxis = chart.xAxes.push(am5xy.DateAxis.new(config.root, {
maxDeviation: 0.2,
baseInterval: { timeUnit: "day", count: 1 },
renderer: am5xy.AxisRendererX.new(config.root, {}),
tooltipDateFormat: "yyyy-MM-dd",
gridIntervals:[{timeUnit: "day", count: 1}],
dateFormats:{day:"yyyy-MM-dd", week:"yyyy-MM-dd",month:"yyyy-MM-dd",year:"yyyy-MM-dd"},
extraMin: 0,
extraMax: 0
}));
xAxis.get("renderer").labels.template.setAll({
rotation: -45,
centerX: 0.5,
centerY: 1.5,
fontSize: 10,
dx: -40,
dy: 10,
fill: labelColor,
paddingBottom: 0,
marginLeft: 0,
});
xAxis.get("renderer").grid.template.setAll({ visible: false });
xAxis.get("renderer").setAll({ maxCategoryWidth: 120 });
// Create left Y-axis (for Total Count)
let yAxisLeft = chart.yAxes.push(am5xy.ValueAxis.new(config.root, {
renderer: am5xy.AxisRendererY.new(config.root, {}),
min: totalCountMin,
max: totalCountMax,
strictMinMax: true,
numberFormat: "#a",
// logarithmic: true, // Enable logarithmic scale
// logarithmicBase: Math.E, // Set the base of the logarithm (default is 10)
extraMin: 0,
extraMax: 0 // Prevent extra space on the top and bottom of the Y-axis
}));
yAxisLeft.get("renderer").labels.template.setAll({
fontSize: 10,
fontWeight: "400",
fill: labelColor
});
yAxisLeft.get("renderer").set("minGridDistance", 20);
yAxisLeft.get("renderer").grid.template.setAll({
stroke: gridColor,
strokeWidth: 1
});
yAxisLeft.children.push(am5.Label.new(config.root, {
text: "Total Count",
fontSize: 10,
fontWeight: "normal",
fill: totalCountLabelColor,
rotation: -90, // Rotate the text to make it vertical
x: am5.percent(0), // Position at the left edge (0% of the container width)
y: am5.percent(80), // Position slightly down (10% of the container height)
dx: -20, // Add offset to the X position
dy: 0,
}));
// Create right Y-axis (for Unique Count)
let yAxisRight = chart.yAxes.push(am5xy.ValueAxis.new(config.root, {
renderer: am5xy.AxisRendererY.new(config.root, { opposite: true }),
min: uniqueCountMin,
max: uniqueCountMax,
strictMinMax: true,
// logarithmic: true, // Enable logarithmic scale
// logarithmicBase: 10, // Set the base of the logarithm (default is 10)
numberFormat: "#a",
extraMin: 0.1,
extraMax: 0.1 // Prevent extra space on the top and bottom of the Y-axis
}));
yAxisRight.get("renderer").labels.template.setAll({
fontSize: 10,
fontWeight: "400",
fill: labelColor
});
yAxisRight.get("renderer").set("minGridDistance", 20);
yAxisRight.get("renderer").grid.template.setAll({ visible: false });
yAxisRight.children.push(am5.Label.new(config.root, {
text: "Unique Count",
fontSize: 10,
fontWeight: "normal",
fill: uniqueCountLabelColor,
rotation: -90, // Vertical text
x: am5.percent(0), // Position at the right edge (100% of the container width)
y: am5.percent(90), // Position slightly up (90% of the container height)
dx: 27.5, // Adjust X offset for rightward position
dy: -20, // Adjust Y offset for upward position
}));
// Add Total Count series (Bar chart)
let totalCountSeries = chart.series.push(am5xy.ColumnSeries.new(config.root, {
name: "Total Count",
xAxis: xAxis,
yAxis: yAxisLeft,
valueYField: "totalCount",
valueXField: "date",
clustered: false
}));
totalCountSeries.columns.template.setAll({ fill: am5.color('#5249eb'), width: am5.percent(40),tooltipText: "{valueY}" });
// Add Unique Count series (Line chart)
let uniqueCountSeries = chart.series.push(am5xy.LineSeries.new(config.root, {
name: "Unique Count",
xAxis: xAxis,
yAxis: yAxisRight,
valueYField: "uniqueCount",
valueXField: "date",
stroke: am5.color('#36CB79'), // line color
fill: am5.color('#36CB79') //
}));
uniqueCountSeries.strokes.template.setAll({ strokeWidth: 2, tooltipText: "{valueY}" });
uniqueCountSeries.bullets.push(() => am5.Bullet.new(config.root, {
sprite: am5.Circle.new(config.root, { radius: 5, fill: am5.color('#36CB79'), tooltipText: "{valueY}" })
}));
// Set data for series
totalCountSeries.data.setAll(data);
uniqueCountSeries.data.setAll(data);
// Add legend
let legend = chart.children.push(am5.Legend.new(config.root, {
useDefaultMarker: true,
paddingLeft: 30
}));
legend.markers.template.setAll({
width: 10,
height: 10
});
legend.labels.template.setAll({
fontSize: 10,
fontWeight: "400",
fill: labelColor
});
legend.data.setAll([totalCountSeries, uniqueCountSeries]);
}
[1]: https://i.sstatic.net/iVtIofj8.png
您可以将日期预处理为 iso fromat,然后再将其传递到图表
const data = config.data.map((item: any) => ({
date: new Date(item.date).toISOString(),
totalCount: item.totalCount,
uniqueCount: item.uniqueCount}));
您已经在 config.root.dateFormatter.set("dateFormat", "yyyy-MM-dd"); 中设置全局日期格式。但你也应该 在 xaxis 标签和工具提示中明确执行此操作
xAxis.get("renderer").labels.template.setAll({
rotation: -45,
centerX: 0.5,
centerY: 1.5,
fontSize: 10,
dx: -40,
dy: 10,
fill: labelColor,
paddingBottom: 0,
marginLeft: 0,
dateFormats: { day: "yyyy-MM-dd" }
});