This is an automated email from the ASF dual-hosted git repository.

sushuang pushed a commit to branch enhance-examples
in repository https://gitbox.apache.org/repos/asf/echarts-examples.git

commit a1a5ed24c3cf58b5696f25508005a5f9a1138b3b
Author: 100pah <[email protected]>
AuthorDate: Sat Aug 9 18:05:34 2025 +0800

    Fix and add examples.
---
 .../examples/ts/doc-example/geo-roam-indicator.js  |   2 +-
 public/examples/ts/matrix-grid-layout.js           | 407 +++++++++++++++++++++
 public/examples/ts/matrix-grid-layout.ts           | 192 ----------
 .../examples/ts/matrix-mini-bar-data-collection.ts | 108 ++++++
 public/examples/ts/matrix-mini-bar-geo.ts          | 256 +++++++++++++
 ...atrix-cartesian-tiny.js => matrix-sparkline.js} |   4 +-
 6 files changed, 774 insertions(+), 195 deletions(-)

diff --git a/public/examples/ts/doc-example/geo-roam-indicator.js 
b/public/examples/ts/doc-example/geo-roam-indicator.js
index a97017de..7742d99a 100644
--- a/public/examples/ts/doc-example/geo-roam-indicator.js
+++ b/public/examples/ts/doc-example/geo-roam-indicator.js
@@ -13,7 +13,7 @@ function updateChart() {
     geo: {
       id: 'my_geo',
       map: 'iceland',
-      aspectScale: Math.cos((65 * Math.PI) / 180),
+      aspectScale: Math.cos((65 * Math.PI) / 180), // 65 is Iceland's 
approximate latitude.
       animation: false,
 
       preserveAspect: app.config.preserveAspect,
diff --git a/public/examples/ts/matrix-grid-layout.js 
b/public/examples/ts/matrix-grid-layout.js
new file mode 100644
index 00000000..bf6bd64e
--- /dev/null
+++ b/public/examples/ts/matrix-grid-layout.js
@@ -0,0 +1,407 @@
+/*
+title: Responsive grid layout based on matrix
+category: matrix
+titleCN: 使用矩阵坐标系做网格布局
+difficulty: 3
+since: 6.0.0
+*/
+
+/**
+ * Use a matrix coordinate system to layout multiple charts and components,
+ * following the similar idea of CSS grid layout, and provide responsiveness
+ * by media queries.
+ */
+
+let _idBase = 1;
+
+const _mediaDefinitionList = [
+  {
+    // When the canvas width is less than 500px,
+    query: { maxWidth: 500 },
+    matrix: {
+      // Define column and rows
+      x: { data: Array(1).fill(null) },
+      y: { data: Array(10).fill(null) }
+    },
+    // Place sections into the matrix cell determined by the coords.
+    // key: sectionId, value: coord.
+    sectionCoordMap: {
+      'section_title_1': [0, 0],
+      'section_header_1': [0, [1, 2]],
+      'section_sidebar_1': [0, [3, 4]],
+      'section_main_content_area_1': [0, [5, 7]],
+      'section_footer_1': [0, [8, 9]],
+    }
+  },
+  {
+    // The default (with no `query`)
+    matrix: {
+      // Define column and rows
+      x: { data: Array(4).fill(null) },
+      y: { data: Array(10).fill(null) }
+    },
+    sectionCoordMap: {
+      'section_title_1': [[0, 3], 0],
+      'section_header_1': [[0, 3], [1, 2]],
+      'section_sidebar_1': [0, [3, 9]],
+      'section_main_content_area_1': [[1, 3], [3, 7]],
+      'section_footer_1': [[1, 3], [8, 9]],
+    }
+  }
+];
+
+/**
+ * Each section contains some charts and components.
+ */
+const _sectionDefinitionMap = {
+  'section_title_1': {
+    option: {
+      title: [{
+        coordinateSystem: 'matrix',
+        text: 'Resize the Canvas to Check the Responsiveness.',
+        left: 'center',
+        top: 10,
+      }],
+    }
+  },
+  'section_header_1': {
+    option: {
+      title: [{
+        coordinateSystem: 'matrix',
+        text: 'Header Section',
+        textStyle: { fontSize: 14 },
+        left: 'center',
+        top: 5
+      }],
+      xAxis: {
+        type: 'time',
+        id: 'header_1',
+        gridId: 'header_1'
+      },
+      yAxis: {
+        id: 'header_1',
+        gridId: 'header_1',
+        splitNumber: 2,
+        splitLine: {show: false},
+      },
+      grid: {
+        id: 'header_1',
+        coordinateSystem: 'matrix',
+        tooltip: {
+          trigger: 'axis'
+        },
+        top: 30,
+        bottom: 10,
+        left: 10,
+        right: 10,
+        outerBounds: {
+          top: 30,
+          left: 20,
+          bottom: 20,
+          right: 20,
+        }
+      },
+      series: {
+        type: 'line',
+        id: 'header_1',
+        xAxisId: 'header_1',
+        yAxisId: 'header_1',
+        symbol: 'none',
+        data: generateSingleSeriesData(100, false)
+      }
+    }
+  },
+  'section_sidebar_1': {
+    option: {
+      title: {
+        coordinateSystem: 'matrix',
+        text: 'Sidebar Section',
+        textStyle: { fontSize: 14 },
+        left: 'center',
+        top: 15
+      },
+      xAxis: {
+        id: 'sidebar_1',
+        gridId: 'sidebar_1',
+        splitLine: {show: false},
+        axisLabel: {
+          hideOverlap: true
+        }
+      },
+      yAxis: {
+        type: 'time',
+        id: 'sidebar_1',
+        gridId: 'sidebar_1',
+        axisLabel: {
+          hideOverlap: true
+        }
+      },
+      grid: {
+        id: 'sidebar_1',
+        coordinateSystem: 'matrix',
+        tooltip: {
+          trigger: 'axis'
+        },
+        top: 50,
+        bottom: 30,
+        left: 40,
+        right: 30,
+        outerBounds: {
+          top: 30,
+          left: 20,
+          bottom: 20,
+          right: 20,
+        }
+      },
+      series: {
+        type: 'bar',
+        id: 'sidebar_1',
+        xAxisId: 'sidebar_1',
+        yAxisId: 'sidebar_1',
+        data: generateSingleSeriesData(10, true)
+      }
+    }
+  },
+  'section_main_content_area_1': {
+    option: {
+      title: {
+        text: 'Main Content Area',
+        coordinateSystem: 'matrix',
+        textStyle: { fontSize: 14 },
+        left: 'center',
+        top: 15
+      },
+      xAxis: {
+        type: 'time',
+        id: 'main_content_area_1',
+        gridId: 'main_content_area_1'
+      },
+      yAxis: {
+        id: 'main_content_area_1',
+        gridId: 'main_content_area_1'
+      },
+      grid: {
+        id: 'main_content_area_1',
+        coordinateSystem: 'matrix',
+        tooltip: {
+          trigger: 'axis'
+        },
+        top: 50,
+        bottom: 10,
+        left: 10,
+        right: 10,
+        outerBounds: {
+          top: 30,
+          left: 20,
+          bottom: 20,
+          right: 20,
+        }
+      },
+      series: {
+        type: 'line',
+        id: 'main_content_area_1',
+        xAxisId: 'main_content_area_1',
+        yAxisId: 'main_content_area_1',
+        symbol: 'none',
+        data: generateSingleSeriesData(100, false)
+      }
+    }
+  },
+  'section_footer_1': {
+    option: {
+      title: {
+        coordinateSystem: 'matrix',
+        text: 'Footer Section',
+        textStyle: { fontSize: 14 },
+        left: 'center',
+        top: 15
+      },
+      xAxis: {
+        type: 'time',
+        id: 'footer_1',
+        gridId: 'footer_1'
+      },
+      yAxis: {
+        id: 'footer_1',
+        gridId: 'footer_1',
+        splitNumber: 2,
+        splitLine: {show: false},
+      },
+      grid: {
+        id: 'footer_1',
+        coordinateSystem: 'matrix',
+        tooltip: {
+          trigger: 'axis'
+        },
+        top: 50,
+        bottom: 10,
+        left: 20,
+        right: 20,
+        outerBounds: {
+          top: 30,
+          left: 20,
+          bottom: 20,
+          right: 20,
+        }
+      },
+      series: {
+        type: 'bar',
+        id: 'footer_1',
+        xAxisId: 'footer_1',
+        yAxisId: 'footer_1',
+        data: generateSingleSeriesData(10, false)
+      }
+    }
+  }
+};
+
+option = {
+
+  // Use the matrix coordinate system to layout the charts and components.
+  matrix: {
+    x: { show: false, data: [] },
+    y: { show: false, data: [] },
+    body: {
+      itemStyle: { borderColor: 'none' }
+    },
+    backgroundStyle: { borderColor: 'none' },
+    top: 0,
+    bottom: 0,
+    left: 0,
+    right: 0
+  },
+
+  tooltip: {},
+
+}; // End of option
+
+
+initFloatingControlPanel();
+
+assembleIntoEChartsOption(option, _sectionDefinitionMap, _mediaDefinitionList);
+
+console.log(option);
+
+
+/**
+ * Merge those definitions into the single echarts option.
+ * @param option The target echarts option to be written to.
+ */
+function assembleIntoEChartsOption(option, sectionDefinitionMap, 
mediaDefinitionList) {
+
+  option.media = mediaDefinitionList.map(({query, matrix}) => {
+    return {query, option: {matrix}};
+  });
+
+  Object.keys(sectionDefinitionMap).forEach(sectionId => {
+    const section = sectionDefinitionMap[sectionId];
+    const optionIdMapWillSetCoord = {};
+
+    Object.keys(section.option).forEach((componentMainType) => {
+      option[componentMainType] = normalizeToArray(option[componentMainType]);
+
+      normalizeToArray(section.option[componentMainType]).forEach((component) 
=> {
+        component = ensureComponentId(component, sectionId, componentMainType);
+        option[componentMainType].push(component);
+
+        if (component.coordinateSystem === 'matrix') {
+          optionIdMapWillSetCoord[componentMainType] = 
normalizeToArray(optionIdMapWillSetCoord[componentMainType]);
+          optionIdMapWillSetCoord[componentMainType].push(
+            component.id
+          );
+        }
+      });
+    });
+
+    mediaDefinitionList.forEach(({query, matrix, sectionCoordMap}, mediaIdx) 
=> {
+      const optionInMedia = option.media[mediaIdx].option;
+      const coord = sectionCoordMap[sectionId];
+      if (!coord) {
+        throw new Error(`Section with id "${sectionId}" not found in media 
definition index ${mediaIdx}.`);
+      }
+      Object.keys(optionIdMapWillSetCoord).forEach((componentMainType) => {
+        optionIdMapWillSetCoord[componentMainType].forEach((id) => {
+          optionInMedia[componentMainType] = 
normalizeToArray(optionInMedia[componentMainType]);
+          optionInMedia[componentMainType].push({
+            id: id,
+            coord: coord
+          });
+        });
+      });
+    });
+  });
+}
+
+/**
+ * If no component id, generate one, and immutablely return a new component 
object.
+ */
+function ensureComponentId(component, sectionId, componentMainType) {
+  if (component.id != null) {
+    return component;
+  }
+  component = Object.assign({}, component);
+  component.id = sectionId + '_' + componentMainType + '_' + _idBase++;
+  return component;
+}
+
+/**
+ * `{}` is converted to `[{}]`; null/undefined is converted to `[]`.
+ */
+function normalizeToArray(value) {
+  return Array.isArray(value) ? value : value != null ? [value] : [];
+}
+
+/**
+ * Generate some random data for a single series.
+ */
+function generateSingleSeriesData(dayCount, inverseXY) {
+  const dayStart = new Date('2025-05-05T00:00:00.000Z'); // Monday
+  const timeStart = dayStart.getTime();
+  const sevenDay = 7 * 1000 * 3600 * 24;
+  const seriesData = [];
+  let lastVal = +(Math.random() * 300).toFixed(0);
+
+  let turnCount = null;
+  let sign = -1;
+  for (let idx = 0; idx < dayCount; idx++) {
+    if (turnCount == null || idx >= turnCount) {
+      turnCount =
+        idx + Math.round((dayCount / 4) * ((Math.random() - 0.5) * 0.1));
+      sign = -sign;
+    }
+    const deltaMag = 50;
+    const delta = +(
+      Math.random() * deltaMag -
+      deltaMag / 2 +
+      (sign * deltaMag) / 3
+    ).toFixed(0);
+    const val = Math.max(0, (lastVal += delta));
+    const xTime = timeStart + idx * sevenDay;
+    const dataXVal = echarts.time.format(xTime, '{yyyy}-{MM}-{dd}');
+    const item = [dataXVal, val];
+    if (inverseXY) {
+      item.reverse();
+    }
+    seriesData.push(item);
+  }
+
+  return seriesData;
+}
+
+/**
+ * Note: The floating control panel are not relevant to echarts API,
+ *  just for illustration purposes.
+ */
+function initFloatingControlPanel() {
+  app.config = {};
+  app.configParameters = {};
+  app.config.showMatrixGrid = false;
+  app.configParameters.showMatrixGrid = { options: [false, true] };
+  app.config.onChange = function () {
+    myChart.setOption({
+      matrix: {
+        body: {itemStyle: {borderColor: app.config.showMatrixGrid ? 'red' : 
'none'}}
+      }
+    });
+  };
+}
diff --git a/public/examples/ts/matrix-grid-layout.ts 
b/public/examples/ts/matrix-grid-layout.ts
deleted file mode 100644
index 47663e82..00000000
--- a/public/examples/ts/matrix-grid-layout.ts
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
-title: Tiny Charts in Matrix (Line Charts)
-category: matrix
-titleCN: 矩阵坐标系中的微型折线图
-difficulty: 2
-since: 6.0.0
-*/
-
-const _matrixDimensionData = {
-  x: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
-  y: [
-    {value: '8:00\n~\n10:00'},
-    {value: '10:00\n~\n12:00'},
-    {value: '12:00\n~\n14:00', size: 55},
-    {value: '14:00\n~\n16:00'},
-    {value: '16:00\n~\n18:00'},
-    {value: '18:00\n~\n20:00'},
-  ]
-};
-const _yBreakTimeIndex = 2; // '12:00 - 14:00',
-const _seriesFakeDataLength = 365;
-
-
-option = {
-  matrix: {
-    x: {
-      data: _matrixDimensionData.x,
-      levelSize: 40,
-      label: {
-        fontSize: 16,
-        color: '#555'
-      }
-    },
-    y: {
-      data: _matrixDimensionData.y,
-      levelSize: 70,
-      label: {
-        fontSize: 14,
-        color: '#777'
-      }
-    },
-    corner: {
-      data: [
-        {
-          coord: [-1, -1],
-          value: 'Time'
-        }
-      ],
-      label: {
-        fontSize: 16,
-        color: '#777'
-      }
-    },
-    body: {
-      data: [
-        {
-          coord: [null, _yBreakTimeIndex],
-          coordClamp: true,
-          mergeCells: true,
-          value: 'Break',
-          label: {
-            color: '#999',
-            fontSize: 16
-          }
-        }
-      ]
-    },
-    top: 30,
-    bottom: 80,
-    width: '90%',
-    left: 'center'
-  },
-  tooltip: {
-    trigger: 'axis'
-  },
-  dataZoom: {
-    type: 'slider',
-    xAxisIndex: 'all',
-    left: '10%',
-    right: '10%',
-    bottom: 30,
-    height: 30,
-    throttle: 120
-  },
-  grid: [], // Fill it for each matrix cell below
-  xAxis: [], // Fill it for each matrix cell below
-  yAxis: [], // Fill it for each matrix cell below
-  series: [], // Fill it for each matrix cell below
-};
-
-eachMatrixCell((xval, yval, xidx, yidx) => {
-  const id = makeId(xidx, yidx);
-  option.grid.push({
-    id: id,
-    coordinateSystem: 'matrix',
-    coord: [xval, yval],
-    top: 10,
-    bottom: 10,
-    left: 'center',
-    width: '90%',
-    containLabel: true
-  });
-
-  option.xAxis.push({
-    type: 'category',
-    id: id,
-    gridId: id,
-    scale: true,
-    axisTick: { show: false },
-    axisLabel: { show: false },
-    axisLine: { show: false },
-    splitLine: { show: false }
-  });
-
-  option.yAxis.push({
-    id: id,
-    gridId: id,
-    interval: Number.MAX_SAFE_INTEGER,
-    scale: true,
-    axisLabel: {
-      showMaxLabel: true,
-      fontSize: 9
-    },
-    axisLine: { show: false },
-    axisTick: { show: false }
-  });
-
-  option.series.push({
-    xAxisId: id,
-    yAxisId: id,
-    type: 'line',
-    symbol: 'none',
-    lineStyle: {
-      lineWidth: 1
-    },
-    data: generateFakeSeriesData(_seriesFakeDataLength, xidx, yidx),
-  });
-});
-
-
-// ------ Helpers Start ------
-function makeId(xidx: number, yidx: number): string {
-  return `${xidx}|${yidx}`;
-}
-
-function eachMatrixCell(
-  cb: (xval: string, yval: string, xidx: number, yidx: number) => void
-): void {
-  _matrixDimensionData.y.forEach((yvalItem, yidx) => {
-    const yval = yvalItem.value;
-    if (yidx === _yBreakTimeIndex) {
-      return;
-    }
-    _matrixDimensionData.x.forEach((xval, xidx) => {
-      cb(xval, yval, xidx, yidx);
-    });
-  });
-}
-
-function generateFakeSeriesData(dayCount: number, xidx: number, yidx: number) {
-  const dayStart = new Date('2025-05-05T00:00:00.000Z'); // Monday
-  dayStart.setDate(xidx + 5);
-  const timeStart = dayStart.getTime();
-  const sevenDay = 7 * 1000 * 3600 * 24;
-  const cellData = [];
-  let lastVal = +(Math.random() * 300).toFixed(0);
-
-  let turnCount = null;
-  let sign = -1;
-  for (let idx = 0; idx < dayCount; idx++) {
-    if (turnCount == null || idx >= turnCount) {
-      turnCount =
-        idx + Math.round((dayCount / 4) * ((Math.random() - 0.5) * 0.1));
-      sign = -sign;
-    }
-    const deltaMag = 50;
-    const delta = +(
-      Math.random() * deltaMag -
-      deltaMag / 2 +
-      (sign * deltaMag) / 3
-    ).toFixed(0);
-    const val = Math.max(0, (lastVal += delta));
-    const xTime = timeStart + idx * sevenDay;
-    const dataXVal = echarts.time.format(xTime, '{yyyy}-{MM}-{dd}');
-    cellData.push([dataXVal, val]);
-  }
-
-  return cellData;
-}
-// ------ Helpers End ------
-
-export {};
diff --git a/public/examples/ts/matrix-mini-bar-data-collection.ts 
b/public/examples/ts/matrix-mini-bar-data-collection.ts
new file mode 100644
index 00000000..77782fde
--- /dev/null
+++ b/public/examples/ts/matrix-mini-bar-data-collection.ts
@@ -0,0 +1,108 @@
+/*
+title: Matrix Header Data Collection (Mini Bar)
+category: matrix
+titleCN: 矩阵坐标系表头数据自动收集(以微型条形图为例)
+noExplore: true
+difficulty: 3
+since: 6.0.0
+*/
+
+/**
+ * Each section contain some charts and components.
+ */
+
+function makeRenderItem(xDim: number, yDim: number, valDim: number, 
dataExtent: number[]): echarts.CustomSeriesRenderItem {
+  return function (params, api) {
+    const xval = api.value(xDim);
+    const yval = api.value(yDim);
+    const labelVal = api.value(valDim) as number;
+    const rect = api.layout!([xval, yval]).rect;
+    if (!rect) {
+        return;
+    }
+
+    const height = rect.height * 0.2;
+    const barY = rect.y + (rect.height - height) / 4 * 3;
+    const barX = rect.x + rect.width * 0.15;
+    const widthMax = rect.width * 0.5;
+    const width = linearMap(labelVal, dataExtent, [0, widthMax])
+    return {
+        type: 'group',
+        children: [{
+            type: 'rect',
+            shape: {x: barX, y: barY, width, height},
+            style: api.style({
+                fill: '#0ca8df',
+            }),
+        }, {
+            type: 'text',
+            x: barX,
+            y: rect.y + rect.height / 4 * 1.5,
+            style: {
+                text: labelVal + '',
+                fill: '#333',
+                align: 'left',
+                verticalAlign: 'middle',
+            },
+        }]
+    };
+  };
+}
+
+function linearMap(val: number, domain: number[], range: number[]) {
+    const d0 = domain[0];
+    const d1 = domain[1];
+    const r0 = range[0];
+    const r1 = range[1];
+    const subDomain = d1 - d0;
+    const subRange = r1 - r0;
+
+    return subDomain === 0 ? subRange === 0 ? r0 : (r0 + r1) / 2
+        : val === d0 ? r0
+        : val === d1 ? r1
+        : (val - d0) / subDomain * subRange + r0;
+}
+
+const _dataExtent = [0, 10000];
+
+option = {
+    dataset: {
+        source: [
+            ['2021-02-01', 'amount', 1212, 'file', 2321, 'Q', 1412],
+            ['2021-02-02', 'amount', 7181, 'file', 2114, 'Q', 1402],
+            ['2021-02-03', 'amount', 2763, 'file', 4212, 'Q', 8172],
+            ['2021-02-04', 'amount', 6122, 'file', 2942, 'Q', 6121],
+            ['2021-02-05', 'amount', 4221, 'file', 3411, 'Q', 1987],
+            ['2021-02-06', 'amount', 7221, 'file', 5121, 'Q', 1303],
+            ['2021-02-07', 'amount', 5121, 'file', 4121, 'Q', 1819],
+            ['2021-02-08', 'amount', 6121, 'file', 3121, 'Q', 2303],
+            ['2021-02-09', 'amount', 7121, 'file', 2121, 'Q', 3303],
+            ['2021-02-10', 'amount', 8121, 'file', 1121, 'Q', 4303],
+        ]
+    },
+    matrix: {
+      // matrix.x/y.data is not specified, which means they will be collected 
from
+      // `dataset.source` (or `series.data`, if any).
+      // All of values under the dimensions specified by `series.encode.x/y` 
will be
+      // auto-collected as `matrix.x/y.data`.
+      x: {levelSize: 50, itemStyle: {color: '#f0f8ff'}, label: {fontWeight: 
'bold'}},
+    },
+    series: [{
+        type: 'custom',
+        coordinateSystem: 'matrix',
+        encode: {x: 1, y: 0},
+        renderItem: makeRenderItem(1, 0, 2, _dataExtent),
+    }, {
+        type: 'custom',
+        coordinateSystem: 'matrix',
+        encode: {x: 3, y: 0},
+        renderItem: makeRenderItem(3, 0, 4, _dataExtent),
+    }, {
+        type: 'custom',
+        coordinateSystem: 'matrix',
+        encode: {x: 5, y: 0},
+        renderItem: makeRenderItem(5, 0, 6, _dataExtent),
+    }],
+};
+
+export {};
diff --git a/public/examples/ts/matrix-mini-bar-geo.ts 
b/public/examples/ts/matrix-mini-bar-geo.ts
new file mode 100644
index 00000000..9a18ea38
--- /dev/null
+++ b/public/examples/ts/matrix-mini-bar-geo.ts
@@ -0,0 +1,256 @@
+/*
+title: Mini Bars and GEO in Matrix
+category: matrix, bar, geo
+titleCN: 矩阵坐标系下的微型条形图和地图
+difficulty: 6
+since: 6.0.0
+*/
+
+var _colHeaders = ['Region and Time', 'Data A', 'Data B', 'Location'];
+var _regionColIdx = 0;
+var _geoColIdx = 3;
+type DataSourceList = {name: string; data: (number | string)[][];}[];
+var _dataSourceList: DataSourceList = [
+  {
+    name: '2021',
+    data: [
+      // 'Region', 'Data A', 'Data B'
+      ['Valais', 1212, 2321],
+      ['Ticino', 7181, 2114],
+      ['Graubünden', 2763, 4212],
+      ['Uri', 6122, 2942],
+      ['Lucerne', 4221, 3411],
+      ['Neuchâtel', 7221, 5121],
+      ['Jura', 5121, 4121],
+      ['Vaud', 6121, 3121],
+      ['Thurgau', 7121, 2121],
+      ['Schwyz', 8121, 1121],
+    ]
+  },
+  {
+    name: '2020',
+    data: [
+      // 'Region', 'Data A', 'Data B'
+      ['Valais', 1010, 2221],
+      ['Ticino', 7040, 1810],
+      ['Graubünden', 2313, 4011],
+      ['Uri', 6011, 2749],
+      ['Lucerne', 3329, 3015],
+      ['Neuchâtel', 7116, 4822],
+      ['Jura', 4968, 3820],
+      ['Vaud', 6027, 2928],
+      ['Thurgau', 7011, 1725],
+      ['Schwyz', 7311, 825],
+    ]
+  }
+];
+
+var _colorList = [
+    '#ffd10a',
+    '#0ca8df',
+    '#b6d634',
+    '#3fbe95',
+    '#5070dd',
+    '#ff994d',
+    '#505372',
+    '#fb628b',
+    '#785db0',
+];
+
+function createChart() {
+  option = {
+    matrix: {
+      x: {
+        levelSize: 40,
+        data: _colHeaders.map(function (item, colIdx) {
+          return {
+            value: item,
+            size: colIdx === _geoColIdx ? '15%'
+              : colIdx === _regionColIdx ? 120
+              : undefined
+          };
+        }),
+        itemStyle: {color: '#f0f8ff'},
+        label: { fontWeight: 'bold' }
+      },
+      y: {
+        data: _dataSourceList[0].data.map(function () {
+          return '_'; // Any value is fine here, as we will not use it.
+        }),
+        show: false,
+      },
+      body: {
+        data: []
+      },
+      top: 25
+    },
+    legend: {},
+    tooltip: {},
+    grid: [],
+    xAxis: [],
+    yAxis: [],
+    geo: [],
+    series: []
+  };
+
+  // Assume every dataSourceList[i] has the same length; just for simplicity 
in this demo.
+  var rowCount = _dataSourceList[0].data.length;
+
+  for (var dataColIdx = 0; dataColIdx < _colHeaders.length; ++dataColIdx) {
+    var dataExtentOnCol = (dataColIdx === _regionColIdx || dataColIdx === 
_geoColIdx)
+      ? null
+      : calculateDataExtentOnCol(_dataSourceList, dataColIdx);
+    for (var dataRowIdx = 0; dataRowIdx < rowCount; ++dataRowIdx) {
+      if (dataColIdx === _regionColIdx) {
+        addCellPlainText(
+          option, _dataSourceList, dataColIdx, dataRowIdx
+        );
+      }
+      else if (dataColIdx === _geoColIdx) {
+        addCellMiniGeo(
+          option, _dataSourceList, dataColIdx, dataRowIdx
+        );
+      }
+      else {
+        addCellMiniBar(
+          option, _dataSourceList, dataColIdx, dataRowIdx, dataExtentOnCol
+        );
+      }
+    }
+  }
+
+  myChart.setOption(option);
+}
+
+function calculateDataExtentOnCol(dataSourceList: DataSourceList, colIdx: 
number): number[] {
+  var min = Infinity;
+  var max = -Infinity;
+  dataSourceList.forEach(dataSource => {
+    dataSource.data.forEach(dataRow => {
+      var val = dataRow[colIdx] as number;
+      if (val < min) { min = val; }
+      if (val > max) { max = val; }
+    });
+  });
+  return [min, max];
+}
+
+function addCellPlainText(
+  option: echarts.EChartsOption,
+  dataSourceList: DataSourceList,
+  dataColIdx: number,
+  dataRowIdx: number,
+) {
+  // Assume every dataSourceList[i] has the same region names; just for 
simplicity in this demo.
+  var dataSource = dataSourceList[0];
+  (option.matrix as echarts.MatrixComponentOption)!.body!.data!.push({
+    value: dataSource.data[dataRowIdx][dataColIdx] as string,
+    coord: [dataColIdx, dataRowIdx], // coord in matrix, happens to be the 
same as `dataColIdx` here.
+  });
+}
+
+function addCellMiniBar(
+  option: echarts.EChartsOption,
+  dataSourceList: DataSourceList,
+  dataColIdx: number,
+  dataRowIdx: number,
+  dataExtentOnCol: number[] | null | undefined
+) {
+  var id = 'mini-bar-' + dataColIdx + '-' + dataRowIdx;
+  (option.grid as echarts.GridComponentOption[])!.push({
+    id: id,
+    coordinateSystem: 'matrix',
+    coord: [dataColIdx, dataRowIdx], // coord in matrix, happens to be the 
same as `dataColIdx` here.
+    top: '15%',
+    bottom: '15%',
+  });
+  (option.xAxis as echarts.XAXisComponentOption[])!.push({
+    id: id,
+    gridId: id,
+    type: 'value',
+    min: 0,
+    max: dataExtentOnCol ? dataExtentOnCol[1] : undefined,
+    scale: false,
+    axisLine: {show: false},
+    axisTick: {show: false},
+    splitLine: {show: false},
+    axisLabel: {show: false}
+  });
+  (option.yAxis as echarts.YAXisComponentOption[])!.push({
+    id: id,
+    gridId: id,
+    type: 'category',
+    boundaryGap: false,
+    inverse: true,
+    axisLine: {show: false},
+    axisTick: {show: false},
+    splitLine: {show: false},
+    axisLabel: {show: false}
+  });
+  dataSourceList.forEach((dataSource, dataSourceIdx) => {
+    (option.series as echarts.BarSeriesOption[])!.push({
+      type: 'bar',
+      // `name` will be collected to legend.
+      name: dataSource.name,
+      xAxisId: id,
+      yAxisId: id,
+      label: {show: true, position: 'insideLeft'},
+      barMinHeight: 2,
+      barGap: '40%',
+      barWidth: '40%',
+      itemStyle: {
+        color: _colorList[dataSourceIdx % _colorList.length]
+      },
+      encode: {label: 0},
+      // Make sure 2021 and 2020 have the same Y value (we use '' here) for 
better bar series layout.
+      data: [[dataSource.data[dataRowIdx][dataColIdx], '']]
+    });
+  });
+
+  return option;
+}
+
+function addCellMiniGeo(
+  option: echarts.EChartsOption,
+  dataSourceList: DataSourceList,
+  dataColIdx: number,
+  dataRowIdx: number
+) {
+  var id = 'mini-geo-' + dataRowIdx;
+  var regionName = dataSourceList[0].data[dataRowIdx][_regionColIdx] as string;
+
+  (option.geo as echarts.GeoComponentOption[])!.push({
+    id: id,
+    map: 'target_map',
+    animation: false,
+    aspectScale: Math.cos(47 * Math.PI / 180), // 47 is Switzerland's 
approximate latitude.
+    coordinateSystem: 'matrix',
+    coord: [dataColIdx, dataRowIdx], // coord in matrix, happens to be the 
same as `dataColIdx` here.
+    roam: false,
+    selectedMode: false,
+    tooltip: {show: false},
+    regions: [{
+      name: regionName,
+      selected: true,
+      select: {
+        itemStyle: {color: '#0a41e6'}
+      }
+    }],
+    select: {
+      label: {show: false},
+    },
+  });
+}
+
+function fetchGeoJSON() {
+  myChart.showLoading();
+  $.get(ROOT_PATH + '/data/asset/geo/ch.geo.json', function (geoJSON) {
+    echarts.registerMap('target_map', geoJSON);
+    createChart();
+    myChart.hideLoading();
+  });
+}
+
+fetchGeoJSON();
+
+export {};
diff --git a/public/examples/ts/matrix-cartesian-tiny.js 
b/public/examples/ts/matrix-sparkline.js
similarity index 98%
rename from public/examples/ts/matrix-cartesian-tiny.js
rename to public/examples/ts/matrix-sparkline.js
index cc34da50..d4ac5ef1 100644
--- a/public/examples/ts/matrix-cartesian-tiny.js
+++ b/public/examples/ts/matrix-sparkline.js
@@ -1,6 +1,6 @@
 /*
-title: Tiny Charts in Matrix (Line Charts)
-category: matrix
+title: Mini Line Charts (Sparkline) in Matrix
+category: matrix, line
 titleCN: 矩阵坐标系中的微型折线图
 difficulty: 5
 since: 6.0.0


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to