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]
