AmCharts4实现下拉选择仅展示3个年份数据系列的方案咨询
AmCharts4 实现下拉选择展示指定年份系列
实现方案
1. 核心逻辑
- 一次性加载全量数据,通过缓存机制动态创建/切换系列,避免重复初始化组件
- 使用HTML下拉框(或AmCharts原生下拉组件)选择3个目标年份
- 切换时隐藏所有未选中的系列和轴,仅展示选中项
2. 完整代码实现
HTML部分(下拉选择组件)
<div style="margin-bottom: 10px;"> <label>年份1:</label> <select id="year1"></select> <label>年份2:</label> <select id="year2"></select> <label>年份3:</label> <select id="year3"></select> <button onclick="updateChart()" style="margin-left: 10px;">更新图表</button> </div> <div id="chartdiv" style="width: 100%; height: 500px;"></div>
JavaScript部分(图表逻辑)
// 全局缓存:已创建的系列和轴,避免重复初始化 let seriesCache = {}; let axisCache = {}; let allYearFields = []; // 初始化图表容器 const chart = am4core.create("chartdiv", am4charts.XYChart); chart.dataSource.url = "ejemplodatos.php"; // 数据加载完成后初始化下拉框和默认图表 chart.dataSource.events.on("done", function(ev) { // 提取所有年份字段(假设字段格式为aYYYY) const firstDataItem = ev.target.data[0]; allYearFields = Object.keys(firstDataItem) .filter(key => key.startsWith("a")) .map(key => ({ field: key, label: key.slice(1) })); // 填充三个下拉选择框 populateYearSelects(allYearFields); // 默认选中最近3年 const defaultYears = allYearFields.slice(-3); document.getElementById("year1").value = defaultYears[0].field; document.getElementById("year2").value = defaultYears[1].field; document.getElementById("year3").value = defaultYears[2].field; // 渲染初始图表 updateChart(); }); // 填充下拉选择框 function populateYearSelects(yearList) { ["year1", "year2", "year3"].forEach(selectId => { const select = document.getElementById(selectId); select.innerHTML = ""; yearList.forEach(year => { const option = document.createElement("option"); option.value = year.field; option.textContent = year.label; select.appendChild(option); }); }); } // 复用你的系列创建逻辑,加入缓存机制 function createAxisAndSeries(field, name, opposite = false, bullet = "default") { // 已缓存直接返回,避免重复创建 if (seriesCache[field]) { return { series: seriesCache[field], axis: axisCache[field] }; } const valueAxis = chart.yAxes.push(new am4charts.ValueAxis()); if (chart.yAxes.indexOf(valueAxis) !== 0) { valueAxis.syncWithAxis = chart.yAxes.getIndex(0); } const series = chart.series.push(new am4charts.LineSeries()); series.dataFields.valueY = field; series.dataFields.categoryX = "mesdia"; series.strokeWidth = 2; series.name = name; series.tooltipText = "{name}: [bold]{valueY}[/]"; series.minBulletDistance = 10; const interfaceColors = new am4core.InterfaceColorSet(); switch(bullet) { case "triangle": valueAxis.renderer.line.disabled = true; valueAxis.renderer.labels.template.disabled = true; valueAxis.renderer.grid.template.disabled = true; const bulletEl = series.bullets.push(new am4charts.Bullet()); bulletEl.width = 1; bulletEl.height = 1; bulletEl.horizontalCenter = "middle"; bulletEl.verticalCenter = "middle"; const triangle = bulletEl.createChild(am4core.Triangle); triangle.stroke = interfaceColors.getFor("background"); triangle.strokeWidth = 2; triangle.direction = "top"; triangle.width = 1; triangle.height = 1; break; default: const circleBullet = series.bullets.push(new am4charts.CircleBullet()); circleBullet.circle.stroke = interfaceColors.getFor("background"); circleBullet.width = 1; circleBullet.height = 1; circleBullet.circle.strokeWidth = 2; break; } valueAxis.renderer.line.strokeOpacity = 1; valueAxis.renderer.line.strokeWidth = 2; valueAxis.renderer.line.stroke = series.stroke; valueAxis.renderer.labels.template.fill = series.stroke; valueAxis.renderer.opposite = opposite; valueAxis.renderer.grid.template.disabled = true; // 缓存当前创建的系列和轴 seriesCache[field] = series; axisCache[field] = valueAxis; return { series, axis }; } // 更新图表:隐藏所有系列,仅显示选中的3个 function updateChart() { // 获取选中的年份字段,过滤空值 const selectedFields = [ document.getElementById("year1").value, document.getElementById("year2").value, document.getElementById("year3").value ].filter(Boolean); // 隐藏所有已创建的系列和轴 Object.values(seriesCache).forEach(series => series.hide()); Object.values(axisCache).forEach(axis => axis.hide()); // 显示选中的系列(不存在则创建) selectedFields.forEach(field => { const yearLabel = field.slice(1); const { series, axis } = createAxisAndSeries(field, yearLabel); series.show(); axis.show(); }); // 触发图表重绘 chart.invalidateRawData(); }
PHP接口要求(ejemplodatos.php)
确保返回的JSON数据格式符合以下结构,包含mesdia(分类轴字段)和多个aYYYY格式的年份数值字段:
<?php // 示例数据,实际从数据库查询获取 $data = [ ["mesdia" => "1月", "a2024" => 120, "a2023" => 100, "a2022" => 90, "a2021" => 85], ["mesdia" => "2月", "a2024" => 150, "a2023" => 130, "a2022" => 110, "a2021" => 95], // 更多月份数据... ]; header('Content-Type: application/json'); echo json_encode($data); ?>
可选优化
- 禁止重复选年份:在下拉框
onchange事件中,移除其他下拉框已选中的选项 - 使用AmCharts原生下拉组件:替换HTML select为AmCharts的
Dropdown,风格更统一 - 默认选中逻辑:可根据业务需求调整默认选中的年份(如最近3年、特定年份)
内容的提问来源于stack exchange,提问作者vane_bdm
相关产品推荐
相关产品推荐

