如何在动画化amCharts饼图中显示月份与日期?
I'm creating an animated timeline pie chart with amCharts, and I want to change the date display from just showing day numbers (like "Day 132") to showing month and day instead—since I have a large dataset, displaying "Day 132" isn't very intuitive.
I tried using conditional checks like if currentDay>=32 && currentDay<60 to define months, but it didn't work and this approach is inefficient. Here's the relevant code snippet:
<!-- Resources --> <script src="https://www.amcharts.com/lib/3/amcharts.js"></script> <script src="https://www.amcharts.com/lib/3/pie.js"></script> <script src="https://www.amcharts.com/lib/3/plugins/animate/animate.min.js"></script> <script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script> <link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" /> <script src="https://www.amcharts.com/lib/3/themes/light.js"></script> <script> var chartData = { "1": [ { "sector": "Subnautica", "size":0 }, { "sector": "DD", "size":0 }, // ... more data entries ], "132": [ { "sector": "Subnautica", "size":42.55 }, { "sector": "DD", "size":41.22 }, // ... more data entries ] }; /** * Create the chart */ var currentYear = 1; var chart = AmCharts.makeChart( "chartdiv6", { "type": "pie", "theme": "dark", "dataProvider": [], "valueField": "size", "titleField": "sector", "startDuration": 0, "innerRadius": 80, "pullOutRadius": 20, "outlineColor": "#FDB515", "marginTop": 30, "titles": [{ "text": "Odd's stream games" }], "allLabels": [{ "y": "54%", "align": "center", "size": 25, "bold": true, "text": "1995", "color": "#bb0a0c" }, { "y": "49%", "align": "center", "size": 15, "text": "Day", "color": "#bb0a0c" }], "listeners": [ { "event": "init", "method": function( e ) { var chart = e.chart; function getCurrentData() { var data = chartData[currentYear]; currentYear++; if (currentYear > 132) currentYear = 132; return data; } function loop() { chart.allLabels[0].text = currentYear; var data = getCurrentData(); chart.animateData( data, { duration: 350, complete: function() { setTimeout( loop, 650 ); } } ); } loop(); } } ], "export": { "enabled": false } } ); </script> <div id="chartdiv6" style="width: 40%; height: 500px; background-color: #1a1a1a;" ></div>
Instead of manually calculating months with messy conditional checks, use JavaScript's built-in Date object to handle date conversion automatically—it's cleaner, more reliable, and handles edge cases like leap years without extra code.
Here's how to implement this:
Step 1: Define a starting date
Pick a base date (matching the "1995" in your chart labels) as the starting point for day 1.
Step 2: Calculate the current date
Add currentYear - 1 days to the starting date (since day 1 equals the starting date).
Step 3: Format the date to show month and day
Use toLocaleDateString or manually extract month/day values to get your desired format (e.g., "MM-DD" or "January 1").
Modified Code Snippet
Here's the updated loop function with date conversion logic:
// Add this outside the init listener const startDate = new Date('1995-01-01'); // Day 1 = Jan 1, 1995 // Inside your init listener's loop function: function loop() { // Calculate current date based on the day number const currentDate = new Date(startDate); currentDate.setDate(startDate.getDate() + currentYear - 1); // Format to "MM-DD" (adjust options for different formats) const formattedDate = currentDate.toLocaleDateString('en-US', { month: '2-digit', day: '2-digit' }); // Update chart labels: keep the year, replace "Day" with month-day chart.allLabels[0].text = '1995'; chart.allLabels[1].text = formattedDate; var data = getCurrentData(); chart.animateData(data, { duration: 350, complete: function() { setTimeout(loop, 650); } }); }
Key Benefits:
- No Manual Date Logic: The
Dateobject automatically handles month transitions, 30/31-day months, and leap years—you don't have to code any of that. - Flexible Formatting: Adjust the
toLocaleDateStringoptions to match your preferred style:- Use
{ month: 'long', day: 'numeric' }for "January 1" - Use
{ month: 'short', day: 'numeric' }for "Jan 1"
- Use
- Cleaner, Maintainable Code: Ditch the nested conditionals for a concise, easy-to-read solution.
Optional Adjustments:
- If you want to keep the "Day X" label alongside the month-day format, add a third
allLabelsentry to display it. - Change the locale in
toLocaleDateString(e.g., 'fr-FR') for region-specific date formatting (like day/month order).
内容的提问来源于stack exchange,提问作者Bloggy

