You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中用ngx-echarts实现地图数据按年份动态切换的最优方案

Angular ngx-echarts 地图按年份动态切换最优实现方案

先修正你现有代码的明显问题

你的chartOptionsMap中series配置存在语法错误:[{ data: this.dataMap.dataGDP['2002'] }],这一行属于多余的非法嵌套,会导致ECharts无法解析配置,需要删除这一行,保留正确的data字段。

两种最优实现方案

方案一:使用ECharts原生Timeline组件(官方推荐,适合批量年份展示)

利用ECharts自带的timeline组件,可以快速实现年份的自动播放、手动切换,无需额外编写交互逻辑,适合需要展示年份序列变化的场景。

修改后的核心代码:

// 可选:定义年份数据类型提升类型安全
interface YearlyMapData {
  [year: string]: { name: string; value: number }[];
}

dataFormatter(obj: any): YearlyMapData {
  const pList = ['01', '15', '59'];
  const formattedData: YearlyMapData = {};
  for (let year = 2002; year <= 2011; year++) {
    const yearStr = year.toString();
    const temp = obj[yearStr];
    formattedData[yearStr] = temp.map((item: any, index: number) => ({
      name: pList[index],
      value: item.value
    }));
  }
  return formattedData;
}

mapFunction(chartData: CountsByDepartmentsModel[]): void {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  echarts.registerMap('france', franceMap, 'france');
  
  const yearlyData = this.dataFormatter({
    2011: [{name: '59', value: 5}, {name: '01', value: 2}, {name: '15', value: 3}],
    2010: [{name: '59', value: 10}, {name: '01', value: 4}, {name: '15', value: 6}],
    2009: [{name: '59', value: 15}, {name: '01', value: 6}, {name: '15', value: 9}],
    2008: [{name: '59', value: 20}, {name: '01', value: 8}, {name: '15', value: 12}],
    2007: [{name: '59', value: 25}, {name: '01', value: 10}, {name: '15', value: 15}],
    2006: [{name: '59', value: 30}, {name: '01', value: 12}, {name: '15', value: 18}],
    2005: [{name: '59', value: 35}, {name: '01', value: 14}, {name: '15', value: 21}],
    2004: [{name: '59', value: 40}, {name: '01', value: 16}, {name: '15', value: 24}],
    2003: [{name: '59', value: 45}, {name: '01', value: 18}, {name: '15', value: 27}],
    2002: [{name: '59', value: 50}, {name: '01', value: 20}, {name: '15', value: 30}]
  });

  const maxCount = chartData.reduce((a, {counts}) => Math.max(a, Number(counts)), -1);
  const years = Object.keys(yearlyData).sort();

  // 基础配置模板
  const baseOption = {
    tooltip: {
      show: true,
      trigger: 'item',
      showDelay: 0,
      transitionDuration: 0.2
    },
    visualMap: {
      left: 'right',
      min: 0,
      max: maxCount,
      inRange: {
        color: [
          '#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8',
          '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'
        ]
      },
      text: ['High', 'Low'],
      calculable: true
    },
    toolbox: {
      show: true,
      left: 'left',
      top: 'top',
      feature: {
        dataView: { readOnly: false },
        restore: {},
        saveAsImage: {}
      }
    }
  };

  this.chartOptionsMap = {
    timeline: {
      data: years,
      autoPlay: false,
      playInterval: 1000,
      left: 'center',
      bottom: 20
    },
    baseOption,
    options: years.map(year => ({
      series: [{
        type: 'map',
        colorBy: 'series',
        map: 'france',
        roam: true,
        nameProperty: 'code',
        label: { show: false },
        layoutCenter: ['50%', '50%'],
        layoutSize: 550,
        selectedMode: false,
        data: yearlyData[year]
      }]
    }))
  };
}

方案二:自定义年份选择器(灵活可控,适合联动场景)

如果需要和页面其他组件联动,或者自定义切换样式,可以自己实现年份选择控件,手动更新图表数据。

  1. 组件模板添加选择器:
<select (change)="onYearChange($event)">
  <option *ngFor="let year of years" [value]="year">{{year}}</option>
</select>
<echarts [options]="chartOptionsMap" style="width: 100%; height: 600px;"></echarts>
  1. 组件逻辑修改:
years: string[] = [];
chartOptionsMap: any;

mapFunction(chartData: CountsByDepartmentsModel[]): void {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  echarts.registerMap('france', franceMap, 'france');
  
  const yearlyData = this.dataFormatter({
    // 同方案一的年份数据
    2011: [{name: '59', value: 5}, {name: '01', value: 2}, {name: '15', value: 3}],
    // ...其他年份
    2002: [{name: '59', value: 50}, {name: '01', value: 20}, {name: '15', value: 30}]
  });
  this.years = Object.keys(yearlyData).sort();
  const defaultYear = this.years[0];

  const maxCount = chartData.reduce((a, {counts}) => Math.max(a, Number(counts)), -1);

  this.chartOptionsMap = {
    series: [{
      type: 'map',
      colorBy: 'series',
      map: 'france',
      roam: true,
      nameProperty: 'code',
      label: { show: false },
      layoutCenter: ['50%', '50%'],
      layoutSize: 550,
      selectedMode: false,
      data: yearlyData[defaultYear]
    }],
    tooltip: { /* 同之前配置 */ },
    visualMap: { /* 同之前配置 */ },
    toolbox: { /* 同之前配置 */ }
  };
}

onYearChange(event: Event): void {
  const selectedYear = (event.target as HTMLSelectElement).value;
  // 更新图表数据,ngx-echarts会自动刷新
  this.chartOptionsMap = {
    ...this.chartOptionsMap,
    series: [{
      ...this.chartOptionsMap.series[0],
      data: this.dataMap.dataGDP[selectedYear]
    }]
  };
}

方案选择建议

  • 若仅需单纯年份切换展示,优先选方案一,依托ECharts原生timeline减少自定义代码,自带播放、拖拽切换等功能。
  • 若需和业务组件联动或自定义切换UI,选方案二,灵活性更高。

内容的提问来源于stack exchange,提问作者MiMoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:09:53