| <!DOCTYPE html> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| --> |
| |
| |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| <script src="lib/simpleRequire.js"></script> |
| <script src="lib/config.js"></script> |
| <script src="lib/jquery.min.js"></script> |
| <script src="lib/facePrint.js"></script> |
| <!-- <script src="lib/testHelper.js"></script> --> |
| <!-- <script src="ut/lib/canteen.js"></script> --> |
| <link rel="stylesheet" href="lib/reset.css" /> |
| </head> |
| <body> |
| <style> |
| h1, h2, h3, p { |
| margin-left: 15px; |
| } |
| |
| #main0 { |
| display: flex; |
| flex-direction: row; |
| flex-wrap: nowrap; |
| overflow-x: auto; |
| width: 100%; |
| } |
| |
| .section { |
| width: 500px; |
| flex-shrink: 0; |
| margin-right: 30px; |
| padding-bottom: 30px; |
| } |
| |
| .chart-item { |
| width: 100%; |
| height: 400px; |
| border: 1px solid #ccc; |
| margin: 10px; |
| flex-shrink: 0; |
| } |
| |
| #main1, #main0 { |
| width: 4800px; |
| } |
| |
| .chart-item-h { |
| width: 500px; |
| height: 400px; |
| border: 1px solid #ccc; |
| margin: 10px 20px 10px 10px; |
| display: inline-block; |
| } |
| |
| @media (prefers-color-scheme: dark) { |
| body { |
| background-color: #000; |
| color: #ccc; |
| } |
| h1, h2, h3 { |
| color: #fff; |
| } |
| |
| .chart-item-h, .chart-item { |
| border-color: #444; |
| } |
| } |
| </style> |
| <p>Set system dark mode to see dark mode charts.</p> |
| |
| <h2>Typical charts of different series count</h2> |
| <div id="main0"></div> |
| |
| <h2>Components</h2> |
| <div id="main1"> |
| </div> |
| |
| |
| |
| |
| |
| |
| <script> |
| require([ |
| 'echarts', |
| './data/usa.json' |
| // 'map/js/china', |
| // './data/nutrients.json' |
| ], function (echarts, geojson) { |
| const charts = []; |
| |
| const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); |
| function updateDarkMode() { |
| const isDarkMode = darkModeMediaQuery.matches; |
| for (const chart of charts) { |
| chart.setTheme(isDarkMode ? 'dark' : 'default'); |
| } |
| } |
| darkModeMediaQuery.addEventListener('change', () => { |
| updateDarkMode(); |
| }); |
| |
| echarts.registerMap('USA', geojson, { |
| Alaska: { |
| left: -131, |
| top: 25, |
| width: 15 |
| }, |
| Hawaii: { |
| left: -110, |
| top: 28, |
| width: 5 |
| }, |
| 'Puerto Rico': { |
| left: -76, |
| top: 26, |
| width: 2 |
| } |
| }); |
| |
| for (let maxSeriesCount = 1; maxSeriesCount <= 9; maxSeriesCount++) { |
| |
| const cases = [ |
| { |
| type: 'bar', |
| data: 'data2d' |
| }, |
| { |
| type: 'line', |
| data: 'data2d' |
| }, |
| { |
| type: 'pie', |
| data: 'data1d' |
| }, |
| { |
| type: 'scatter', |
| data: 'data2d' |
| }, |
| { |
| type: 'funnel', |
| data: 'data1d' |
| }, |
| { |
| type: 'radar', |
| data: 'data1d' |
| }, |
| { |
| type: 'treemap', |
| data: 'dataTree' |
| }, |
| { |
| type: 'sunburst', |
| data: 'dataTree' |
| }, |
| { |
| type: 'themeRiver', |
| data: 'data3d' |
| } |
| ]; |
| |
| function getData3d() { |
| const data = []; |
| for (let s = 0; s < maxSeriesCount; s++) { |
| for (let i = 0; i < 5; ++i) { |
| data.push([i, Math.random() * 100, 'S' + s]); |
| } |
| } |
| return data; |
| } |
| |
| function getData2d(base) { |
| return [ |
| ['Q1', Math.random() * 100 + base], |
| ['Q2', Math.random() * 100 + base], |
| ['Q3', Math.random() * 100 + base], |
| ['Q4', Math.random() * 100 + base] |
| ]; |
| } |
| |
| function getData1d() { |
| const data = []; |
| for (let i = 0; i < maxSeriesCount; i++) { |
| data.push({ |
| name: `Data ${i + 1}`, |
| value: (Math.random() + maxSeriesCount - i) * 100, |
| }); |
| } |
| return data; |
| } |
| |
| function getNodesData() { |
| const data = []; |
| // 2 levels |
| for (let i = 0; i < maxSeriesCount; i++) { |
| const children = []; |
| for (let j = 0; j < 3; j++) { |
| const grandChildren = []; |
| for (let k = 0; k < 3; k++) { |
| grandChildren.push({ |
| name: `Data ${i + 1}-${j + 1}-${k + 1}`, |
| value: Math.random() * 100, |
| }); |
| } |
| children.push({ |
| name: `Data ${i + 1}-${j + 1}`, |
| children: grandChildren, |
| }); |
| } |
| data.push({ |
| name: `Data ${i + 1}`, |
| children |
| }); |
| } |
| return data; |
| } |
| |
| const section = document.createElement('div'); |
| section.className = 'section'; |
| document.getElementById('main0').appendChild(section); |
| const sectionTitle = document.createElement('h3'); |
| sectionTitle.textContent = `Count: ${maxSeriesCount}`; |
| section.appendChild(sectionTitle); |
| |
| for (const c of cases) { |
| const div = document.createElement('div'); |
| div.className = 'chart-item'; |
| section.appendChild(div); |
| |
| const chart = echarts.init(div, null, { |
| // renderer: 'svg' |
| }); |
| charts.push(chart); |
| |
| const series = []; |
| switch (c.data) { |
| case 'data1d': |
| series.push({ |
| type: c.type, |
| data: getData1d(), |
| }); |
| break; |
| |
| case 'data2d': |
| for (let i = 0; i < maxSeriesCount; i++) { |
| series.push({ |
| type: c.type, |
| data: getData2d((maxSeriesCount - i) * 100), |
| name: `Series ${i + 1}`, |
| }); |
| } |
| break; |
| |
| case 'data3d': |
| series.push({ |
| type: c.type, |
| data: getData3d() |
| }); |
| break; |
| |
| case 'dataTree': |
| series.push({ |
| type: c.type, |
| data: getNodesData() |
| }); |
| break; |
| } |
| |
| const option = { |
| title: { |
| text: `A ${c.type} chart`, |
| }, |
| series: series, |
| legend: { |
| show: true |
| } |
| }; |
| |
| if (['line', 'bar', 'scatter'].includes(c.type)) { |
| option.xAxis = { |
| type: 'category' |
| }; |
| option.yAxis = { |
| type: 'value' |
| }; |
| option.tooltip = { |
| trigger: 'axis', |
| }; |
| } |
| else if (['sunburst'].includes(c.type)) { |
| option.series[0].label = { |
| show: false |
| }; |
| } |
| else if (['themeRiver'].includes(c.type)) { |
| option.singleAxis = { |
| type: 'value', |
| axisLine: { |
| show: false |
| }, |
| axisTick: { |
| show: false |
| }, |
| axisLabel: { |
| show: false |
| } |
| }; |
| } |
| else if (['radar'].includes(c.type)) { |
| const indicators = 6; |
| const indicator = []; |
| for (let i = 0; i < indicators; i++) { |
| indicator.push({ |
| name: `Indicator ${i + 1}`, |
| max: 100 |
| }); |
| } |
| option.radar = { |
| indicator: indicator |
| }; |
| |
| const data = []; |
| for (let i = 0; i < maxSeriesCount; i++) { |
| const value = []; |
| for (let j = 0; j < indicators; j++) { |
| value.push(Math.min(Math.round(Math.random() * 50 + i * 10), 100)); |
| } |
| data.push({ |
| name: `Series ${i + 1}`, |
| value: value |
| }); |
| } |
| option.series = [{ |
| type: 'radar', |
| data: data |
| }] |
| } |
| |
| chart.setOption(option); |
| } |
| } |
| |
| // Components |
| const options = [ |
| { |
| title: { |
| text: 'timeline' |
| }, |
| xAxis: { |
| type: 'category', |
| data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] |
| }, |
| yAxis: { |
| type: 'value', |
| splitArea: { |
| show: true |
| } |
| }, |
| options: [ |
| { |
| series: [{ |
| data: [130, 200, 150, 80, 70, 110, 130], |
| type: 'bar', |
| label: { |
| show: true, |
| position: 'inside' |
| } |
| }], |
| }, { |
| series: [{ |
| data: [140, 200, 150, 80, 70, 110, 130], |
| type: 'bar' |
| }], |
| }, { |
| series: [{ |
| data: [90, 200, 150, 80, 70, 110, 130], |
| type: 'bar' |
| }], |
| }, { |
| series: [{ |
| data: [50, 200, 150, 80, 70, 110, 130], |
| type: 'bar' |
| }], |
| }], |
| timeline: { |
| data: ['2010', '2011', '2012', '2013'], |
| } |
| }, |
| { |
| title: { |
| text: 'dataZoom & toolbox', |
| }, |
| toolbox: { |
| feature: { |
| dataZoom: { |
| yAxisIndex: 'none' |
| }, |
| restore: {}, |
| saveAsImage: {} |
| }, |
| }, |
| tooltip: { |
| trigger: 'axis', |
| }, |
| dataZoom: [ |
| { |
| show: true, |
| realtime: true, |
| start: 30, |
| end: 70 |
| } |
| ], |
| xAxis: { |
| type: 'time', |
| }, |
| yAxis: { |
| type: 'value' |
| }, |
| series: [{ |
| name: 'data', |
| type: 'line', |
| data: (function () { |
| const data = []; |
| const date = new Date(); |
| for (let i = 0; i < 100; i++) { |
| date.setHours(date.getHours() + 1); |
| data.push([date.toLocaleString(), Math.sin(i / 5) * 100 + 200]); |
| } |
| return data; |
| })() |
| }] |
| }, |
| { |
| title: { |
| text: 'dataZoom & legend (right/bottom)' |
| }, |
| legend: { |
| show: true |
| }, |
| tooltip: { |
| trigger: 'axis', |
| }, |
| dataZoom: [ |
| { |
| show: true, |
| realtime: true, |
| start: 30, |
| end: 70 |
| }, |
| { |
| show: true, |
| realtime: true, |
| yAxisIndex: 0 |
| }, |
| { |
| type: 'inside' |
| } |
| ], |
| xAxis: { |
| type: 'time', |
| }, |
| yAxis: { |
| type: 'value' |
| }, |
| series: [{ |
| name: 'data', |
| type: 'line', |
| data: (function () { |
| const data = []; |
| const date = new Date(); |
| for (let i = 0; i < 100; i++) { |
| date.setHours(date.getHours() + 1); |
| data.push([date.toLocaleString(), Math.sin(i / 5) * 100 + 200]); |
| } |
| return data; |
| })() |
| }] |
| }, |
| { |
| title: { |
| text: 'dataZoom & legend (left/top)' |
| }, |
| legend: { |
| show: true |
| }, |
| tooltip: { |
| trigger: 'axis', |
| }, |
| dataZoom: [ |
| { |
| show: true, |
| realtime: true, |
| start: 30, |
| end: 70, |
| top: 50 |
| }, |
| { |
| show: true, |
| realtime: true, |
| yAxisIndex: 0, |
| left: 25 |
| }, |
| { |
| type: 'inside' |
| } |
| ], |
| xAxis: { |
| type: 'time', |
| }, |
| yAxis: { |
| type: 'value' |
| }, |
| series: [{ |
| name: 'data', |
| type: 'line', |
| data: (function () { |
| const data = []; |
| const date = new Date(); |
| for (let i = 0; i < 100; i++) { |
| date.setHours(date.getHours() + 1); |
| data.push([date.toLocaleString(), Math.sin(i / 5) * 100 + 200]); |
| } |
| return data; |
| })() |
| }] |
| }, |
| { |
| title: { |
| text: 'visualMap & calendar', |
| }, |
| calendar: { |
| orient: 'vertical', |
| range: ['2025-01', '2025-03'], |
| cellSize: 25, |
| top: 120, |
| left: 'center' |
| }, |
| visualMap: { |
| min: 0, |
| max: 1000, |
| calculable: true |
| }, |
| series: [{ |
| type: 'heatmap', |
| coordinateSystem: 'calendar', |
| data: (function () { |
| const date = +echarts.time.parse('2025-01-06'); |
| const end = +echarts.time.parse('2025-02-20'); |
| const dayTime = 3600 * 24 * 1000; |
| const data = []; |
| for (let time = date; time < end; time += dayTime) { |
| data.push([ |
| echarts.time.format(time, '{yyyy}-{MM}-{dd}', false), |
| Math.floor(Math.random() * 1000) |
| ]); |
| } |
| return data; |
| })() |
| }] |
| }, { |
| title: { |
| text: 'map' |
| }, |
| series: [{ |
| type: 'map', |
| mapType: 'USA', |
| data: [], |
| label: { |
| show: true |
| } |
| }], |
| }, { |
| title: { |
| text: 'geo' |
| }, |
| geo: [{ |
| map: 'test1', |
| zoom: 1, |
| roam: true |
| }], |
| series: [{ |
| type: 'scatter', |
| coordinateSystem: 'geo', |
| symbol: 'roundRect', |
| symbolSize: 30, |
| data: (() => { |
| const data = []; |
| const step = 500; |
| const lngStart = 1000; |
| const latStart = 2000; |
| for (let i = 0; i < 10; i++) { |
| for (let j = 0; j < 10; j++) { |
| data.push({ |
| value: [lngStart + j * step, latStart + i * step], |
| symbolSize: 5 + j * 5 |
| }); |
| } |
| } |
| return data; |
| })() |
| }] |
| } |
| ]; |
| |
| const testGeoJson1 = { |
| type: 'FeatureCollection', |
| features: [{ |
| geometry: { |
| type: 'Polygon', |
| coordinates: [ |
| [[2000, 3000], [5000, 3000], [5000, 8000], [2000, 8000]] |
| ] |
| }, |
| properties: { |
| name: 'Some Area', |
| childNum: 1 |
| } |
| }] |
| }; |
| echarts.registerMap('test1', testGeoJson1); |
| |
| const main1 = document.getElementById('main1'); |
| for (const option of options) { |
| const div = document.createElement('div'); |
| div.className = 'chart-item-h'; |
| main1.appendChild(div); |
| |
| const chart = echarts.init(div, null, { |
| // renderer: 'svg' |
| }); |
| charts.push(chart); |
| |
| chart.setOption(option); |
| } |
| |
| updateDarkMode(); |
| }); |
| </script> |
| </body> |
| </html> |
| |