From e6429944e76616423d0cc3ae0d614871847d8c62 Mon Sep 17 00:00:00 2001 From: fengyuexingzi Date: Tue, 28 Jun 2022 08:10:19 +0800 Subject: [PATCH] ecore by antd --- .editorconfig | 16 + .env | 3 + .eslintignore | 7 + .eslintrc | 8 + .github/issue_template.md | 8 + .gitignore | 23 + .prettierignore | 6 + .prettierrc | 5 + .stylelintrc.json | 9 + .travis.yml | 18 + .umirc.js | 135 + .vscode/settings.json | 6 + LICENSE | 22 + README-zh_CN.md | 88 + assets/standard.md | 35 + docs/.nojekyll | 0 docs/API-configuration.md | 86 + docs/README.md | 83 + docs/_media/favicon.ico | Bin 0 -> 67646 bytes docs/_media/logo.svg | 24 + docs/_media/term_build.svg | 69 + docs/_media/term_i18n.svg | 69 + docs/_media/term_js_build.svg | 200 + docs/_media/term_js_i18n.svg | 200 + docs/_sidebar.md | 12 + docs/change-log.md | 50 + docs/configuration.md | 102 + docs/deploy.md | 113 + docs/faq.md | 9 + docs/getting-started.md | 73 + docs/i18n.md | 75 + docs/index.html | 55 + docs/layout.md | 60 + docs/request.md | 22 + docs/sw.js | 83 + docs/zh-cn/API-configuration.md | 86 + docs/zh-cn/README.md | 84 + docs/zh-cn/_sidebar.md | 11 + docs/zh-cn/change-log.md | 52 + docs/zh-cn/configuration.md | 102 + docs/zh-cn/deploy.md | 114 + docs/zh-cn/faq.md | 7 + docs/zh-cn/getting-started.md | 73 + docs/zh-cn/i18n.md | 75 + docs/zh-cn/layout.md | 60 + docs/zh-cn/request.md | 24 + docs/zh-cn/router.md | 5 + jest.config.js | 3 + manifest.json | 36 + mock/_utils.js | 59 + mock/dashboard.js | 142 + mock/post.js | 67 + mock/route.js | 155 + mock/user.js | 250 + package.json | 129 + public/america.svg | 63 + public/china.svg | 23 + public/favicon.ico | Bin 0 -> 67646 bytes public/logo.svg | 24 + public/logo/logo@128.png | Bin 0 -> 3184 bytes public/logo/logo@144.png | Bin 0 -> 3604 bytes public/logo/logo@152.png | Bin 0 -> 4038 bytes public/logo/logo@192.png | Bin 0 -> 4785 bytes public/logo/logo@384.png | Bin 0 -> 9968 bytes public/logo/logo@512.png | Bin 0 -> 13256 bytes public/logo/logo@72.png | Bin 0 -> 2138 bytes public/logo/logo@96.png | Bin 0 -> 2449 bytes public/portugal.svg | 40 + scripts/translate.js | 114 + src/components/DropOption/DropOption.js | 35 + src/components/DropOption/package.json | 6 + src/components/Editor/Editor.js | 17 + src/components/Editor/Editor.less | 106 + src/components/Editor/package.json | 6 + src/components/Ellipsis/index.d.ts | 21 + src/components/Ellipsis/index.js | 270 + src/components/Ellipsis/index.less | 24 + src/components/Ellipsis/index.md | 17 + src/components/Ellipsis/index.test.js | 13 + src/components/FilterItem/FilterItem.js | 28 + src/components/FilterItem/FilterItem.less | 17 + src/components/FilterItem/package.json | 6 + src/components/GlobalFooter/index.d.ts | 14 + src/components/GlobalFooter/index.js | 28 + src/components/GlobalFooter/index.less | 29 + src/components/GlobalFooter/index.md | 15 + src/components/Layout/Bread.js | 68 + src/components/Layout/Bread.less | 16 + src/components/Layout/Header.js | 169 + src/components/Layout/Header.less | 154 + src/components/Layout/Menu.js | 122 + src/components/Layout/Sider.js | 88 + src/components/Layout/Sider.less | 110 + src/components/Layout/index.js | 6 + src/components/Loader/Loader.js | 27 + src/components/Loader/Loader.less | 67 + src/components/Loader/package.json | 6 + src/components/Page/Page.js | 33 + src/components/Page/Page.less | 16 + src/components/Page/package.json | 6 + src/components/ScrollBar/index.js | 5 + src/components/ScrollBar/index.less | 31 + src/components/index.js | 11 + src/e2e/login.e2e.js | 41 + src/layouts/BaseLayout.js | 55 + src/layouts/BaseLayout.less | 74 + src/layouts/PrimaryLayout.js | 168 + src/layouts/PrimaryLayout.less | 58 + src/layouts/PublicLayout.js | 3 + src/layouts/index.js | 71 + src/locales/en/messages.json | 56 + src/locales/pt-br/messages.json | 54 + src/locales/zh/messages.json | 56 + src/models/app.js | 161 + src/pages/404.less | 19 + src/pages/404.tsx | 15 + .../chart/ECharts/AirportCoordComponent.js | 321 + .../chart/ECharts/BubbleGradientComponent.js | 165 + src/pages/chart/ECharts/CalendarComponent.js | 193 + src/pages/chart/ECharts/ChartAPIComponent.js | 130 + .../ECharts/ChartShowLoadingComponent.js | 104 + .../chart/ECharts/ChartWithEventComponent.js | 95 + .../chart/ECharts/DynamicChartComponent.js | 217 + src/pages/chart/ECharts/EchartsComponent.js | 49 + src/pages/chart/ECharts/GCalendarComponent.js | 76 + src/pages/chart/ECharts/GaugeComponent.js | 370 + src/pages/chart/ECharts/GraphComponent.js | 1365 +++ .../chart/ECharts/LiquidfillComponent.js | 32 + .../chart/ECharts/LunarCalendarComponent.js | 490 + src/pages/chart/ECharts/MainPageComponent.js | 53 + src/pages/chart/ECharts/MapChartComponent.js | 209 + .../chart/ECharts/ModuleLoadChartComponent.js | 55 + .../chart/ECharts/SimpleChartComponent.js | 90 + .../chart/ECharts/ThemeChartComponent.js | 127 + .../ECharts/TransparentBar3DComPonent.js | 302 + src/pages/chart/ECharts/TreemapComponent.js | 275 + src/pages/chart/ECharts/index.js | 115 + src/pages/chart/ECharts/index.less | 34 + src/pages/chart/ECharts/map/js/china.js | 46 + src/pages/chart/ECharts/theme/macarons.js | 219 + src/pages/chart/ECharts/theme/shine.js | 169 + .../chart/Recharts/AreaChartComponent.js | 360 + src/pages/chart/Recharts/BarChartComponent.js | 260 + src/pages/chart/Recharts/Container.js | 27 + src/pages/chart/Recharts/Container.less | 20 + .../chart/Recharts/LineChartComponent.js | 261 + src/pages/chart/Recharts/ReChartsComponent.js | 18 + src/pages/chart/Recharts/index.js | 53 + src/pages/chart/Recharts/index.less | 8 + .../chart/highCharts/HighChartsComponent.js | 18 + .../chart/highCharts/HighMoreComponent.js | 53 + .../chart/highCharts/HighmapsComponent.js | 81 + .../chart/highCharts/HighstockComponent.js | 99 + src/pages/chart/highCharts/index.js | 53 + src/pages/chart/highCharts/index.less | 7 + src/pages/chart/highCharts/mapdata/europe.js | 9162 +++++++++++++++++ src/pages/dashboard/components/browser.js | 51 + src/pages/dashboard/components/browser.less | 7 + src/pages/dashboard/components/comments.js | 68 + src/pages/dashboard/components/comments.less | 43 + src/pages/dashboard/components/completed.js | 109 + src/pages/dashboard/components/completed.less | 49 + src/pages/dashboard/components/cpu.js | 79 + src/pages/dashboard/components/cpu.less | 40 + src/pages/dashboard/components/index.js | 23 + src/pages/dashboard/components/numberCard.js | 45 + .../dashboard/components/numberCard.less | 33 + src/pages/dashboard/components/quote.js | 30 + src/pages/dashboard/components/quote.less | 52 + src/pages/dashboard/components/recentSales.js | 67 + .../dashboard/components/recentSales.less | 8 + src/pages/dashboard/components/sales.js | 115 + src/pages/dashboard/components/sales.less | 50 + .../dashboard/components/user-background.png | Bin 0 -> 51198 bytes src/pages/dashboard/components/user.js | 55 + src/pages/dashboard/components/user.less | 88 + src/pages/dashboard/components/weather.js | 39 + src/pages/dashboard/components/weather.less | 48 + src/pages/dashboard/index.js | 162 + src/pages/dashboard/index.less | 27 + src/pages/dashboard/model.js | 75 + src/pages/dashboard/services/dashboard.js | 12 + src/pages/dashboard/services/weather.js | 12 + src/pages/editor/index.js | 105 + src/pages/index.js | 11 + src/pages/login/index.js | 90 + src/pages/login/index.less | 60 + src/pages/login/model.js | 39 + src/pages/org/[id]/index.js | 35 + src/pages/org/[id]/index.less | 14 + src/pages/org/[id]/models/detail.js | 50 + src/pages/org/components/Filter.js | 143 + src/pages/org/components/List.js | 113 + src/pages/org/components/List.less | 7 + src/pages/org/components/Modal.js | 82 + src/pages/org/index.js | 190 + src/pages/org/model.js | 110 + src/pages/post/components/List.js | 73 + src/pages/post/components/List.less | 7 + src/pages/post/index.js | 92 + src/pages/post/model.js | 47 + src/pages/request/index.js | 259 + src/pages/request/index.less | 39 + src/pages/user/[id]/index.js | 35 + src/pages/user/[id]/index.less | 14 + src/pages/user/[id]/models/detail.js | 50 + src/pages/user/components/Filter.js | 141 + src/pages/user/components/List.js | 99 + src/pages/user/components/List.less | 7 + src/pages/user/components/Modal.js | 67 + src/pages/user/index.js | 199 + src/pages/user/model.js | 111 + src/plugins/onError.js | 13 + src/services/api.js | 25 + src/services/index.js | 38 + src/themes/default.less | 16 + src/themes/index.less | 124 + src/themes/mixin.less | 35 + src/themes/vars.less | 2 + src/utils/city.js | 4055 ++++++++ src/utils/config.js | 39 + src/utils/constant.js | 7 + src/utils/iconMap.jsx | 31 + src/utils/index.js | 172 + src/utils/index.test.js | 19 + src/utils/model.js | 39 + src/utils/request.js | 112 + src/utils/theme.js | 14 + 228 files changed, 30188 insertions(+) create mode 100644 .editorconfig create mode 100644 .env create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .github/issue_template.md create mode 100644 .gitignore create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .stylelintrc.json create mode 100644 .travis.yml create mode 100644 .umirc.js create mode 100644 .vscode/settings.json create mode 100644 LICENSE create mode 100644 README-zh_CN.md create mode 100644 assets/standard.md create mode 100644 docs/.nojekyll create mode 100644 docs/API-configuration.md create mode 100644 docs/README.md create mode 100644 docs/_media/favicon.ico create mode 100644 docs/_media/logo.svg create mode 100644 docs/_media/term_build.svg create mode 100644 docs/_media/term_i18n.svg create mode 100644 docs/_media/term_js_build.svg create mode 100644 docs/_media/term_js_i18n.svg create mode 100644 docs/_sidebar.md create mode 100644 docs/change-log.md create mode 100644 docs/configuration.md create mode 100644 docs/deploy.md create mode 100644 docs/faq.md create mode 100644 docs/getting-started.md create mode 100644 docs/i18n.md create mode 100644 docs/index.html create mode 100644 docs/layout.md create mode 100644 docs/request.md create mode 100644 docs/sw.js create mode 100644 docs/zh-cn/API-configuration.md create mode 100644 docs/zh-cn/README.md create mode 100644 docs/zh-cn/_sidebar.md create mode 100644 docs/zh-cn/change-log.md create mode 100644 docs/zh-cn/configuration.md create mode 100644 docs/zh-cn/deploy.md create mode 100644 docs/zh-cn/faq.md create mode 100644 docs/zh-cn/getting-started.md create mode 100644 docs/zh-cn/i18n.md create mode 100644 docs/zh-cn/layout.md create mode 100644 docs/zh-cn/request.md create mode 100644 docs/zh-cn/router.md create mode 100644 jest.config.js create mode 100644 manifest.json create mode 100644 mock/_utils.js create mode 100644 mock/dashboard.js create mode 100644 mock/post.js create mode 100644 mock/route.js create mode 100644 mock/user.js create mode 100644 package.json create mode 100644 public/america.svg create mode 100644 public/china.svg create mode 100644 public/favicon.ico create mode 100644 public/logo.svg create mode 100755 public/logo/logo@128.png create mode 100755 public/logo/logo@144.png create mode 100755 public/logo/logo@152.png create mode 100755 public/logo/logo@192.png create mode 100755 public/logo/logo@384.png create mode 100755 public/logo/logo@512.png create mode 100755 public/logo/logo@72.png create mode 100755 public/logo/logo@96.png create mode 100644 public/portugal.svg create mode 100644 scripts/translate.js create mode 100644 src/components/DropOption/DropOption.js create mode 100644 src/components/DropOption/package.json create mode 100644 src/components/Editor/Editor.js create mode 100644 src/components/Editor/Editor.less create mode 100644 src/components/Editor/package.json create mode 100644 src/components/Ellipsis/index.d.ts create mode 100644 src/components/Ellipsis/index.js create mode 100644 src/components/Ellipsis/index.less create mode 100644 src/components/Ellipsis/index.md create mode 100644 src/components/Ellipsis/index.test.js create mode 100644 src/components/FilterItem/FilterItem.js create mode 100644 src/components/FilterItem/FilterItem.less create mode 100644 src/components/FilterItem/package.json create mode 100644 src/components/GlobalFooter/index.d.ts create mode 100644 src/components/GlobalFooter/index.js create mode 100644 src/components/GlobalFooter/index.less create mode 100644 src/components/GlobalFooter/index.md create mode 100644 src/components/Layout/Bread.js create mode 100644 src/components/Layout/Bread.less create mode 100644 src/components/Layout/Header.js create mode 100644 src/components/Layout/Header.less create mode 100644 src/components/Layout/Menu.js create mode 100644 src/components/Layout/Sider.js create mode 100644 src/components/Layout/Sider.less create mode 100644 src/components/Layout/index.js create mode 100644 src/components/Loader/Loader.js create mode 100644 src/components/Loader/Loader.less create mode 100644 src/components/Loader/package.json create mode 100644 src/components/Page/Page.js create mode 100644 src/components/Page/Page.less create mode 100644 src/components/Page/package.json create mode 100644 src/components/ScrollBar/index.js create mode 100644 src/components/ScrollBar/index.less create mode 100644 src/components/index.js create mode 100644 src/e2e/login.e2e.js create mode 100644 src/layouts/BaseLayout.js create mode 100644 src/layouts/BaseLayout.less create mode 100644 src/layouts/PrimaryLayout.js create mode 100644 src/layouts/PrimaryLayout.less create mode 100644 src/layouts/PublicLayout.js create mode 100644 src/layouts/index.js create mode 100644 src/locales/en/messages.json create mode 100644 src/locales/pt-br/messages.json create mode 100644 src/locales/zh/messages.json create mode 100644 src/models/app.js create mode 100644 src/pages/404.less create mode 100644 src/pages/404.tsx create mode 100644 src/pages/chart/ECharts/AirportCoordComponent.js create mode 100644 src/pages/chart/ECharts/BubbleGradientComponent.js create mode 100644 src/pages/chart/ECharts/CalendarComponent.js create mode 100644 src/pages/chart/ECharts/ChartAPIComponent.js create mode 100644 src/pages/chart/ECharts/ChartShowLoadingComponent.js create mode 100644 src/pages/chart/ECharts/ChartWithEventComponent.js create mode 100644 src/pages/chart/ECharts/DynamicChartComponent.js create mode 100644 src/pages/chart/ECharts/EchartsComponent.js create mode 100644 src/pages/chart/ECharts/GCalendarComponent.js create mode 100644 src/pages/chart/ECharts/GaugeComponent.js create mode 100644 src/pages/chart/ECharts/GraphComponent.js create mode 100644 src/pages/chart/ECharts/LiquidfillComponent.js create mode 100644 src/pages/chart/ECharts/LunarCalendarComponent.js create mode 100644 src/pages/chart/ECharts/MainPageComponent.js create mode 100644 src/pages/chart/ECharts/MapChartComponent.js create mode 100644 src/pages/chart/ECharts/ModuleLoadChartComponent.js create mode 100644 src/pages/chart/ECharts/SimpleChartComponent.js create mode 100644 src/pages/chart/ECharts/ThemeChartComponent.js create mode 100644 src/pages/chart/ECharts/TransparentBar3DComPonent.js create mode 100644 src/pages/chart/ECharts/TreemapComponent.js create mode 100644 src/pages/chart/ECharts/index.js create mode 100644 src/pages/chart/ECharts/index.less create mode 100644 src/pages/chart/ECharts/map/js/china.js create mode 100644 src/pages/chart/ECharts/theme/macarons.js create mode 100644 src/pages/chart/ECharts/theme/shine.js create mode 100644 src/pages/chart/Recharts/AreaChartComponent.js create mode 100644 src/pages/chart/Recharts/BarChartComponent.js create mode 100644 src/pages/chart/Recharts/Container.js create mode 100644 src/pages/chart/Recharts/Container.less create mode 100644 src/pages/chart/Recharts/LineChartComponent.js create mode 100644 src/pages/chart/Recharts/ReChartsComponent.js create mode 100644 src/pages/chart/Recharts/index.js create mode 100644 src/pages/chart/Recharts/index.less create mode 100644 src/pages/chart/highCharts/HighChartsComponent.js create mode 100644 src/pages/chart/highCharts/HighMoreComponent.js create mode 100644 src/pages/chart/highCharts/HighmapsComponent.js create mode 100644 src/pages/chart/highCharts/HighstockComponent.js create mode 100644 src/pages/chart/highCharts/index.js create mode 100644 src/pages/chart/highCharts/index.less create mode 100644 src/pages/chart/highCharts/mapdata/europe.js create mode 100644 src/pages/dashboard/components/browser.js create mode 100644 src/pages/dashboard/components/browser.less create mode 100644 src/pages/dashboard/components/comments.js create mode 100644 src/pages/dashboard/components/comments.less create mode 100644 src/pages/dashboard/components/completed.js create mode 100644 src/pages/dashboard/components/completed.less create mode 100644 src/pages/dashboard/components/cpu.js create mode 100644 src/pages/dashboard/components/cpu.less create mode 100644 src/pages/dashboard/components/index.js create mode 100644 src/pages/dashboard/components/numberCard.js create mode 100644 src/pages/dashboard/components/numberCard.less create mode 100644 src/pages/dashboard/components/quote.js create mode 100644 src/pages/dashboard/components/quote.less create mode 100644 src/pages/dashboard/components/recentSales.js create mode 100644 src/pages/dashboard/components/recentSales.less create mode 100644 src/pages/dashboard/components/sales.js create mode 100644 src/pages/dashboard/components/sales.less create mode 100644 src/pages/dashboard/components/user-background.png create mode 100644 src/pages/dashboard/components/user.js create mode 100644 src/pages/dashboard/components/user.less create mode 100644 src/pages/dashboard/components/weather.js create mode 100644 src/pages/dashboard/components/weather.less create mode 100644 src/pages/dashboard/index.js create mode 100644 src/pages/dashboard/index.less create mode 100644 src/pages/dashboard/model.js create mode 100644 src/pages/dashboard/services/dashboard.js create mode 100644 src/pages/dashboard/services/weather.js create mode 100644 src/pages/editor/index.js create mode 100644 src/pages/index.js create mode 100644 src/pages/login/index.js create mode 100644 src/pages/login/index.less create mode 100644 src/pages/login/model.js create mode 100644 src/pages/org/[id]/index.js create mode 100644 src/pages/org/[id]/index.less create mode 100644 src/pages/org/[id]/models/detail.js create mode 100644 src/pages/org/components/Filter.js create mode 100644 src/pages/org/components/List.js create mode 100644 src/pages/org/components/List.less create mode 100644 src/pages/org/components/Modal.js create mode 100644 src/pages/org/index.js create mode 100644 src/pages/org/model.js create mode 100644 src/pages/post/components/List.js create mode 100644 src/pages/post/components/List.less create mode 100644 src/pages/post/index.js create mode 100644 src/pages/post/model.js create mode 100644 src/pages/request/index.js create mode 100644 src/pages/request/index.less create mode 100644 src/pages/user/[id]/index.js create mode 100644 src/pages/user/[id]/index.less create mode 100644 src/pages/user/[id]/models/detail.js create mode 100644 src/pages/user/components/Filter.js create mode 100644 src/pages/user/components/List.js create mode 100644 src/pages/user/components/List.less create mode 100644 src/pages/user/components/Modal.js create mode 100644 src/pages/user/index.js create mode 100644 src/pages/user/model.js create mode 100644 src/plugins/onError.js create mode 100644 src/services/api.js create mode 100644 src/services/index.js create mode 100644 src/themes/default.less create mode 100644 src/themes/index.less create mode 100644 src/themes/mixin.less create mode 100644 src/themes/vars.less create mode 100644 src/utils/city.js create mode 100644 src/utils/config.js create mode 100644 src/utils/constant.js create mode 100644 src/utils/iconMap.jsx create mode 100644 src/utils/index.js create mode 100644 src/utils/index.test.js create mode 100644 src/utils/model.js create mode 100644 src/utils/request.js create mode 100644 src/utils/theme.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7e3649a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/.env b/.env new file mode 100644 index 0000000..904cfb0 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +BROWSER=none +HOST=0.0.0.0 +PORT=7001 diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..96a82df --- /dev/null +++ b/.eslintignore @@ -0,0 +1,7 @@ +src/**/*-test.js +src/public +src/routes/chart/ECharts/theme +src/routes/chart/highCharts/mapdata +src/locales/_build/ +src/locales/**/*.js +docs/**/*.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..e71ebc8 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,8 @@ +{ + "extends": "react-app", + "rules": { + "jsx-a11y/href-no-hash": "off", + "no-console": "warn", + "valid-jsdoc": "warn" + } +} diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 0000000..1f0ad65 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,8 @@ +> 请酌情提供细节,并保持issue精简便于查阅 +> 1. 功能需求 => 详细说明 +> 2. Bug反馈 +> 2.1 简单描述下报错 +> 2.2 你期望什么结果 +> 2.3 如何操作导致的 +> 2.4 可提供运行环境信息 +> 3. 代码求助 => 可以提,未必及时答复 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75b78a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +coverage +dist +node_modules +npm-debug.log +yarn-error.log +yarn.lock +package-lock.json + +# ide +.idea + +# Mac General +.DS_Store +.AppleDouble +.LSOverride + +# umi +.umi +.umi-production + +# jslingui +src/locales/_build +src/locales/**/*.js \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..1e879f7 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +*.svg +*.ejs +.DS_Store +.umi +.umi-production +src/locales/**/*.json \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..36301bc --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/.stylelintrc.json b/.stylelintrc.json new file mode 100644 index 0000000..b533bdd --- /dev/null +++ b/.stylelintrc.json @@ -0,0 +1,9 @@ +{ + "extends": ["stylelint-config-standard", "stylelint-config-prettier"], + "rules": { + "declaration-empty-line-before": null, + "no-descending-specificity": null, + "selector-pseudo-class-no-unknown": null, + "selector-pseudo-element-colon-notation": null + } +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..66de02f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,18 @@ +language: node_js +node_js: + - node +script: + - npm run build +before_install: + - yarn global add now +after_script: + - | + if [[ $TRAVIS_BRANCH == 'master' ]]; then + echo $PROD_SITE_NOW_CONFIG >> dist/vercel.json && echo $PROD_DOC_NOW_CONFIG >> docs/vercel.json; + else + echo $DEV_SITE_NOW_CONFIG >> dist/vercel.json && echo $DEV_DOC_NOW_CONFIG >> docs/vercel.json; + fi + - cd ./dist + - now -A vercel.json -t $NOW_TOKEN --prod -c + - cd ../docs + - now -A vercel.json -t $NOW_TOKEN --prod -c diff --git a/.umirc.js b/.umirc.js new file mode 100644 index 0000000..1a0cbc5 --- /dev/null +++ b/.umirc.js @@ -0,0 +1,135 @@ +// https://umijs.org/config/ +import { resolve } from 'path' +const fs = require('fs') +const path = require('path') +const lessToJs = require('less-vars-to-js') +const isDevelopment = process.env.NODE_ENV === 'development' + +// how to speed compile: https://umijs.org/guide/boost-compile-speed +export default { + // IMPORTANT! change next line to yours or delete. And hide in dev + publicPath: isDevelopment ? '/' : 'http://140.249.182.90:7000/', + alias: { + api: resolve(__dirname, './src/services/'), + components: resolve(__dirname, './src/components'), + config: resolve(__dirname, './src/utils/config'), + themes: resolve(__dirname, './src/themes'), + utils: resolve(__dirname, './src/utils'), + }, + antd: {}, + // a lower cost way to genereate sourcemap, default is cheap-module-source-map, could save 60% time in dev hotload + devtool: 'eval', + dva: { immer: true }, + dynamicImport: { + loading: 'components/Loader/Loader', + }, + extraBabelPlugins: [ + [ + 'import', + { + libraryName: 'lodash', + libraryDirectory: '', + camel2DashComponentName: false, + }, + 'lodash', + ], + [ + 'import', + { + libraryName: '@ant-design/icons', + libraryDirectory: 'es/icons', + camel2DashComponentName: false, + }, + 'ant-design-icons', + ], + [ + 'macros' + ] + ], + hash: true, + ignoreMomentLocale: true, + // umi3 comple node_modules by default, could be disable + nodeModulesTransform: { + type: 'none', + exclude: [], + }, + // Webpack Configuration + proxy: { + '/api/v1/weather': { + target: 'https://api.seniverse.com/', + changeOrigin: true, + pathRewrite: { '^/api/v1/weather': '/v3/weather' }, + }, + }, + // Theme for antd + // https://ant.design/docs/react/customize-theme + theme: lessToJs( + fs.readFileSync(path.join(__dirname, './src/themes/default.less'), 'utf8') + ), + webpack5: {}, + mfsu: {}, + chainWebpack: function (config, { webpack }) { + !isDevelopment && config.merge({ + optimization: { + minimize: false, + splitChunks: { + chunks: 'all', + minSize: 30000, + minChunks: 3, + automaticNameDelimiter: '.', + cacheGroups: { + react: { + name: 'react', + priority: 20, + test: /[\\/]node_modules[\\/](react|react-dom|react-dom-router)[\\/]/, + }, + antd: { + name: 'antd', + priority: 20, + test: /[\\/]node_modules[\\/](antd|@ant-design\/icons)[\\/]/, + }, + 'echarts-gl': { + name: 'echarts-gl', + priority: 30, + test: /[\\/]node_modules[\\/]echarts-gl[\\/]/, + }, + zrender: { + name: 'zrender', + priority: 30, + test: /[\\/]node_modules[\\/]zrender[\\/]/, + }, + echarts: { + name: 'echarts', + priority: 20, + test: /[\\/]node_modules[\\/](echarts|echarts-for-react|echarts-liquidfill)[\\/]/, + }, + highcharts: { + name: 'highcharts', + priority: 20, + test: /[\\/]node_modules[\\/]highcharts[\\/]/, + }, + recharts: { + name: 'recharts', + priority: 20, + test: /[\\/]node_modules[\\/]recharts[\\/]/, + }, + draftjs: { + name: 'draftjs', + priority: 30, + test: /[\\/]node_modules[\\/](draft-js|react-draft-wysiwyg|draftjs-to-html|draftjs-to-markdown)[\\/]/, + }, + async: { + chunks: 'async', + minChunks: 2, + name: 'async', + maxInitialRequests: 1, + minSize: 0, + priority: 5, + reuseExistingChunk: true, + }, + }, + }, + }, + }) + }, +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..58dfaa4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "json.schemas": [ + + ], + "js/ts.implicitProjectConfig.experimentalDecorators": true +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fb8f0c2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT LICENSE + +Copyright (c) 2016 zuiidea (zuiiidea@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README-zh_CN.md b/README-zh_CN.md new file mode 100644 index 0000000..5c2468e --- /dev/null +++ b/README-zh_CN.md @@ -0,0 +1,88 @@ + +

+ + antd-admin + +

+ +

AntD Admin

+ +
+ +一套优秀的中后台前端解决方案 + +[![antd](https://img.shields.io/badge/antd-^3.10.0-blue.svg?style=flat-square)](https://github.com/ant-design/ant-design) +[![umi](https://img.shields.io/badge/umi-^2.2.1-orange.svg?style=flat-square)](https://github.com/umijs/umi) +[![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/issues) +[![MIT](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](http://opensource.org/licenses/MIT) +![Travis (.org)](https://img.shields.io/travis/zuiidea/antd-admin.svg) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls) +[![Gitter](https://img.shields.io/gitter/room/antd-admin/antd-admin.svg)](https://gitter.im/antd-admin/antd-admin) + +
+ +- 在线演示 - [https://antd-admin.zuiidea.com](https://antd-admin.zuiidea.com) +- 使用文档 - [https://doc.antd-admin.zuiidea.com/#/zh-cn/](https://doc.antd-admin.zuiidea.com/#/zh-cn/) +- 常见问题 - [https://doc.antd-admin.zuiidea.com/#/zh-cn/faq](https://doc.antd-admin.zuiidea.com/#/zh-cn/faq) +- 更新日志 - [https://doc.antd-admin.zuiidea.com/#/zh-cn/change-log](https://doc.antd-admin.zuiidea.com/#/zh-cn/change-log) + +[English](./README.md) | 简体中文 + +## 特性 + +- 国际化,源码中抽离翻译字段,按需加载语言包 +- 动态权限,不同权限对应不同菜单 +- 优雅美观,Ant Design 设计体系 +- Mock 数据,本地数据调试 + + +## 使用 + +1. 下载项目代码。 + +```bash +git clone https://github.com/zuiidea/antd-admin.git my-project +cd my-project +``` + +2. 进入目录安装依赖,国内用户推荐使用 [cnpm](https://cnpmjs.org) 进行加速。 + +```bash +yarn install +``` + +或者 + +```bash +npm install +``` + +3. 启动本地服务器。 + +```bash +npm run start +``` + +4. 启动完成后打开浏览器访问 [http://localhost:7000](http://localhost:7000),如果需要更改启动端口,可在 `.env` 文件中配置。 + +5. 登录账号有2个,一个账号admin 密码admin;另一个账号guest 密码guest + +> 更多信息请参考 [使用文档](https://doc.antd-admin.zuiidea.com/#/zh-cn/)。 + + +## 支持环境 + +现代浏览器。 + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | [Opera](http://godban.github.io/browsers-support-badges/)
Opera | +| --------- | --------- | --------- | --------- | --------- | +|IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions + +## 参与贡献 + +我们非常欢迎你的贡献,你可以通过以下方式和我们一起共建 :smiley: +- 在你的公司或个人项目中使用 AntD Admin。 +- 通过 [Issue](http://github.com/zuiidea/antd-admin/issues) 报告 bug 或进行咨询。 +- 提交 [Pull Request](http://github.com/zuiidea/antd-admin/pulls) 改进代码。 + +> 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。 diff --git a/assets/standard.md b/assets/standard.md new file mode 100644 index 0000000..f8cd8ce --- /dev/null +++ b/assets/standard.md @@ -0,0 +1,35 @@ +### 开发环境 + +- OS:Windows +- 编辑器:Atom +- cmd:Cmder + +### Atom 插件 + +- [atom-beautify](https://atom.io/packages/atom-beautify) + + #### Less + + - [x] Beautify On Save + + #### Javascript + + - [ ] Disable Beautifying Language + + #### Markdown + + - [x] Beautify On Save + - [x] Default Beautifier:Remark + + #### HTML + + - [x] Beautify On Save + +- [linter](https://atom.io/packages/linter) + - [ ] Lint on Change +- [linter-eslint](https://atom.io/packages/linter-eslint) + - [x] Fix errors on save + +### Cmder 主题 + +- [Panda-Theme-Cmder](https://github.com/HamidFaraji/Panda-Theme-Cmder) diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/docs/API-configuration.md b/docs/API-configuration.md new file mode 100644 index 0000000..73ee148 --- /dev/null +++ b/docs/API-configuration.md @@ -0,0 +1,86 @@ +# API configuration + +## Why + +In the use of `redux` or `dva` projects, we often write functions like the following `service` layer to make the code structure clearer, but it is easy to see that we will write a lot of similar code in `antd -admin@5.0`, using the more concise configuration method to achieve the same function. + +```javascript +export async function login(data) { +  return request({ +    url: '/api/v1/user/login', +    method: 'post', +    data, +  }) +} +``` + +## Configuration and use + +In the `src/services/api.js` file, you will see the following configuration object, the object's key is used to call the function name, the object's value is the requested `url`, the default request method is `GET`, The format of the value of the other request mode object is `'method url'`. + +```javascript +export default { +  ... +  queryUser: '/user/:id', +  queryUserList: '/users', +  updateUser: 'Patch /user/:id', +  createUser: 'POST /user/:id', +  removeUser: 'DELETE /user/:id', +  removeUserList: 'POST /users/delete', +  ... +} +``` + +Used in other files + +```javascript +import { queryUser } from 'api' + +// in the general file +... +queryUser(option).then(data => console.log(data)) +... + +/ / Model file +... +yield call(queryUser, option) +... +``` + +## Method to realize + +Refer to the `src/services/index.js` file to traverse the api configuration. Each property returns the corresponding encapsulated request function. + +```javascript +import request from 'utils/request' +import { apiPrefix } from 'utils/config' + +import api from './api' + +const gen = params => { +  let url = apiPrefix + params +  let method = 'GET' + +  const paramsArray = params.split(' ') +  if (paramsArray.length === 2) { +    method = paramsArray[0] +    url = apiPrefix + paramsArray[1] +  } + +  return function(data) { +    return request({ +      url, +      data, +      method, +    }) +  } +} + +const APIFunction = {} +for (const key in api) { +  APIFunction[key] = gen(api[key]) +} + +module.exports = APIFunction + +``` \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..41f72da --- /dev/null +++ b/docs/README.md @@ -0,0 +1,83 @@ +

+ + antd-admin + +

+ +

AntD Admin

+ +
+ +An excellent front-end solution for enterprise applications. + +[![antd](https://img.shields.io/badge/antd-^3.10.0-blue.svg?style=flat-square)](https://github.com/ant-design/ant-design) +[![umi](https://img.shields.io/badge/umi-^2.2.1-orange.svg?style=flat-square)](https://github.com/umijs/umi) +[![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/issues) +[![MIT](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](http://opensource.org/licenses/MIT) +![Travis (.org)](https://img.shields.io/travis/zuiidea/antd-admin.svg) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls) +[![Gitter](https://img.shields.io/gitter/room/antd-admin/antd-admin.svg)](https://gitter.im/antd-admin/antd-admin) + +
+ +- Preview - [https://antd-admin.zuiidea.com](https://antd-admin.zuiidea.com) +- Documentation - [https://doc.antd-admin.zuiidea.com](https://doc.antd-admin.zuiidea.com) +- FAQ - [https://doc.antd-admin.zuiidea.com/#/faq](https://doc.antd-admin.zuiidea.com/#/faq) +- ChangeLog - [https://doc.antd-admin.zuiidea.com/#/change-log](https://doc.antd-admin.zuiidea.com/#/change-log) + +## Features + +- Internationalization, extracting translation fields from source code, loading language packs on demand +- Dynamic permissions, different permissions for different menus +- Elegant and beautiful, Ant Design system +- Mock data, local data debugging + + +## Usage + +1. Clone project code. + +```bash +git clone https://github.com/zuiidea/antd-admin.git my-project +cd my-project +``` + +2. Installation dependence. + +```bash +yarn install +``` + +Or + +```bash +npm install +``` + +3. Start local server. + +```bash +npm run start +``` + +4. After the startup is complete, open a browser and visit [http://localhost:7000](http://localhost:7000), If you need to change the startup port, you can configure it in the `.env` file. + + +> More instructions at [documentation](https://doc.antd-admin.zuiidea.com)。 + + +## Browsers support + +Modern browsers. + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | [Opera](http://godban.github.io/browsers-support-badges/)
Opera | +| --------- | --------- | --------- | --------- | --------- | +|IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions + +## Contributing + +We very much welcome your contribution, you can build together with us in the following ways :smiley: + +- Use Ant Design Pro in your daily work. +- Submit [GitHub issues](http://github.com/zuiidea/antd-admin/issues)s to report bugs or ask questions. +- Propose [Pull Request](http://github.com/zuiidea/antd-admin/pulls) to improve our code. diff --git a/docs/_media/favicon.ico b/docs/_media/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ca2170ea0f4e0472c56924a402807e10ddf0220 GIT binary patch literal 67646 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 + + Created with Sketch. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_media/term_build.svg b/docs/_media/term_build.svg new file mode 100644 index 0000000..5b1a6ea --- /dev/null +++ b/docs/_media/term_build.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + antd-admin git:(master) antd-admin git:(master) n antd-admin git:(master) np antd-admin git:(master) npm antd-admin git:(master) npm antd-admin git:(master) npm r antd-admin git:(master) npm ru antd-admin git:(master) npm run antd-admin git:(master) npm run antd-admin git:(master) npm run b antd-admin git:(master) npm run bu antd-admin git:(master) npm run bui antd-admin git:(master) npm run buil antd-admin git:(master) npm run build Compiling webpack █████████████████████████ compiling (0%) Compiling webpack █████████████████████████ building modules (10%) 2/2 modules 0 active Compiling webpack █████████████████████████ building modules (11%) 11/13 modules 2 active node_modules/umi/lib/createHistory.js webpack █████████████████████████ building modules (12%) 18/21 modules 3 activ node_modules/webpack/buildin/global.js webpack █████████████████████████ building modules (23%) 110/112 modules 2 active node_modules/react-dom/cjs/react-dom.production.min.js webpack █████████████████████████ building modules (23%) 115/118 modules 3 act node_modules/util/support/isBufferBrowser.js webpack █████████████████████████ building modules (23%) 116/141 modules 25 active node_modules/core-js/modules/_global.js webpack █████████████████████████ building modules (25%) 130/142 modules 12 ac node_modules/path-browserify/index.js webpack █████████████████████████ building modules (27%) 147/191 modules 44 ac node_modules/core-js/modules/_bind.js webpack █████████████████████████ building modules (35%) 215/256 modules 41 ac node_modules/core-js/modules/_inherit-if-required.js webpack █████████████████████████ building modules (39%) 249/266 modules 17 ac node_modules/core-js/modules/web.dom.iterable.js webpack █████████████████████████ building modules (42%) 267/307 modules 40 ac ...4m › postcss-loaderless-loadersrc/pages/404.less webpack █████████████████████████ building modules (47%) 313/320 modules 7 act node_modules/prop-types/index.js webpack █████████████████████████ building modules (49%) 328/351 modules 23 ac node_modules/react-router-dom/es/index.js webpack █████████████████████████ building modules (51%) 343/354 modules 11 ac babel-loadersrc/pages/chart/highCharts/HighChartsComponent.js webpack █████████████████████████ building modules (52%) 354/372 modules 18 ac src/locales/en/messages.json webpack █████████████████████████ building modules (54%) 372/394 modules 22 ac babel-loadersrc/utils/theme.js webpack █████████████████████████ building modules (57%) 395/422 modules 27 ac node_modules/@babel/runtime/helpers/arrayWithoutHoles.js webpack █████████████████████████ building modules (60%) 424/455 modules 31 ac node_modules/antd/es/card/Meta.js webpack █████████████████████████ building modules (61%) 427/463 modules 36 ac node_modules/antd/es/_util/throttleByAnimationFrame.js webpack █████████████████████████ building modules (64%) 458/477 modules 19 ac node_modules/antd/es/radio/group.js webpack █████████████████████████ building modules (67%) 476/497 modules 21 ac babel-loadersrc/pages/chart/highCharts/mapdata/europe.js webpack █████████████████████████ building modules (66%) 488/514 modules 26 ac node_modules/react-router-dom/node_modules/warning/warning.js webpack █████████████████████████ building modules (67%) 493/518 modules 25 ac ...derless-loadersrc/pages/chart/Recharts/Container.less webpack █████████████████████████ building modules (67%) 505/525 modules 20 ac node_modules/omit.js/es/index.js webpack █████████████████████████ building modules (67%) 532/559 modules 27 ac node_modules/highcharts-exporting/exporting.js webpack █████████████████████████ building modules (67%) 574/598 modules 24 ac node_modules/antd/es/date-picker/locale/en_US.js webpack █████████████████████████ building modules (68%) 589/608 modules 19 ac node_modules/draft-js/lib/ContentState.js webpack █████████████████████████ building modules (67%) 616/641 modules 25 ac node_modules/react-router/es/matchPath.js webpack █████████████████████████ building modules (67%) 656/679 modules 23 ac node_modules/draft-js/lib/DraftEntityInstance.js webpack █████████████████████████ building modules (67%) 665/690 modules 25 ac node_modules/axios/lib/utils.js webpack █████████████████████████ building modules (67%) 685/712 modules 27 ac node_modules/add-dom-event-listener/lib/index.js webpack █████████████████████████ building modules (68%) 735/756 modules 21 ac node_modules/lodash/_objectToString.js webpack █████████████████████████ building modules (68%) 737/758 modules 21 ac node_modules/lodash/_getRawTag.js webpack █████████████████████████ building modules (67%) 756/787 modules 31 ac node_modules/add-dom-event-listener/lib/EventObject.js webpack █████████████████████████ building modules (67%) 771/800 modules 29 ac node_modules/core-js/library/modules/_add-to-unscopables.js webpack █████████████████████████ building modules (67%) 781/808 modules 27 ac node_modules/core-js/library/modules/_object-dp.js webpack █████████████████████████ building modules (68%) 817/836 modules 19 ac node_modules/size-sensor/lib/index.js webpack █████████████████████████ building modules (68%) 845/870 modules 25 ac node_modules/is-buffer/index.js webpack █████████████████████████ building modules (68%) 892/913 modules 21 ac node_modules/echarts/lib/util/model.js webpack █████████████████████████ building modules (68%) 933/963 modules 30 ac node_modules/echarts-liquidfill/node_modules/echarts/lib/model/Series.js webpack █████████████████████████ building modules (68%) 978/996 modules 18 ac node_modules/lodash/_baseFor.js webpack █████████████████████████ building modules (68%) 1000/1029 modules 29 active node_modules/zrender/lib/contain/text.js webpack █████████████████████████ building modules (68%) 1029/1056 modules 27 ...e_modules/echarts-liquidfill/node_modules/echarts/lib/model/mixin/dataFormat.js webpack █████████████████████████ building modules (68%) 1059/1077 modules 18 node_modules/lodash/_createBaseFor.js webpack █████████████████████████ building modules (68%) 1101/1133 modules 32 node_modules/zrender/lib/graphic/helper/image.js webpack █████████████████████████ building modules (68%) 1155/1175 modules 20 node_modules/lodash/_baseGetAllKeys.js webpack █████████████████████████ building modules (69%) 1212/1231 modules 19 node_modules/size-sensor/lib/sensors/resizeObserver.js webpack █████████████████████████ building modules (68%) 1266/1296 modules 30 node_modules/d3-shape/src/curve/cardinalClosed.js webpack █████████████████████████ building modules (68%) 1329/1357 modules 28 ...ules/echarts-liquidfill/node_modules/echarts/lib/data/helper/dataStackHelper. webpack █████████████████████████ building modules (69%) 1392/1409 modules 17 node_modules/d3-collection/src/set.js webpack █████████████████████████ building modules (69%) 1449/1467 modules 18 node_modules/component-classes/index.js webpack █████████████████████████ building modules (68%) 1481/1507 modules 26 node_modules/d3-time/src/second.js webpack █████████████████████████ building modules (69%) 1534/1551 modules 17 node_modules/echarts-liquidfill/src/liquidFillView.js webpack █████████████████████████ building modules (69%) 1594/1607 modules 13 node_modules/rc-animate/es/CSSMotion.js webpack █████████████████████████ building modules (68%) 1651/1691 modules 40 node_modules/echarts/lib/component/gridSimple.js webpack █████████████████████████ building modules (69%) 1700/1713 modules 13 node_modules/echarts/lib/coord/calendar/prepareCustom.js webpack █████████████████████████ building modules (68%) 1739/1771 modules 32 node_modules/echarts/lib/component/tooltip/TooltipContent.js webpack █████████████████████████ building modules (69%) 1780/1807 modules 27 node_modules/echarts/lib/chart/scatter/ScatterView.js webpack █████████████████████████ building modules (69%) 1781/1808 modules 27 node_modules/echarts/lib/chart/scatter/ScatterSeries.js webpack █████████████████████████ building modules (68%) 1819/1852 modules 33 node_modules/echarts/lib/chart/graph/categoryFilter.js webpack █████████████████████████ building modules (69%) 1867/1880 modules 13 node_modules/echarts/lib/chart/sankey/SankeySeries.js webpack █████████████████████████ building modules (69%) 1916/1944 modules 28 node_modules/echarts/lib/component/dataZoom/DataZoomView.js webpack █████████████████████████ building modules (69%) 1966/1993 modules 27 node_modules/echarts/lib/chart/sunburst/SunburstPiece.js webpack █████████████████████████ building modules (69%) 2002/2030 modules 28 node_modules/draft-js/lib/CompositeDraftDecorator.js webpack █████████████████████████ building modules (69%) 2010/2034 modules 24 node_modules/echarts/lib/component/marker/MarkerModel.js webpack █████████████████████████ building modules (69%) 2031/2047 modules 16 babel-loadersrc/pages/dashboard/components/browser.js webpack █████████████████████████ building modules (69%) 2081/2100 modules 19 node_modules/array-tree-filter/lib/index.js webpack █████████████████████████ building modules (69%) 2105/2122 modules 17 node_modules/echarts/lib/component/dataZoom/SelectZoomModel.js webpack █████████████████████████ building modules (69%) 2108/2123 modules 15 webpack █████████████████████████ building modules (69%) 2117/2127 modules 10 node_modules/react-router-redux/es/middleware.js webpack █████████████████████████ building modules (69%) 2122/2130 modules 8 active node_modules/react-router-redux/es/actions.js webpack █████████████████████████ building modules (69%) 2143/2167 modules 24 node_modules/react-redux/es/connect/connect.js webpack █████████████████████████ building modules (69%) 2185/2203 modules 18 node_modules/rc-dialog/es/DialogWrap.js webpack █████████████████████████ building modules (69%) 2237/2265 modules 28 node_modules/antd/es/tag/index.js webpack █████████████████████████ building modules (69%) 2283/2301 modules 18 babel-loadersrc/pages/user/components/Filter.js webpack █████████████████████████ building modules (69%) 2327/2338 modules 11 node_modules/rc-util/es/getScrollBarSize.js webpack █████████████████████████ building modules (69%) 2339/2357 modules 18 node_modules/async-validator/es/index.js webpack █████████████████████████ building modules (69%) 2347/2363 modules 16 node_modules/lodash/_createCurry.js webpack █████████████████████████ building modules (69%) 2384/2400 modules 16 node_modules/rmc-feedback/es/index.js webpack █████████████████████████ building modules (69%) 2402/2422 modules 20 node_modules/dom-align/es/getAlignOffset.js webpack █████████████████████████ building modules (69%) 2426/2438 modules 12 node_modules/dva-core/lib/prefixType.js webpack █████████████████████████ building modules (69%) 2430/2438 modules 8 a webpack █████████████████████████ building modules (69%) 2451/2471 modules 20 node_modules/antd/es/badge/index.js webpack █████████████████████████ building modules (69%) 2485/2494 modules 9 a node_modules/fbjs/lib/emptyObject.js webpack █████████████████████████ building modules (69%) 2490/2520 modules 30 node_modules/antd/es/date-picker/WeekPicker.js webpack █████████████████████████ building modules (69%) 2512/2524 modules 12 node_modules/react-side-effect/lib/index.js webpack █████████████████████████ building modules (69%) 2519/2529 modules 10 node_modules/redux-saga/lib/internal/runSaga.js webpack █████████████████████████ building modules (69%) 2524/2532 modules 8 a node_modules/antd/es/layout/Sider.js webpack █████████████████████████ building modules (69%) 2540/2549 modules 9 a node_modules/antd/es/_util/getDataOrAriaProps.js webpack █████████████████████████ building modules (69%) 2554/2561 modules 7 a node_modules/redux-saga/lib/internal/sagaHelpers/index.js webpack █████████████████████████ building modules (69%) 2577/2581 modules 4 a node_modules/rc-switch/es/index.js webpack █████████████████████████ building modules (69%) 2581/2589 modules 8 a node_modules/rc-drawer/es/index.js webpack █████████████████████████ building modules (69%) 2604/2610 modules 6 a node_modules/rc-calendar/es/date/DateInput.js webpack █████████████████████████ finish module graph (70%) webpack █████████████████████████ optimizing (73%) webpack █████████████████████████ advanced chunk modules optimization (79%) webpack █████████████████████████ after hashing (88%) webpack █████████████████████████ additional chunk assets processing (90%) webpack █████████████████████████ chunk asset optimization (92%) UglifyJSPlugin webpack █████████████████████████ after chunk asset optimization (92%) antd-admin git:(master) npm run build > antd-admin@5.0.0-beta build /Users/zuiidea/web/antd-admin> umi build[12:40:22] webpack compiled in 15s 56ms DONE Compiled successfully in 15062ms 12:40:22File sizes after gzip: 887 B dist/p__dashboard__model.js.async.js 877 B dist/precache-manifest.6d2a703c437c4f28b5f6e072817bbe6e.js 786 B dist/p__UIElement__editor__index.async.js 764 B dist/i18n-0.async.js 652 B dist/p__login__index.chunk.css 614 B dist/p__user__$id__models__detail.js.async.js 599 B dist/p__post__model.js.async.js 589 B dist/p__user__$id__index.async.js 569 B dist/service-worker.js 530 B dist/p__request__index.chunk.css 515 B dist/p__login__model.js.async.js 419 B dist/p__index.async.js 245 B dist/p__chart__ECharts__index.chunk.css 230 B dist/p__chart__Recharts__index.chunk.css 138 B dist/p__user__$id__index.chunk.css 74 B dist/p__chart__highCharts__index.chunk.css 66 B dist/p__user__index.chunk.css 66 B dist/p__post__index.chunk.cssThe bundle size is significantly larger than recommended.Consider reducing it with code splitting: https://goo.gl/9VhYWBYou can also analyze the project dependencies: https://goo.gl/LeUzfbantd-admin git:(master) + \ No newline at end of file diff --git a/docs/_media/term_i18n.svg b/docs/_media/term_i18n.svg new file mode 100644 index 0000000..a287916 --- /dev/null +++ b/docs/_media/term_i18n.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + antd-admin git:(master) antd-admin git:(master) n antd-admin git:(master) np antd-admin git:(master) npm antd-admin git:(master) npm antd-admin git:(master) npm r antd-admin git:(master) npm ru antd-admin git:(master) npm run antd-admin git:(master) npm run antd-admin git:(master) npm run a antd-admin git:(master) npm run ad antd-admin git:(master) npm run add antd-admin git:(master) npm run add- antd-admin git:(master) npm run add-l antd-admin git:(master) npm run add-lo antd-admin git:(master) npm run add-loc antd-admin git:(master) npm run add-loca antd-admin git:(master) npm run add-local antd-admin git:(master) npm run add-locale antd-admin git:(master) npm run add-locale antd-admin git:(master) npm run add-locale j antd-admin git:(master) npm run add-locale ja antd-admin git:(master) npm run e antd-admin git:(master) npm run ex antd-admin git:(master) npm run ext antd-admin git:(master) npm run extr antd-admin git:(master) npm run extra antd-admin git:(master) npm run extrac antd-admin git:(master) npm run extract antd-admin git:(master) npm run add-locale ja > antd-admin@5.0.0-beta add-locale /Users/zuiidea/web/antd-admin> lingui add-locale "ja"Added locale ja.(use "lingui extract" to extract messages)antd-admin git:(master) npm run extract > antd-admin@5.0.0-beta extract /Users/zuiidea/web/antd-admin> lingui extractantd-admin git:(master) npm run t antd-admin git:(master) npm run tr antd-admin git:(master) npm run tra antd-admin git:(master) npm run tran antd-admin git:(master) npm run trans antd-admin git:(master) npm run trans: antd-admin git:(master) npm run trans:o antd-admin git:(master) npm run trans:on antd-admin git:(master) npm run trans:onl Catalog statistics:┌─────────────┬─────────────┬─────────┐ Language Total count Missing ├─────────────┼─────────────┼─────────┤ en (source) │ 52 │ - │ ja │ 52 │ 52 │ zh │ 52 │ 0 │└─────────────┴─────────────┴─────────┘(use "lingui add-locale <language>" to add more locales)(use "lingui extract" to update catalogs with new messages)(use "lingui compile" to compile catalogs for production)antd-admin git:(master) npm run trans:only antd-admin git:(master) npm run trans:only > antd-admin@5.0.0-beta trans:only /Users/zuiidea/web/antd-admin> node ./scripts/translate.jsadd to skip: Publish Dateadd to skip: Resetadd to skip: Searchadd to skip: Search Nameadd to skip: Sendadd to skip: Sign inadd to skip: Sign outadd to skip: Switch Themeadd to skip: Tagsadd to skip: The input is not valid E-mail!add to skip: The input is not valid phone!add to skip: Titleadd to skip: Total {total} Itemsadd to skip: Unpublishedadd to skip: Updateadd to skip: Update Useradd to skip: Usernameadd to skip: Viewsadd to skip: Visibilityadd to skip: You have viewed all notifications.completed: en -> zhstart: en -> jalink: en -> ja: /dashboard -> /ja/dashboardyoudao: en -> ja: Add Param -> Param の追加youdao: en -> ja: Address -> アドレスyoudao: en -> ja: Age -> 年齢youdao: en -> ja: Are you sure delete this record? -> このレコードを削除してもよろしいですか?youdao: en -> ja: Author -> 著者youdao: en -> ja: Avatar -> アバターyoudao: en -> ja: Categories -> カテゴリyoudao: en -> ja: Clear notifications -> 通知のクリアyoudao: en -> ja: Comments -> コメントyoudao: en -> ja: Create -> 作成youdao: en -> ja: Create User -> ユーザーの作成same: en -> ja: CreateTimeyoudao: en -> ja: Dark -> 暗いyoudao: en -> ja: Delete -> 削除youdao: en -> ja: Email -> 電子メールyoudao: en -> ja: Female -> 女性youdao: en -> ja: Gender -> 性別youdao: en -> ja: Hi, -> こんにちはyoudao: en -> ja: Image -> イメージyoudao: en -> ja: Light -> 光youdao: en -> ja: Male -> 男性youdao: en -> ja: Name -> 名前youdao: en -> ja: NickName -> ニックネームyoudao: en -> ja: Not Found -> 見つからないyoudao: en -> ja: Operation -> 操作same: en -> ja: Paramsyoudao: en -> ja: Password -> パスワードyoudao: en -> ja: Phone -> 電話youdao: en -> ja: Pick an address -> 住所の選択youdao: en -> ja: Please pick an address -> 住所を選択してくださいsame: en -> ja: Publisedyoudao: en -> ja: Publish Date -> 発行日youdao: en -> ja: Reset -> リセットyoudao: en -> ja: Search -> 検索youdao: en -> ja: Search Name -> 検索名youdao: en -> ja: Send -> 送信youdao: en -> ja: Sign in -> サインインyoudao: en -> ja: Sign out -> サインアウトyoudao: en -> ja: Switch Theme -> テーマを切り替えるyoudao: en -> ja: Tags -> タグyoudao: en -> ja: The input is not valid E-mail! -> 入力が有効な電子メールではありません!youdao: en -> ja: The input is not valid phone! -> 入力は有効な電話ではありません!youdao: en -> ja: Title -> タイトルyoudao: en -> ja: Total {total} Items -> 合計{total}項目youdao: en -> ja: Unpublished -> 未発表youdao: en -> ja: Update -> 更新youdao: en -> ja: Update User -> ユーザーの更新youdao: en -> ja: Username -> 名youdao: en -> ja: Views -> 表示モードyoudao: en -> ja: Visibility -> 可視 性youdao: en -> ja: You have viewed all notifications. -> すべての通知を表示しました。completed: en -> jaAll translations have been completed.antd-admin git:(master) + \ No newline at end of file diff --git a/docs/_media/term_js_build.svg b/docs/_media/term_js_build.svg new file mode 100644 index 0000000..ff7489f --- /dev/null +++ b/docs/_media/term_js_build.svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + antd-admin git:(master) antd-admin git:(master) n antd-admin git:(master) np antd-admin git:(master) npm antd-admin git:(master) npm antd-admin git:(master) npm r antd-admin git:(master) npm ru antd-admin git:(master) npm run antd-admin git:(master) npm run antd-admin git:(master) npm run b antd-admin git:(master) npm run bu antd-admin git:(master) npm run bui antd-admin git:(master) npm run buil antd-admin git:(master) npm run build Compiling webpack █████████████████████████ compiling (0%) Compiling webpack █████████████████████████ building modules (10%) 2/2 modules 0 active Compiling webpack █████████████████████████ building modules (11%) 11/13 modules 2 active node_modules/umi/lib/createHistory.js webpack █████████████████████████ building modules (12%) 18/21 modules 3 activ node_modules/webpack/buildin/global.js webpack █████████████████████████ building modules (23%) 110/112 modules 2 active node_modules/react-dom/cjs/react-dom.production.min.js webpack █████████████████████████ building modules (23%) 115/118 modules 3 act node_modules/util/support/isBufferBrowser.js webpack █████████████████████████ building modules (23%) 116/141 modules 25 active node_modules/core-js/modules/_global.js webpack █████████████████████████ building modules (25%) 130/142 modules 12 ac node_modules/path-browserify/index.js webpack █████████████████████████ building modules (27%) 147/191 modules 44 ac node_modules/core-js/modules/_bind.js webpack █████████████████████████ building modules (35%) 215/256 modules 41 ac node_modules/core-js/modules/_inherit-if-required.js webpack █████████████████████████ building modules (39%) 249/266 modules 17 ac node_modules/core-js/modules/web.dom.iterable.js webpack █████████████████████████ building modules (42%) 267/307 modules 40 ac ...4m › postcss-loaderless-loadersrc/pages/404.less webpack █████████████████████████ building modules (47%) 313/320 modules 7 act node_modules/prop-types/index.js webpack █████████████████████████ building modules (49%) 328/351 modules 23 ac node_modules/react-router-dom/es/index.js webpack █████████████████████████ building modules (51%) 343/354 modules 11 ac babel-loadersrc/pages/chart/highCharts/HighChartsComponent.js webpack █████████████████████████ building modules (52%) 354/372 modules 18 ac src/locales/en/messages.json webpack █████████████████████████ building modules (54%) 372/394 modules 22 ac babel-loadersrc/utils/theme.js webpack █████████████████████████ building modules (57%) 395/422 modules 27 ac node_modules/@babel/runtime/helpers/arrayWithoutHoles.js webpack █████████████████████████ building modules (60%) 424/455 modules 31 ac node_modules/antd/es/card/Meta.js webpack █████████████████████████ building modules (61%) 427/463 modules 36 ac node_modules/antd/es/_util/throttleByAnimationFrame.js webpack █████████████████████████ building modules (64%) 458/477 modules 19 ac node_modules/antd/es/radio/group.js webpack █████████████████████████ building modules (67%) 476/497 modules 21 ac babel-loadersrc/pages/chart/highCharts/mapdata/europe.js webpack █████████████████████████ building modules (66%) 488/514 modules 26 ac node_modules/react-router-dom/node_modules/warning/warning.js webpack █████████████████████████ building modules (67%) 493/518 modules 25 ac ...derless-loadersrc/pages/chart/Recharts/Container.less webpack █████████████████████████ building modules (67%) 505/525 modules 20 ac node_modules/omit.js/es/index.js webpack █████████████████████████ building modules (67%) 532/559 modules 27 ac node_modules/highcharts-exporting/exporting.js webpack █████████████████████████ building modules (67%) 574/598 modules 24 ac node_modules/antd/es/date-picker/locale/en_US.js webpack █████████████████████████ building modules (68%) 589/608 modules 19 ac node_modules/draft-js/lib/ContentState.js webpack █████████████████████████ building modules (67%) 616/641 modules 25 ac node_modules/react-router/es/matchPath.js webpack █████████████████████████ building modules (67%) 656/679 modules 23 ac node_modules/draft-js/lib/DraftEntityInstance.js webpack █████████████████████████ building modules (67%) 665/690 modules 25 ac node_modules/axios/lib/utils.js webpack █████████████████████████ building modules (67%) 685/712 modules 27 ac node_modules/add-dom-event-listener/lib/index.js webpack █████████████████████████ building modules (68%) 735/756 modules 21 ac node_modules/lodash/_objectToString.js webpack █████████████████████████ building modules (68%) 737/758 modules 21 ac node_modules/lodash/_getRawTag.js webpack █████████████████████████ building modules (67%) 756/787 modules 31 ac node_modules/add-dom-event-listener/lib/EventObject.js webpack █████████████████████████ building modules (67%) 771/800 modules 29 ac node_modules/core-js/library/modules/_add-to-unscopables.js webpack █████████████████████████ building modules (67%) 781/808 modules 27 ac node_modules/core-js/library/modules/_object-dp.js webpack █████████████████████████ building modules (68%) 817/836 modules 19 ac node_modules/size-sensor/lib/index.js webpack █████████████████████████ building modules (68%) 845/870 modules 25 ac node_modules/is-buffer/index.js webpack █████████████████████████ building modules (68%) 892/913 modules 21 ac node_modules/echarts/lib/util/model.js webpack █████████████████████████ building modules (68%) 933/963 modules 30 ac node_modules/echarts-liquidfill/node_modules/echarts/lib/model/Series.js webpack █████████████████████████ building modules (68%) 978/996 modules 18 ac node_modules/lodash/_baseFor.js webpack █████████████████████████ building modules (68%) 1000/1029 modules 29 active node_modules/zrender/lib/contain/text.js webpack █████████████████████████ building modules (68%) 1029/1056 modules 27 ...e_modules/echarts-liquidfill/node_modules/echarts/lib/model/mixin/dataFormat.js webpack █████████████████████████ building modules (68%) 1059/1077 modules 18 node_modules/lodash/_createBaseFor.js webpack █████████████████████████ building modules (68%) 1101/1133 modules 32 node_modules/zrender/lib/graphic/helper/image.js webpack █████████████████████████ building modules (68%) 1155/1175 modules 20 node_modules/lodash/_baseGetAllKeys.js webpack █████████████████████████ building modules (69%) 1212/1231 modules 19 node_modules/size-sensor/lib/sensors/resizeObserver.js webpack █████████████████████████ building modules (68%) 1266/1296 modules 30 node_modules/d3-shape/src/curve/cardinalClosed.js webpack █████████████████████████ building modules (68%) 1329/1357 modules 28 ...ules/echarts-liquidfill/node_modules/echarts/lib/data/helper/dataStackHelper. webpack █████████████████████████ building modules (69%) 1392/1409 modules 17 node_modules/d3-collection/src/set.js webpack █████████████████████████ building modules (69%) 1449/1467 modules 18 node_modules/component-classes/index.js webpack █████████████████████████ building modules (68%) 1481/1507 modules 26 node_modules/d3-time/src/second.js webpack █████████████████████████ building modules (69%) 1534/1551 modules 17 node_modules/echarts-liquidfill/src/liquidFillView.js webpack █████████████████████████ building modules (69%) 1594/1607 modules 13 node_modules/rc-animate/es/CSSMotion.js webpack █████████████████████████ building modules (68%) 1651/1691 modules 40 node_modules/echarts/lib/component/gridSimple.js webpack █████████████████████████ building modules (69%) 1700/1713 modules 13 node_modules/echarts/lib/coord/calendar/prepareCustom.js webpack █████████████████████████ building modules (68%) 1739/1771 modules 32 node_modules/echarts/lib/component/tooltip/TooltipContent.js webpack █████████████████████████ building modules (69%) 1780/1807 modules 27 node_modules/echarts/lib/chart/scatter/ScatterView.js webpack █████████████████████████ building modules (69%) 1781/1808 modules 27 node_modules/echarts/lib/chart/scatter/ScatterSeries.js webpack █████████████████████████ building modules (68%) 1819/1852 modules 33 node_modules/echarts/lib/chart/graph/categoryFilter.js webpack █████████████████████████ building modules (69%) 1867/1880 modules 13 node_modules/echarts/lib/chart/sankey/SankeySeries.js webpack █████████████████████████ building modules (69%) 1916/1944 modules 28 node_modules/echarts/lib/component/dataZoom/DataZoomView.js webpack █████████████████████████ building modules (69%) 1966/1993 modules 27 node_modules/echarts/lib/chart/sunburst/SunburstPiece.js webpack █████████████████████████ building modules (69%) 2002/2030 modules 28 node_modules/draft-js/lib/CompositeDraftDecorator.js webpack █████████████████████████ building modules (69%) 2010/2034 modules 24 node_modules/echarts/lib/component/marker/MarkerModel.js webpack █████████████████████████ building modules (69%) 2031/2047 modules 16 babel-loadersrc/pages/dashboard/components/browser.js webpack █████████████████████████ building modules (69%) 2081/2100 modules 19 node_modules/array-tree-filter/lib/index.js webpack █████████████████████████ building modules (69%) 2105/2122 modules 17 node_modules/echarts/lib/component/dataZoom/SelectZoomModel.js webpack █████████████████████████ building modules (69%) 2108/2123 modules 15 webpack █████████████████████████ building modules (69%) 2117/2127 modules 10 node_modules/react-router-redux/es/middleware.js webpack █████████████████████████ building modules (69%) 2122/2130 modules 8 active node_modules/react-router-redux/es/actions.js webpack █████████████████████████ building modules (69%) 2143/2167 modules 24 node_modules/react-redux/es/connect/connect.js webpack █████████████████████████ building modules (69%) 2185/2203 modules 18 node_modules/rc-dialog/es/DialogWrap.js webpack █████████████████████████ building modules (69%) 2237/2265 modules 28 node_modules/antd/es/tag/index.js webpack █████████████████████████ building modules (69%) 2283/2301 modules 18 babel-loadersrc/pages/user/components/Filter.js webpack █████████████████████████ building modules (69%) 2327/2338 modules 11 node_modules/rc-util/es/getScrollBarSize.js webpack █████████████████████████ building modules (69%) 2339/2357 modules 18 node_modules/async-validator/es/index.js webpack █████████████████████████ building modules (69%) 2347/2363 modules 16 node_modules/lodash/_createCurry.js webpack █████████████████████████ building modules (69%) 2384/2400 modules 16 node_modules/rmc-feedback/es/index.js webpack █████████████████████████ building modules (69%) 2402/2422 modules 20 node_modules/dom-align/es/getAlignOffset.js webpack █████████████████████████ building modules (69%) 2426/2438 modules 12 node_modules/dva-core/lib/prefixType.js webpack █████████████████████████ building modules (69%) 2430/2438 modules 8 a webpack █████████████████████████ building modules (69%) 2451/2471 modules 20 node_modules/antd/es/badge/index.js webpack █████████████████████████ building modules (69%) 2485/2494 modules 9 a node_modules/fbjs/lib/emptyObject.js webpack █████████████████████████ building modules (69%) 2490/2520 modules 30 node_modules/antd/es/date-picker/WeekPicker.js webpack █████████████████████████ building modules (69%) 2512/2524 modules 12 node_modules/react-side-effect/lib/index.js webpack █████████████████████████ building modules (69%) 2519/2529 modules 10 node_modules/redux-saga/lib/internal/runSaga.js webpack █████████████████████████ building modules (69%) 2524/2532 modules 8 a node_modules/antd/es/layout/Sider.js webpack █████████████████████████ building modules (69%) 2540/2549 modules 9 a node_modules/antd/es/_util/getDataOrAriaProps.js webpack █████████████████████████ building modules (69%) 2554/2561 modules 7 a node_modules/redux-saga/lib/internal/sagaHelpers/index.js webpack █████████████████████████ building modules (69%) 2577/2581 modules 4 a node_modules/rc-switch/es/index.js webpack █████████████████████████ building modules (69%) 2581/2589 modules 8 a node_modules/rc-drawer/es/index.js webpack █████████████████████████ building modules (69%) 2604/2610 modules 6 a node_modules/rc-calendar/es/date/DateInput.js webpack █████████████████████████ finish module graph (70%) webpack █████████████████████████ optimizing (73%) webpack █████████████████████████ advanced chunk modules optimization (79%) webpack █████████████████████████ after hashing (88%) webpack █████████████████████████ additional chunk assets processing (90%) webpack █████████████████████████ chunk asset optimization (92%) UglifyJSPlugin webpack █████████████████████████ after chunk asset optimization (92%) antd-admin git:(master) npm run build > antd-admin@5.0.0-beta build /Users/zuiidea/web/antd-admin> umi build[12:40:22] webpack compiled in 15s 56ms DONE Compiled successfully in 15062ms 12:40:22File sizes after gzip: 887 B dist/p__dashboard__model.js.async.js 877 B dist/precache-manifest.6d2a703c437c4f28b5f6e072817bbe6e.js 786 B dist/p__UIElement__editor__index.async.js 764 B dist/i18n-0.async.js 652 B dist/p__login__index.chunk.css 614 B dist/p__user__$id__models__detail.js.async.js 599 B dist/p__post__model.js.async.js 589 B dist/p__user__$id__index.async.js 569 B dist/service-worker.js 530 B dist/p__request__index.chunk.css 515 B dist/p__login__model.js.async.js 419 B dist/p__index.async.js 245 B dist/p__chart__ECharts__index.chunk.css 230 B dist/p__chart__Recharts__index.chunk.css 138 B dist/p__user__$id__index.chunk.css 74 B dist/p__chart__highCharts__index.chunk.css 66 B dist/p__user__index.chunk.css 66 B dist/p__post__index.chunk.cssThe bundle size is significantly larger than recommended.Consider reducing it with code splitting: https://goo.gl/9VhYWBYou can also analyze the project dependencies: https://goo.gl/LeUzfbantd-admin git:(master) + 0:00/0:00 + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_media/term_js_i18n.svg b/docs/_media/term_js_i18n.svg new file mode 100644 index 0000000..f985604 --- /dev/null +++ b/docs/_media/term_js_i18n.svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + antd-admin git:(master) antd-admin git:(master) n antd-admin git:(master) np antd-admin git:(master) npm antd-admin git:(master) npm antd-admin git:(master) npm r antd-admin git:(master) npm ru antd-admin git:(master) npm run antd-admin git:(master) npm run antd-admin git:(master) npm run a antd-admin git:(master) npm run ad antd-admin git:(master) npm run add antd-admin git:(master) npm run add- antd-admin git:(master) npm run add-l antd-admin git:(master) npm run add-lo antd-admin git:(master) npm run add-loc antd-admin git:(master) npm run add-loca antd-admin git:(master) npm run add-local antd-admin git:(master) npm run add-locale antd-admin git:(master) npm run add-locale antd-admin git:(master) npm run add-locale j antd-admin git:(master) npm run add-locale ja antd-admin git:(master) npm run e antd-admin git:(master) npm run ex antd-admin git:(master) npm run ext antd-admin git:(master) npm run extr antd-admin git:(master) npm run extra antd-admin git:(master) npm run extrac antd-admin git:(master) npm run extract antd-admin git:(master) npm run add-locale ja > antd-admin@5.0.0-beta add-locale /Users/zuiidea/web/antd-admin> lingui add-locale "ja"Added locale ja.(use "lingui extract" to extract messages)antd-admin git:(master) npm run extract > antd-admin@5.0.0-beta extract /Users/zuiidea/web/antd-admin> lingui extractantd-admin git:(master) npm run t antd-admin git:(master) npm run tr antd-admin git:(master) npm run tra antd-admin git:(master) npm run tran antd-admin git:(master) npm run trans antd-admin git:(master) npm run trans: antd-admin git:(master) npm run trans:o antd-admin git:(master) npm run trans:on antd-admin git:(master) npm run trans:onl Catalog statistics:┌─────────────┬─────────────┬─────────┐ Language Total count Missing ├─────────────┼─────────────┼─────────┤ en (source) │ 52 │ - │ ja │ 52 │ 52 │ zh │ 52 │ 0 │└─────────────┴─────────────┴─────────┘(use "lingui add-locale <language>" to add more locales)(use "lingui extract" to update catalogs with new messages)(use "lingui compile" to compile catalogs for production)antd-admin git:(master) npm run trans:only antd-admin git:(master) npm run trans:only > antd-admin@5.0.0-beta trans:only /Users/zuiidea/web/antd-admin> node ./scripts/translate.jsadd to skip: Publish Dateadd to skip: Resetadd to skip: Searchadd to skip: Search Nameadd to skip: Sendadd to skip: Sign inadd to skip: Sign outadd to skip: Switch Themeadd to skip: Tagsadd to skip: The input is not valid E-mail!add to skip: The input is not valid phone!add to skip: Titleadd to skip: Total {total} Itemsadd to skip: Unpublishedadd to skip: Updateadd to skip: Update Useradd to skip: Usernameadd to skip: Viewsadd to skip: Visibilityadd to skip: You have viewed all notifications.completed: en -> zhstart: en -> jalink: en -> ja: /dashboard -> /ja/dashboardyoudao: en -> ja: Add Param -> Param の追加youdao: en -> ja: Address -> アドレスyoudao: en -> ja: Age -> 年齢youdao: en -> ja: Are you sure delete this record? -> このレコードを削除してもよろしいですか?youdao: en -> ja: Author -> 著者youdao: en -> ja: Avatar -> アバターyoudao: en -> ja: Categories -> カテゴリyoudao: en -> ja: Clear notifications -> 通知のクリアyoudao: en -> ja: Comments -> コメントyoudao: en -> ja: Create -> 作成youdao: en -> ja: Create User -> ユーザーの作成same: en -> ja: CreateTimeyoudao: en -> ja: Dark -> 暗いyoudao: en -> ja: Delete -> 削除youdao: en -> ja: Email -> 電子メールyoudao: en -> ja: Female -> 女性youdao: en -> ja: Gender -> 性別youdao: en -> ja: Hi, -> こんにちはyoudao: en -> ja: Image -> イメージyoudao: en -> ja: Light -> 光youdao: en -> ja: Male -> 男性youdao: en -> ja: Name -> 名前youdao: en -> ja: NickName -> ニックネームyoudao: en -> ja: Not Found -> 見つからないyoudao: en -> ja: Operation -> 操作same: en -> ja: Paramsyoudao: en -> ja: Password -> パスワードyoudao: en -> ja: Phone -> 電話youdao: en -> ja: Pick an address -> 住所の選択youdao: en -> ja: Please pick an address -> 住所を選択してくださいsame: en -> ja: Publisedyoudao: en -> ja: Publish Date -> 発行日youdao: en -> ja: Reset -> リセットyoudao: en -> ja: Search -> 検索youdao: en -> ja: Search Name -> 検索名youdao: en -> ja: Send -> 送信youdao: en -> ja: Sign in -> サインインyoudao: en -> ja: Sign out -> サインアウトyoudao: en -> ja: Switch Theme -> テーマを切り替えるyoudao: en -> ja: Tags -> タグyoudao: en -> ja: The input is not valid E-mail! -> 入力が有効な電子メールではありません!youdao: en -> ja: The input is not valid phone! -> 入力は有効な電話ではありません!youdao: en -> ja: Title -> タイトルyoudao: en -> ja: Total {total} Items -> 合計{total}項目youdao: en -> ja: Unpublished -> 未発表youdao: en -> ja: Update -> 更新youdao: en -> ja: Update User -> ユーザーの更新youdao: en -> ja: Username -> 名youdao: en -> ja: Views -> 表示モードyoudao: en -> ja: Visibility -> 可視 性youdao: en -> ja: You have viewed all notifications. -> すべての通知を表示しました。completed: en -> jaAll translations have been completed.antd-admin git:(master) + 0:00/0:00 + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_sidebar.md b/docs/_sidebar.md new file mode 100644 index 0000000..3d6d176 --- /dev/null +++ b/docs/_sidebar.md @@ -0,0 +1,12 @@ +- Getting started + - [Quick Start](getting-started.md) +- Customization + - [Configuration](configuration.md) + - [API Configuration](API-configuration.md) + - [I18n](i18n.md) + - [Layout](layout.md) + - [Request](request.md) +- Guide + - [Deploy](deploy.md) +- [Change Log](change-log.md) +- [FAQ](faq.md) diff --git a/docs/change-log.md b/docs/change-log.md new file mode 100644 index 0000000..3465321 --- /dev/null +++ b/docs/change-log.md @@ -0,0 +1,50 @@ +## 5.0.0 + +#### Optimization + +- Try to use decorators to simplify code writing and improve code readability. + +- API configurization to simplify the way data is obtained. + +- The files in `utils` are split and each has its own role. + +- Simplify the `utils/request` file without special handling. + +#### Specification + +- Functions add comments, parameters, return values, etc., ambiguous code adds comments, canonical reference [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html#appendices-jsdoc-tag-reference). +   +- Semantic version number, specification participation [semantic version 2.0.0](https://semver.org/lang/zh-CN/). + +- Static code checking, unified code style, will use `prettier`, `stylelint`, `eslint` specification code before code submission. + +- Git submits information normalization, [git-commit-emoji-cn](https://github.com/liuchengxu/git-commit-emoji-cn). + +- Based on the pre-defined routing of `Umi`, there is no need to write a routing configuration file. + +- Use `React 16` new features such as `Fragment`, `Context`, `PureComponent`, etc. + +#### Features + +- Support internationalization, extract source fields from source code, load language packs on demand, and automatically translate online. + +- Support for the introduction `lodash` functions on demand. +   +- Support multiple layouts, which rules can be used according to the rules. + +- Support Antd Admin to automatically compile and deploy on Travis. + +- Generate a documentation website using `Docsify`. + + +#### Style + +- Added Antd Admin standalone Logo. + +- Rewrite the overall layout component, optimize the menu, automatic breadcrumb navigation, menu auto-expansion and other logic. + +- The mobile menu is changed to drawer. + +#### Other + +- Discard components such as `IconFont`, `Search`, `DataTable` because they are well supported and replaceable in `Antd`. \ No newline at end of file diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..54acff7 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,102 @@ +# Configuration + +You can do some custom configuration in `/src/utils/config.js`: + +## siteName + +- Type `String` + + Configure the site name, apply it to the login box, and display the title text at the top of the sidebar. + +## copyright + +- Type: `String` + + Configure the copyright notice to apply to the login page, at the bottom of the `Primary` layout. + +## logoPath + +- Type: `String` + + Configure the site logo to apply to the login box and the Logo display at the top of the sidebar. + +## apiPrefix + +- Type: `String` + + Configure the prefix of the interface in the project. The interface related documents can be viewed [API configuration](API-configuration.md) + +## fixedHeader + +- Type: `String` + + Under the `Primary` layout, whether the top of the page is fixed when scrolling。 + +## layouts + +- Type: `Array` + + Configuration? Which routes use which layout, unspecified route uses the default layout `Public`, the project currently has `Primary` and `Public` layouts, +     The default configuration is as follows: + + ```javascript + layouts: [ + { + name: 'primary', + include: [/.*/], + exclude: [/(\/(en|zh))*\/login/], + }, + ], + ``` + + The object properties for each layout are as follows: + + - `name` - The name of the layout; + + - `include` - Specifies a list of routing rules that use this layout, which can be a regular expression or a string; + + - `exclude` - Specifies a list of routing rules that do not use this layout, which can be a regular expression or a string. + + > Note: `exclude` takes precedence over `include`, and the layout previous it has a higher priority than the behind layout. The development process may need to be combined with the layout in the `src/layouts` directory. For details, see [Using Layout](./layout.md). + +## i18n + +- Type: `Object` + + Configure internationalization, the default configuration is as follows: + + ```javascript + i18n: { + languages: [ + { + key: 'en', + title: 'English', + flag: '/america.svg', + }, + { + key: 'zh', + title: '中文', + flag: '/china.svg', + }, + ], + defaultLanguage: 'en', + } + ``` + + ### i18n.languages + + - Type: `Array` + + Specify which languages the app supports, and the object properties for each language are as follows: + + - `key` - The `key` of the language is applied to the page url to distinguish the language, and also corresponds to the language package folder name in the `src/locales` directory; + + - `title` - The name of the language, at the bottom of the login page, at the top of the `Primary` layout, the language switch is displayed; + + - `flag` - The path of the flag icon of the language, the language switching display at the top of the `Primary` layout. + + ### i18n.defaultLanguage + + - Type: `String` + + Configure the default language. diff --git a/docs/deploy.md b/docs/deploy.md new file mode 100644 index 0000000..3cc157f --- /dev/null +++ b/docs/deploy.md @@ -0,0 +1,113 @@ +# Deploy + +After the development is completed and verified in the development environment, it needs to be deployed to our users. + +![i18n](./_media/term_build.svg) + +## Build + +First execute the following command, + +```bash +npm run build +``` + +After a few seconds, the output should look like this: + +```bash +> antd-admin@5.0.0-beta build /Users/zuiidea/web/antd-admin +> umi build + +[21:13:17] webpack compiled in 43s 868ms + DONE Compiled successfully in 43877ms 21:13:17 + +File sizes after gzip: + + 1.3 MB dist/vendors.async.js + 308.21 KB dist/umi.js + 45.49 KB dist/vendors.chunk.css + 36.08 KB dist/p__chart__highCharts__index.async.js + 33.53 KB dist/p__user__index.async.js + 22.36 KB dist/p__chart__ECharts__index.async.js + 4.21 KB dist/p__dashboard__index.async.js + 4.06 KB dist/umi.css + ... +``` + +The `build` command will package all resources, including JavaScript, CSS, web fonts, images, html, and more. You can find these files in the `dist/` directory. + +> If you have requirements for using HashHistory , deploying html to non-root directories, statics, etc., check out [Umi Deployment] (https://umijs.org/en/guide/deploy.html). + +## Local verification + + +Local verification can be done via `serve` before publishing. + +``` +$ yarn global add serve +$ serve ./dist + +Serving! + +- Local: http://localhost:5000 +- On Your Network: http://{Your IP}:5000 + +Copied local address to clipboard! + +``` + +Access [http://localhost:5000](http://localhost:5000), under normal circumstances, it should be consistent with `npm start` (The API may not get the correct data). + + +## Deploy + +Next, we can upload the static file to the server. If you use Nginx as the Web server, you can configure it in `ngnix.conf`: +``` +server + { + listen 80; + # Specify an accessible domain name + server_name antd-admin.zuiidea.com; + # The directory where the compiled files are stored + root /home/www/antd-admin/dist; + + # Proxy server interface to avoid cross-domain + location /api { + proxy_pass http://localhost:7000/api; + } + + Because the front end uses BrowserHistory, it will route backback to index.html + location / { + index index.html; + try_files $uri $uri/ /index.html; + } + } +``` + +Restart the web server and access [http://antd-admin.zuiidea.com](http://antd-admin.zuiidea.com) , You will see the correct page. + +```bash +nginx -s reload +``` + +Similarly, if you use Caddy as a web server, you can do this in `Caddyfile`: + +``` +antd-admin.zuiidea.com { + gzip + root /home/www/antd-admin/dist + proxy /api http://localhost:7000 + + rewrite { + if {path} not_match ^/api + to {path} {path}/ / + } +} + + +antd-admin.zuiidea.com/public { + gzip + root /home/www/antd-admin/dist/static/public +} + +``` diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..2c6409d --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,9 @@ +# FAQ + +Most asked + +## create new page + + 1. just copy a page in /src/pages (route here auto generated by [umi](https://umijs.org/guide/router.html#basic-routing)) + 2. modify namespace/pathToRegexp in model.js + 3. modify mock route.js to add a route \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..9a9c90f --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,73 @@ +# Quick Start + +> Before delving into Ant Design React, a good knowledge base of [React](http://facebook.github.io/react/) 、 [ES2015+](http://es6.ruanyifeng.com/) 、 [Antd Design](https://ant.design/docs/react/introduce-cn) . Learn about [UmiJS](https://umijs.org/) , [Dva](http://github.com/dvajs/dva) . And properly installed and configured [Node.js](https://nodejs.org/) v8 or above, [Git](https://git-scm.com/). It would be helpful if you have pre-existing knowledge on those. + +## Installation + +```bash +git clone https://github.com/zuiidea/antd-admin.git my-project +cd my-project +``` + +## Scaffolding + +The project layout is as follows: + +```bash +├── dist/ # Default build output directory +├── mock/ # Mock files +├── public/ # Static resource +├── src/ # Source code +│ ├── components/ # Components +│ ├── e2e/ # Integrated Test Case +│ ├── layouts/ # Common Layouts +│ ├── locales/ # i18n resources +│ ├── models/ # Global dva Model +│ ├── pages/ # Sub-pages and templates +│ ├── services/ # Backend Services +│ │ ├── api.js # API configuration +│ │ └── index.js # API export +│ ├── themes/ # Themes +│ │ ├── default.less # Less variable +│ │ ├── index.less # Global style +│ │ ├── mixin.less # Less mixin +│ │ └── vars.less # Less variable and mixin +│ ├── utils/ # Utility +│ │ ├── config.js # Application configuration +│ │ ├── constant.js # Static constant +│ │ ├── index.js # Utility methods +│ │ ├── request.js # Request function(axios) +│ │ └── theme.js # Style variables used in js +├── .editorconfig +├── .env +├── .eslintrc +├── .gitignore +├── .prettierignore +├── .prettierrc +├── .stylelintrc.json +├── .travis.yml +└── .umirc.js +└── package.json +``` + +## Development + +1. Install Dependencies. + +```bash +yarn install +``` + +Or + +```bash +npm install +``` + +2. Start local server. + +```bash +npm run start +``` + +3. After the startup is complete, open a browser and visit [http://localhost:7000](http://localhost:7000), If you need to change the startup port, you can configure it in the `.env` file. diff --git a/docs/i18n.md b/docs/i18n.md new file mode 100644 index 0000000..33bf011 --- /dev/null +++ b/docs/i18n.md @@ -0,0 +1,75 @@ +# globalization + +## Add language + +Take Japanese as an example. + +![i18n](../_media/term_i18n.svg) + +1. Add a language pack local file, `ja` is the Japanese language code, and a list of languages ​​that support translation [有道智云](http://ai.youdao.com/docs/doc-trans-api.s#p05), the `src/locales/ja/messages.json` file will be generated after running the following command. + + ```bash  + npm run add-locale ja + ``` + +2. Extract the fields in the code that need to be translated, ie `?message`, `` t`message `` in the `message` field, run the following command after `src/locales/ja /messages.json` will appear after the extracted field configuration. + + ```bash  + npm run extract + ``` + + You will see the following information: + + ```bash + Catalog statistics: + ┌─────────────┬─────────────┬─────────┐ + │ Language │ Total count │ Missing │ + ├─────────────┼─────────────┼─────────┤ + │ en (source) │ 52 │ - │ + │ ja │ 52 │ 52 │ + │ zh │ 52 │ 0 │ + └─────────────┴─────────────┴─────────┘ + ``` + +3. At the same time, we have added the relevant configuration in `src/utils/config.js`. + + ```javascript + { + ... + i18n: { + languages: [ + ... + { + key:'ja', + title: '日本語', + flag: '/japanese.svg', + }, + ], + }, + } + ``` + + > Routing related effects, after the configuration `npm run start` takes effect after restart. + +4. Use the built-in commands for automatic translation. You will see the translated configuration in `src/locales/ja/messages.json`. + + ```bash + npm run trans:only + ``` + + You will see the following information: + + ```bash + start: en -> ja + ... + youdao: en -> ja: Unpublished -> 未発表 + youdao: en -> ja: Update -> 更新 + youdao: en -> ja: Update User -> ユーザーの更新 + youdao: en -> ja: Username -> 名 + ... + All translations have been completed. + ``` + + > `npm run trans` will execute `npm run extract` and `npm run trans:only` in order. + +5. Finally, you can adjust the inaccurate fields in `src/locales/ja/messages.json`. Start the development mode `npm run start`, open [http://localhost:7000/ja/login](http://localhost:7000/ja/login) and you will see the Japanese version of the app. diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..e981d4c --- /dev/null +++ b/docs/index.html @@ -0,0 +1,55 @@ + + + + + + antd-admin - An admin dashboard application demo built upon Ant Design and UmiJS + + + + + + + + + +
Loading...
+ + + + + + + + + \ No newline at end of file diff --git a/docs/layout.md b/docs/layout.md new file mode 100644 index 0000000..22223ad --- /dev/null +++ b/docs/layout.md @@ -0,0 +1,60 @@ +# Layout + +## Add a new layout + +Take a new layout named `secondary` as an example to make the route starting with `secondary` use this layout. + +1. Add related configuration in `src/utils/config.js`. For details, please refer to [layouts](/configuration?id=layouts). + +```javascript +   layouts: [ +           { +               name: 'primary', +               include: [/.*/], +               exclude: [/(\/(en|zh))*\/login/, /(\/(en|zh))*\/secondary\/(.*)/], +           }, +           { +               name: 'secondary', +               include: [/(\/(en|zh))*\/secondary\/(.*)/], +           }, +   ], +``` + +2. Add the `secondary` layout component to the `src/layouts/BaseLayout.js` file. + +```javascript +   import SecondaryLayout from './SecondaryLayout' + +   const LayoutMap = { +     primary: PrimaryLayout, +     public: PublicLayout, +     secondary: SecondaryLayout, +   } +``` + +3. Add the `SecondaryLayout.js` file to the `src/layouts/` directory. + +```javascript +   import React from 'react' + +   export default ({ children }) => { +     return ( +       
+         

Secondary

+         {children} +       
+     ) +   } +``` + +4. Add a `secondary/index.js` file to the `src/pages/` directory. + +```javascript +   import React from 'react' + +   export default ({ children }) => { +     Return
Secondary page Content
+   } +``` + +5. Finally, start the development mode `npm run start`, open [http://localhost:7000/secondary/](http://localhost:7000/secondary/) and you will see the page for the `secondary` layout. diff --git a/docs/request.md b/docs/request.md new file mode 100644 index 0000000..69d6607 --- /dev/null +++ b/docs/request.md @@ -0,0 +1,22 @@ +# HTTP request + +this project use axios for http service, file located in src/utils/request.js + +## Custom Header + +As for privilege access or modify cookie, you could add header param by yourself + +``` +axios.defaults.headers.common['Authorization'] = 'token' +``` + +Or + +``` +axios.interceptors.request.use(function (config) { + config.headers.token = window.localStorage.getItem('token'); + return config; +}, function (error) { + return Promise.reject(error); +}); +``` \ No newline at end of file diff --git a/docs/sw.js b/docs/sw.js new file mode 100644 index 0000000..cf6295c --- /dev/null +++ b/docs/sw.js @@ -0,0 +1,83 @@ +/* =========================================================== + * docsify sw.js + * =========================================================== + * Copyright 2016 @huxpro + * Licensed under Apache 2.0 + * Register service worker. + * ========================================================== */ + +const RUNTIME = 'docsify' +const HOSTNAME_WHITELIST = [ + self.location.hostname, + 'fonts.gstatic.com', + 'fonts.googleapis.com', + 'unpkg.com' +] + +// The Util Function to hack URLs of intercepted requests +const getFixedUrl = (req) => { + var now = Date.now() + var url = new URL(req.url) + + // 1. fixed http URL + // Just keep syncing with location.protocol + // fetch(httpURL) belongs to active mixed content. + // And fetch(httpRequest) is not supported yet. + url.protocol = self.location.protocol + + // 2. add query for caching-busting. + // Github Pages served with Cache-Control: max-age=600 + // max-age on mutable content is error-prone, with SW life of bugs can even extend. + // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. + // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 + if (url.hostname === self.location.hostname) { + url.search += (url.search ? '&' : '?') + 'cache-bust=' + now + } + return url.href +} + +/** + * @Lifecycle Activate + * New one activated when old isnt being used. + * + * waitUntil(): activating ====> activated + */ +self.addEventListener('activate', event => { + event.waitUntil(self.clients.claim()) +}) + +/** + * @Functional Fetch + * All network requests are being intercepted here. + * + * void respondWith(Promise r) + */ +self.addEventListener('fetch', event => { + // Skip some of cross-origin requests, like those for Google Analytics. + if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { + // Stale-while-revalidate + // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale + // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 + const cached = caches.match(event.request) + const fixedUrl = getFixedUrl(event.request) + const fetched = fetch(fixedUrl, { cache: 'no-store' }) + const fetchedCopy = fetched.then(resp => resp.clone()) + + // Call respondWith() with whatever we get first. + // If the fetch fails (e.g disconnected), wait for the cache. + // If there’s nothing in cache, wait for the fetch. + // If neither yields a response, return offline pages. + event.respondWith( + Promise.race([fetched.catch(_ => cached), cached]) + .then(resp => resp || fetched) + .catch(_ => { /* eat any errors */ }) + ) + + // Update the cache with the version we fetched (only for ok status) + event.waitUntil( + Promise.all([fetchedCopy, caches.open(RUNTIME)]) + .then(([response, cache]) => response.ok && cache.put(event.request, response)) + .catch(_ => { /* eat any errors */ }) + ) + } +}) \ No newline at end of file diff --git a/docs/zh-cn/API-configuration.md b/docs/zh-cn/API-configuration.md new file mode 100644 index 0000000..19913ac --- /dev/null +++ b/docs/zh-cn/API-configuration.md @@ -0,0 +1,86 @@ +# 接口配置 + +## 为什么 + +在使用了`redux`或者`dva`项目中,我们经常会写类似下面的`service`层的函数,使代码结构更清晰,但是很容易看出,我们会写很多相似的代码,在`antd-admin@5.0`中,使用了更加简洁的配置方式实现了相同的功能。 + +```javascript +export async function login(data) { + return request({ + url: '/api/v1/user/login', + method: 'post', + data, + }) +} +``` + +## 配置和使用 + +在`src/services/api.js`文件中,你会看到如下配置对象,对象的键用于调用时的函数名称,对象的值为请求的`url`,默认请求方式为`GET`,如果是其他请求方式对象的值的格式则为`'method url'`。 + +```javascript +export default { + ... + queryUser: '/user/:id', + queryUserList: '/users', + updateUser: 'Patch /user/:id', + createUser: 'POST /user/:id', + removeUser: 'DELETE /user/:id', + removeUserList: 'POST /users/delete', + ... +} +``` + +在其他文件中使用 + +```javascript +import { queryUser } from 'api' + +// 一般文件中 +... +queryUser(option).then(data => console.log(data)) +... + +// model文件中 +... +yield call(queryUser, option) +... +``` + +## 实现方式 + +参考`src/services/index.js`文件,对api配置进行遍历,每个属性都返回对应的封装后的request函数。 + +```javascript +import request from 'utils/request' +import { apiPrefix } from 'utils/config' + +import api from './api' + +const gen = params => { + let url = apiPrefix + params + let method = 'GET' + + const paramsArray = params.split(' ') + if (paramsArray.length === 2) { + method = paramsArray[0] + url = apiPrefix + paramsArray[1] + } + + return function(data) { + return request({ + url, + data, + method, + }) + } +} + +const APIFunction = {} +for (const key in api) { + APIFunction[key] = gen(api[key]) +} + +module.exports = APIFunction + +``` \ No newline at end of file diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md new file mode 100644 index 0000000..61799bb --- /dev/null +++ b/docs/zh-cn/README.md @@ -0,0 +1,84 @@ +

+ + antd-admin + +

+ +

AntD Admin

+ +
+ +一套优秀的中后台前端解决方案 + +[![antd](https://img.shields.io/badge/antd-^3.10.0-blue.svg?style=flat-square)](https://github.com/ant-design/ant-design) +[![umi](https://img.shields.io/badge/umi-^2.2.1-orange.svg?style=flat-square)](https://github.com/umijs/umi) +[![GitHub issues](https://img.shields.io/github/issues/zuiidea/antd-admin.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/issues) +[![MIT](https://img.shields.io/dub/l/vibe-d.svg?style=flat-square)](http://opensource.org/licenses/MIT) +![Travis (.org)](https://img.shields.io/travis/zuiidea/antd-admin.svg) +[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/zuiidea/antd-admin/pulls) +[![Gitter](https://img.shields.io/gitter/room/antd-admin/antd-admin.svg)](https://gitter.im/antd-admin/antd-admin) + +
+ +- 在线演示 - [https://antd-admin.zuiidea.com](https://antd-admin.zuiidea.com) +- 使用文档 - [https://doc.antd-admin.zuiidea.com/#/zh-cn/](https://doc.antd-admin.zuiidea.com/#/zh-cn/) +- 常见问题 - [https://doc.antd-admin.zuiidea.com/#/zh-cn/faq](https://doc.antd-admin.zuiidea.com/#/zh-cn/faq) +- 更新日志 - [https://doc.antd-admin.zuiidea.com/#/zh-cn/change-log](https://doc.antd-admin.zuiidea.com/#/zh-cn/change-log) + +## 特性 + +- 国际化,源码中抽离翻译字段,按需加载语言包 +- 动态权限,不同权限对应不同菜单 +- 优雅美观,Ant Design 设计体系 +- Mock 数据,本地数据调试 + + +## 使用 + +1. 下载项目代码。 + +```bash +git clone https://github.com/zuiidea/antd-admin.git my-project +cd my-project +``` + +2. 进入目录安装依赖,国内用户推荐使用 [cnpm](https://cnpmjs.org) 进行加速。 + +```bash +yarn install +``` + +或者 + +```bash +npm install +``` + +3. 启动本地服务器。 + +```bash +npm run start +``` + +4. 启动完成后打开浏览器访问 [http://localhost:7000](http://localhost:7000),如果需要更改启动端口,可在 `.env` 文件中配置。 + + +> 更多信息请参考 [使用文档](https://doc.antd-admin.zuiidea.com/#/zh-cn/)。 + + +## 支持环境 + +现代浏览器。 + +| [IE / Edge](http://godban.github.io/browsers-support-badges/)
IE / Edge | [Firefox](http://godban.github.io/browsers-support-badges/)
Firefox | [Chrome](http://godban.github.io/browsers-support-badges/)
Chrome | [Safari](http://godban.github.io/browsers-support-badges/)
Safari | [Opera](http://godban.github.io/browsers-support-badges/)
Opera | +| --------- | --------- | --------- | --------- | --------- | +|IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions + +## 参与贡献 + +我们非常欢迎你的贡献,你可以通过以下方式和我们一起共建 :smiley: +- 在你的公司或个人项目中使用 AntD Admin。 +- 通过 [Issue](http://github.com/zuiidea/antd-admin/issues) 报告 bug 或进行咨询。 +- 提交 [Pull Request](http://github.com/zuiidea/antd-admin/pulls) 改进代码。 + +> 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。 \ No newline at end of file diff --git a/docs/zh-cn/_sidebar.md b/docs/zh-cn/_sidebar.md new file mode 100644 index 0000000..68dc92e --- /dev/null +++ b/docs/zh-cn/_sidebar.md @@ -0,0 +1,11 @@ +- 入门 + - [快速上手](zh-cn/getting-started.md) +- 定制化 + - [配置项](zh-cn/configuration.md) + - [接口配置](zh-cn/API-configuration.md) + - [国际化](zh-cn/i18n.md) + - [布局](zh-cn/layout.md) + - [http 请求](zh-cn/request.md) +- 指南 + - [部署](zh-cn/deploy.md) +- [更新日志](zh-cn/change-log.md) diff --git a/docs/zh-cn/change-log.md b/docs/zh-cn/change-log.md new file mode 100644 index 0000000..54b0ec6 --- /dev/null +++ b/docs/zh-cn/change-log.md @@ -0,0 +1,52 @@ +## 5.0.0 + +#### 优化 + +- 尽量使用修饰器,简化代码编写,提高代码可读性。 + +- API 配置化,简化获取数据方式。 + +- `utils` 内文件拆分,各司其职。 + +- 简化`utils/request`文件,不做特殊处理。 + +#### 规范 + +- 函数添加描述、参数、返回值等注释,含糊不清的代码增加注释,规范参考 [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html#appendices-jsdoc-tag-reference)。 + +- 语义化版本号,规范参加 [语义化版本 2.0.0](https://semver.org/lang/zh-CN/)。 + +- 静态代码检查,统一代码风格,代码提交前将会使用 `prettier`、`stylelint`、`eslint` 规范代码。 + +- Git 提交信息规范化,[git-commit-emoji-cn](https://github.com/liuchengxu/git-commit-emoji-cn)。 + +- 基于 `Umi` 的约定式路由,无需再写路由配置文件。 + +- 使用 `React 16` 新特性,如 `Fragment`、`Context`、 `PureComponent`等。 + +#### 功能 + +- 支持国际化,源码中抽离翻译字段,按需加载语言包,自动在线翻译。 + +- 支持按需引入 `lodash` 函数。 + +- 支持多布局,可根据规则规定哪些路由使用哪种布局。 + +- 支持 Antd Admin 在 Travis 上自动编译和部署。 + +- 使用 `Docsify` 生成文档网站。 + + +#### 样式 + +- 新增 Antd Admin 独立 Logo。 + +- 重写整体布局组件,优化菜单、面包屑导航自动高亮,菜单自动展开等逻辑。 + +- 移动端菜单更改为抽屉式。 + +#### 其他 + +- 废弃 `IconFont`、 `Search`、`DataTable`等组件,因为在 `Antd` 中有很好的支持和可替代的。 + + diff --git a/docs/zh-cn/configuration.md b/docs/zh-cn/configuration.md new file mode 100644 index 0000000..70f517f --- /dev/null +++ b/docs/zh-cn/configuration.md @@ -0,0 +1,102 @@ +# 配置项 + +你可以在 `/src/utils/config.js` 里做一些自定义配置: + +## siteName + +- 类型: `String` + + 配置站点名称,应用到登录框,侧边栏顶部的标题文字显示。 + +## copyright + +- 类型: `String` + + 配置版权声明,应用到登录页、`Primay`布局底部。 + +## logoPath + +- 类型: `String` + + 配置站点 Logo,应用到登录框,侧边栏顶部的 Logo 显示。 + +## apiPrefix + +- 类型: `String` + + 配置项目中接口的前缀,接口相关文档可查看 [接口配置](API-configuration.md) + +## fixedHeader + +- 类型: `String` + + 在`Primary`布局下,页面滚动时是否固定顶部。 + +## layouts + +- 类型: `Array` + + 配置哪些路由使用哪种布局,未指定路由使用默认布局 `Public`,项目中目前有 `Primary` 和 `Public` 两种布局, + 默认配置如下: + + ```javascript + layouts: [ + { + name: 'primary', + include: [/.*/], + exclude: [/(\/(en|zh))*\/login/], + }, + ], + ``` + + 每种布局的对象属性如下: + + - `name` - 布局的名称; + + - `include` - 指定使用该布局的路由规则列表,规则可为正则表达式或者字符串; + + - `exclude` - 指定不使用该布局的路由规则列表,规则可为正则表达式或者字符串。 + + > 注意:`exclude` 优先级高于 `include`,前面的布局优先级高于后面的布局。开发过程中可能需要结合`src/layouts`目录下的布局使用,具体方法可查看 [使用布局](./layout.md)。 + +## i18n + +- 类型: `Object` + + 配置国际化,默认配置如下: + + ```javascript + i18n: { + languages: [ + { + key: 'en', + title: 'English', + flag: '/america.svg', + }, + { + key: 'zh', + title: '中文', + flag: '/china.svg', + }, + ], + defaultLanguage: 'en', + } + ``` + + ### i18n.languages + + - 类型: `Array` + + 指定应用支持哪些语言,每种语言的对象属性如下: + + - `key` - 语言的`key`,应用到页面 url 上以区分语言,也对应 `src/locales` 目录下的语言包文件夹名; + + - `title` - 语言名称,在登录页底部、`Primay` 布局顶部语言切换显示; + + - `flag` - 语言的国旗图标的路径,在 `Primay` 布局顶部语言切换显示。 + + ### i18n.defaultLanguage + + - 类型: `String` + + 配置默认语言。 diff --git a/docs/zh-cn/deploy.md b/docs/zh-cn/deploy.md new file mode 100644 index 0000000..cdbac06 --- /dev/null +++ b/docs/zh-cn/deploy.md @@ -0,0 +1,114 @@ +# 部署 + +完成开发并且在开发环境验证之后,就需要部署给我们的用户了。 + +![i18n](../_media/term_build.svg) + +## 构建 + +先执行下面的命令, + +```bash +npm run build +``` + +几秒后,输出应该如下: + +```bash +> antd-admin@5.0.0-beta build /Users/zuiidea/web/antd-admin +> umi build + +[21:13:17] webpack compiled in 43s 868ms + DONE Compiled successfully in 43877ms 21:13:17 + +File sizes after gzip: + + 1.3 MB dist/vendors.async.js + 308.21 KB dist/umi.js + 45.49 KB dist/vendors.chunk.css + 36.08 KB dist/p__chart__highCharts__index.async.js + 33.53 KB dist/p__user__index.async.js + 22.36 KB dist/p__chart__ECharts__index.async.js + 4.21 KB dist/p__dashboard__index.async.js + 4.06 KB dist/umi.css + ... +``` + +`build` 命令会打包所有的资源,包含 JavaScript, CSS, web fonts, images, html 等。你可以在 `dist/` 目录下找到这些文件。 + +> 如果有使用 HashHistory 、 部署 html 到非根目录、静态化等需求,请查看[Umi 部署](https://umijs.org/zh/guide/deploy.html)。 + +## 本地验证 + + +发布之前,可以通过 `serve` 做本地验证, + +``` +$ yarn global add serve +$ serve ./dist + +Serving! + +- Local: http://localhost:5000 +- On Your Network: http://{Your IP}:5000 + +Copied local address to clipboard! + +``` + +访问 [http://localhost:5000](http://localhost:5000),正常情况下法应该是和 `npm start` 一致的(接口可能无法获取到正确数据)。 + + +## 部署 + +接下来,我们可以把静态文件上传到服务器,如果使用 Nginx 作为 Web server,你可以在 `ngnix.conf` 中这样配置: + +``` +server + { + listen 80; + # 指定可访问的域名 + server_name antd-admin.zuiidea.com; + # 编译后的文件存放的目录 + root /home/www/antd-admin/dist; + + # 代理服务端接口,避免跨域 + location /api { + proxy_pass http://localhost:7000/api; + } + + # 因为前端使用了BrowserHistory,所以将路由 fallback 到 index.html + location / { + index index.html; + try_files $uri $uri/ /index.html; + } + } +``` + +重启 Web server,访问 [http://antd-admin.zuiidea.com](http://antd-admin.zuiidea.com) ,你将看到正确的页面。 + +```bash +nginx -s reload +``` + +类似的,如果你使用 Caddy 作为 Web server,你可以在 `Caddyfile` 中这样配置: + +``` +antd-admin.zuiidea.com { + gzip + root /home/www/antd-admin/dist + proxy /api http://localhost:7000 + + rewrite { + if {path} not_match ^/api + to {path} {path}/ / + } +} + + +antd-admin.zuiidea.com/public { + gzip + root /home/www/antd-admin/dist/static/public +} + +``` diff --git a/docs/zh-cn/faq.md b/docs/zh-cn/faq.md new file mode 100644 index 0000000..bf5f1bd --- /dev/null +++ b/docs/zh-cn/faq.md @@ -0,0 +1,7 @@ +# 问题集锦 + +## 新建页面 + + 1. 直接从/src/pages复制一个page (会自动创建路由[umi](https://umijs.org/zh/guide/router.html#%E7%BA%A6%E5%AE%9A%E5%BC%8F%E8%B7%AF%E7%94%B1)) + 2. 修改 namespace/pathToRegexp 在 model.js + 3. 修改 mock中route.js增加一条route \ No newline at end of file diff --git a/docs/zh-cn/getting-started.md b/docs/zh-cn/getting-started.md new file mode 100644 index 0000000..b9d1183 --- /dev/null +++ b/docs/zh-cn/getting-started.md @@ -0,0 +1,73 @@ +# 快速上手 + +> 在开始之前,推荐先学习 [React](http://facebook.github.io/react/) 、 [ES2015+](http://es6.ruanyifeng.com/) 、 [Antd Design](https://ant.design/docs/react/introduce-cn) , 了解 [UmiJS](https://umijs.org/) 、[Dva](http://github.com/dvajs/dva) ,并正确安装和配置了 [Node.js](https://nodejs.org/) v8 或以上 、[Git](https://git-scm.com/)。提前了解和学习这些知识会非常有帮助。 + +## 安装 + +```bash +git clone https://github.com/zuiidea/antd-admin.git my-project +cd my-project +``` + +## 目录结构 + +应用的目录结构如下 + +```bash +├── dist/ # 默认build输出目录 +├── mock/ # Mock文件目录 +├── public/ # 静态资源文件目录 +├── src/ # 源码目录 +│ ├── components/ # 组件目录 +│ ├── e2e/ # e2e目录 +│ ├── layouts/ # 布局目录 +│ ├── locales/ # 国际化文件目录 +│ ├── models/ # 数据模型目录 +│ ├── pages/ # 页面组件目录 +│ ├── services/ # 数据接口目录 +│ │ ├── api.js # 接口配置 +│ │ └── index.js # 接口输出 +│ ├── themes/ # 项目样式目录 +│ │ ├── default.less # 样式变量 +│ │ ├── index.less # 全局样式 +│ │ ├── mixin.less # 样式函数 +│ │ └── vars.less # 样式变量及函数 +│ ├── utils/ # 工具函数目录 +│ │ ├── config.js # 项目配置 +│ │ ├── constant.js # 静态常量 +│ │ ├── index.js # 工具函数 +│ │ ├── request.js # 异步请求函数(axios) +│ │ └── theme.js # 项目需要在js中使用到样式变量 +├── .editorconfig # 编辑器配置 +├── .env # 环境变量 +├── .eslintrc # ESlint配置 +├── .gitignore # Git忽略文件配置 +├── .prettierignore # Prettier忽略文件配置 +├── .prettierrc # Prettier配置 +├── .stylelintrc.json # Stylelint配置 +├── .travis.yml # Travis配置 +└── .umirc.js # Umi配置 +└── package.json # 项目信息 +``` + +## 本地开发 + +1. 进入目录安装依赖,国内用户推荐使用 [cnpm](https://cnpmjs.org) 进行加速 + +```bash +yarn install +``` + +或者 + +```bash +npm install +``` + +2. 启动本地服务器 + +```bash +npm run start +``` + +3. 启动完成后打开浏览器访问 [http://localhost:7000](http://localhost:7000),如果需要更改启动端口,可在 `.env` 文件中配置。 diff --git a/docs/zh-cn/i18n.md b/docs/zh-cn/i18n.md new file mode 100644 index 0000000..33244d6 --- /dev/null +++ b/docs/zh-cn/i18n.md @@ -0,0 +1,75 @@ +# 国际化 + +## 新增应用语言 + +以新增日语为例。 + +![i18n](../_media/term_i18n.svg) + +1. 添加语言包本地文件,`ja` 为日语的语言代码,支持翻译的语言列表参考 [有道智云](http://ai.youdao.com/docs/doc-trans-api.s#p05),运行下面命令后会生成 `src/locales/ja/messages.json` 文件。 + + ```bash + npm run add-locale ja + ``` + +2. 提取代码中需要翻译的字段,即 `message`、`` intl.formatMessage({ id: 'message `` 中 `message` 字段,运行下面命令后 `src/locales/ja/messages.json' }) 将会出现提取后的字段配置。 + + ```bash + npm run extract + ``` + + 你将看到如下信息: + + ```bash + Catalog statistics: + ┌─────────────┬─────────────┬─────────┐ + │ Language │ Total count │ Missing │ + ├─────────────┼─────────────┼─────────┤ + │ en (source) │ 52 │ - │ + │ ja │ 52 │ 52 │ + │ zh │ 52 │ 0 │ + └─────────────┴─────────────┴─────────┘ + ``` + +3. 与此同时,我们在 `src/utils/config.js` 新增相关配置。 + + ```javascript + { + ... + i18n: { + languages: [ + ... + { + key:'ja', + title: '日本語', + flag: '/japanese.svg', + }, + ], + }, + } + ``` + + >  路由相关效果,配置后 `npm run start` 重启后生效。 + +4. 使用内置的命令进行自动翻译,在 `src/locales/ja/messages.json` 中将会看到翻译后的配置。 + + ```bash + npm run trans:only + ``` + + 你将看到如下信息: + + ```bash + start: en -> ja + ... + youdao: en -> ja: Unpublished -> 未発表 + youdao: en -> ja: Update -> 更新 + youdao: en -> ja: Update User -> ユーザーの更新 + youdao: en -> ja: Username -> 名 + ... + All translations have been completed. + ``` + + > `npm run trans` 将会依次执行 `npm run extract` 和 `npm run trans:only` + +5. 最后,可以在 `src/locales/ja/messages.json` 中对翻译不准确的的字段进行调整。启动开发模式 `npm run start`,打开 [http://localhost:7000/ja/login](http://localhost:7000/ja/login),你将看到日语版本的应用。 diff --git a/docs/zh-cn/layout.md b/docs/zh-cn/layout.md new file mode 100644 index 0000000..f3a39e7 --- /dev/null +++ b/docs/zh-cn/layout.md @@ -0,0 +1,60 @@ +# 布局 + +## 新增布局 + +以新增名为 `secondary` 的布局为例,使以 `secondary` 开头的路由都使用该布局。 + +1. 在 `src/utils/config.js` 新增相关配置,参数详细请查看 [layouts](/zh-cn/configuration?id=layouts)。 + + ```javascript + layouts: [ + { + name: 'primary', + include: [/.*/], + exclude: [/(\/(en|zh))*\/login/, /(\/(en|zh))*\/secondary\/(.*)/], + }, + { + name: 'secondary', + include: [/(\/(en|zh))*\/secondary\/(.*)/], + }, + ], + ``` + +2. 在`src/layouts/BaseLayout.js` 文件中新增 `secondary` 布局组件。 + + ```javascript + import SecondaryLayout from './SecondaryLayout' + + const LayoutMap = { + primary: PrimaryLayout, + public: PublicLayout, + secondary: SecondaryLayout, + } + ``` + +3. 在`src/layouts/` 目录中新增 `SecondaryLayout.js` 文件。 + + ```javascript + import React from 'react' + + export default ({ children }) => { + return ( +
+

Secondary

+ {children} +
+ ) + } + ``` + +4. 在`src/pages/` 目录中新增 `secondary/index.js` 文件。 + + ```javascript + import React from 'react' + + export default ({ children }) => { + return
Secondary page Content
+ } + ``` + +5. 最后,启动开发模式 `npm run start`,打开 [http://localhost:7000/secondary/](http://localhost:7000/secondary/),你将看到 `secondary` 布局的页面。 diff --git a/docs/zh-cn/request.md b/docs/zh-cn/request.md new file mode 100644 index 0000000..a87022c --- /dev/null +++ b/docs/zh-cn/request.md @@ -0,0 +1,24 @@ +# HTTP请求 + +本项目使用了axios提供http请求服务,文件在src/utils/request.js + +## 自定义Header + +为了提供鉴权、修改cookie等服务,可以手动修改Header + +``` +axios.defaults.headers.common['Authorization'] = 'token' +``` + +或者 + +``` +// 添加请求拦截器 +axios.interceptors.request.use(function (config) { + // 在发送请求之前做些什么 + config.headers.token = window.localStorage.getItem('token'); + return config; +}, function (error) { + return Promise.reject(error); +}); +``` \ No newline at end of file diff --git a/docs/zh-cn/router.md b/docs/zh-cn/router.md new file mode 100644 index 0000000..f511c2e --- /dev/null +++ b/docs/zh-cn/router.md @@ -0,0 +1,5 @@ +# 路由 + +本项目中采用约定式路由 + +参考[umi 路由](https://umijs.org/zh/guide/router.html) diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..c52ac83 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + testURL: 'http://localhost:8000', +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..3316983 --- /dev/null +++ b/manifest.json @@ -0,0 +1,36 @@ +{ + "name": "Antd-Admin", + "start_url": ".", + "display": "standalone", + "background_color": "#fff", + "description": "A front-end solution for enterprise applications built upon Ant Design and UmiJS", + "icons": [{ + "src": "logo/logo@96.png", + "sizes": "72x72" + }, + { + "src": "logo/logo@128.png", + "sizes": "128x128" + }, + { + "src": "logo/logo@144.png", + "sizes": "144x144" + }, + { + "src": "logo/logo@152.png", + "sizes": "152x152" + }, + { + "src": "logo/logo@192.png", + "sizes": "192x192" + }, + { + "src": "logo/logo@384.png", + "sizes": "384x384" + }, + { + "src": "logo/logo@512.png", + "sizes": "512x512" + } + ] +} diff --git a/mock/_utils.js b/mock/_utils.js new file mode 100644 index 0000000..2229c12 --- /dev/null +++ b/mock/_utils.js @@ -0,0 +1,59 @@ +/** + * Query objects that specify keys and values in an array where all values are objects. + * @param {array} array An array where all values are objects, like [{key:1},{key:2}]. + * @param {string} key The key of the object that needs to be queried. + * @param {string} value The value of the object that needs to be queried. + * @return {object|undefined} Return frist object when query success. + */ +export function queryArray(array, key, value) { + if (!Array.isArray(array)) { + return + } + return array.filter(_ => _[key] === value) +} + +export function randomNumber(min, max) { + return Math.floor(Math.random() * (max - min) + min) +} + +export function randomAvatar() { + const avatarList = [ + 'photo-1549492864-2ec7d66ffb04.jpeg', + 'photo-1480535339474-e083439a320d.jpeg', + 'photo-1523419409543-a5e549c1faa8.jpeg', + 'photo-1519648023493-d82b5f8d7b8a.jpeg', + 'photo-1523307730650-594bc63f9d67.jpeg', + 'photo-1522962506050-a2f0267e4895.jpeg', + 'photo-1489779162738-f81aed9b0a25.jpeg', + 'photo-1534308143481-c55f00be8bd7.jpeg', + 'photo-1519336555923-59661f41bb45.jpeg', + 'photo-1551438632-e8c7d9a5d1b7.jpeg', + 'photo-1525879000488-bff3b1c387cf.jpeg', + 'photo-1487412720507-e7ab37603c6f.jpeg', + 'photo-1510227272981-87123e259b17.jpeg' + ] + return `//image.zuiidea.com/${avatarList[randomNumber(0, avatarList.length - 1)]}?imageView2/1/w/200/h/200/format/webp/q/75|imageslim` +} + +export const Constant = { + ApiPrefix: '/api/v1', + NotFound: { + message: 'Not Found', + documentation_url: '', + }, + Color: { + green: '#64ea91', + blue: '#8fc9fb', + purple: '#d897eb', + red: '#f69899', + yellow: '#f8c82e', + peach: '#f797d6', + borderBase: '#e5e5e5', + borderSplit: '#f4f4f4', + grass: '#d6fbb5', + sky: '#c1e0fc', + }, +} + +export Mock from 'mockjs' +export qs from 'qs' diff --git a/mock/dashboard.js b/mock/dashboard.js new file mode 100644 index 0000000..8758594 --- /dev/null +++ b/mock/dashboard.js @@ -0,0 +1,142 @@ +import { Mock, Constant } from './_utils' + +const { ApiPrefix, Color } = Constant + +const Dashboard = Mock.mock({ + 'sales|8': [ + { + 'name|+1': 2008, + 'Clothes|200-500': 1, + 'Food|180-400': 1, + 'Electronics|300-550': 1, + }, + ], + cpu: { + 'usage|50-600': 1, + space: 825, + 'cpu|40-90': 1, + 'data|20': [ + { + 'cpu|20-80': 1, + }, + ], + }, + browser: [ + { + name: 'Google Chrome', + percent: 43.3, + status: 1, + }, + { + name: 'Mozilla Firefox', + percent: 33.4, + status: 2, + }, + { + name: 'Apple Safari', + percent: 34.6, + status: 3, + }, + { + name: 'Internet Explorer', + percent: 12.3, + status: 4, + }, + { + name: 'Opera Mini', + percent: 3.3, + status: 1, + }, + { + name: 'Chromium', + percent: 2.53, + status: 1, + }, + ], + user: { + name: 'github', + sales: 3241, + sold: 3556, + }, + 'completed|12': [ + { + 'name|+1': 2008, + 'Task complete|200-1000': 1, + 'Cards Complete|200-1000': 1, + }, + ], + 'comments|5': [ + { + name: '@last', + 'status|1-3': 1, + content: '@sentence', + avatar() { + return Mock.Random.image( + '48x48', + Mock.Random.color(), + '#757575', + 'png', + this.name.substr(0, 1) + ) + }, + date() { + return `2016-${Mock.Random.date('MM-dd')} ${Mock.Random.time( + 'HH:mm:ss' + )}` + }, + }, + ], + 'recentSales|36': [ + { + 'id|+1': 1, + name: '@last', + 'status|1-4': 1, + date() { + return `${Mock.Random.integer(2015, 2016)}-${Mock.Random.date( + 'MM-dd' + )} ${Mock.Random.time('HH:mm:ss')}` + }, + 'price|10-200.1-2': 1, + }, + ], + quote: { + name: 'Joho Doe', + title: 'Graphic Designer', + content: + "I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.", + avatar: + '//cdn.antd-admin.zuiidea.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236', + }, + numbers: [ + { + icon: 'pay-circle-o', + color: Color.green, + title: 'Online Review', + number: 2781, + }, + { + icon: 'team', + color: Color.blue, + title: 'New Customers', + number: 3241, + }, + { + icon: 'message', + color: Color.purple, + title: 'Active Projects', + number: 253, + }, + { + icon: 'shopping-cart', + color: Color.red, + title: 'Referrals', + number: 4324, + }, + ], +}) + +module.exports = { + [`GET ${ApiPrefix}/dashboard`](req, res) { + res.json(Dashboard) + }, +} diff --git a/mock/post.js b/mock/post.js new file mode 100644 index 0000000..e8e0d7c --- /dev/null +++ b/mock/post.js @@ -0,0 +1,67 @@ +import { Mock, Constant } from './_utils' + +const { ApiPrefix } = Constant + +let postId = 0 +const database = Mock.mock({ + 'data|100': [ + { + id() { + postId += 1 + return postId + 10000 + }, + 'status|1-2': 1, + title: '@title', + author: '@last', + categories: '@word', + tags: '@word', + 'views|10-200': 1, + 'comments|10-200': 1, + visibility: () => { + return Mock.mock( + '@pick(["Public",' + '"Password protected", ' + '"Private"])' + ) + }, + date: '@dateTime', + image() { + return Mock.Random.image( + '100x100', + Mock.Random.color(), + '#757575', + 'png', + this.author.substr(0, 1) + ) + }, + }, + ], +}).data + +module.exports = { + [`GET ${ApiPrefix}/posts`](req, res) { + const { query } = req + let { pageSize, page, ...other } = query + pageSize = pageSize || 10 + page = page || 1 + + let newData = database + for (let key in other) { + if ({}.hasOwnProperty.call(other, key)) { + newData = newData.filter(item => { + if ({}.hasOwnProperty.call(item, key)) { + return ( + String(item[key]) + .trim() + .indexOf(decodeURI(other[key]).trim()) > -1 + ) + } + return true + }) + } + } + + res.status(200).json({ + data: newData.slice((page - 1) * pageSize, page * pageSize), + total: newData.length, + }) + }, +} diff --git a/mock/route.js b/mock/route.js new file mode 100644 index 0000000..fb0456b --- /dev/null +++ b/mock/route.js @@ -0,0 +1,155 @@ +import { Constant } from './_utils' +const { ApiPrefix } = Constant + +const database = [ + { + id: '1', + icon: 'dashboard', + name: 'Dashboard', + zh: { + name: '仪表盘' + }, + 'pt-br': { + name: 'Dashboard' + }, + route: '/dashboard', + }, + { + id: '2', + breadcrumbParentId: '1', + name: 'Users', + zh: { + name: '用户管理' + }, + 'pt-br': { + name: 'Usuário' + }, + icon: 'user', + route: '/user', + }, + { + id: '7', + breadcrumbParentId: '1', + name: 'Posts', + zh: { + name: '用户管理' + }, + 'pt-br': { + name: 'Posts' + }, + icon: 'shopping-cart', + route: '/post', + }, + { + id: '21', + menuParentId: '-1', + breadcrumbParentId: '2', + name: 'User Detail', + zh: { + name: '用户详情' + }, + 'pt-br': { + name: 'Detalhes do usuário' + }, + route: '/user/:id', + }, + { + id: '3', + breadcrumbParentId: '1', + name: 'Request', + zh: { + name: 'Request' + }, + 'pt-br': { + name: 'Requisição' + }, + icon: 'api', + route: '/request', + }, + { + id: '4', + breadcrumbParentId: '1', + name: 'UI Element', + zh: { + name: 'UI组件' + }, + 'pt-br': { + name: 'Elementos UI' + }, + icon: 'camera-o', + }, + { + id: '45', + breadcrumbParentId: '4', + menuParentId: '4', + name: 'Editor', + zh: { + name: 'Editor' + }, + 'pt-br': { + name: 'Editor' + }, + icon: 'edit', + route: '/editor', + }, + { + id: '5', + breadcrumbParentId: '1', + name: 'Charts', + zh: { + name: 'Charts' + }, + 'pt-br': { + name: 'Graficos' + }, + icon: 'code-o', + }, + { + id: '51', + breadcrumbParentId: '5', + menuParentId: '5', + name: 'ECharts', + zh: { + name: 'ECharts' + }, + 'pt-br': { + name: 'ECharts' + }, + icon: 'line-chart', + route: '/chart/ECharts', + }, + { + id: '52', + breadcrumbParentId: '5', + menuParentId: '5', + name: 'HighCharts', + zh: { + name: 'HighCharts' + }, + 'pt-br': { + name: 'HighCharts' + }, + icon: 'bar-chart', + route: '/chart/highCharts', + }, + { + id: '53', + breadcrumbParentId: '5', + menuParentId: '5', + name: 'Rechartst', + zh: { + name: 'Rechartst' + }, + 'pt-br': { + name: 'Rechartst' + }, + icon: 'area-chart', + route: '/chart/Recharts', + }, +] + +module.exports = { + [`GET ${ApiPrefix}/routes`](req, res) { + res.status(200).json(database) + }, +} diff --git a/mock/user.js b/mock/user.js new file mode 100644 index 0000000..4ffd4d3 --- /dev/null +++ b/mock/user.js @@ -0,0 +1,250 @@ +import { Mock, Constant, randomAvatar } from './_utils' +import qs from 'qs' + +const { ApiPrefix } = Constant + +let usersListData = Mock.mock({ + 'data|80-100': [ + { + id: '@id', + name: '@name', + nickName: '@last', + phone: /^1[34578]\d{9}$/, + 'age|11-99': 1, + address: '@county(true)', + isMale: '@boolean', + email: '@email', + createTime: '@datetime', + avatar() { + return randomAvatar() + }, + }, + ], +}) + +let database = usersListData.data + +const EnumRoleType = { + ADMIN: 'admin', + DEFAULT: 'guest', + DEVELOPER: 'developer', +} + +const userPermission = { + DEFAULT: { + visit: ['1', '2', '21', '7', '5', '51', '52', '53'], + role: EnumRoleType.DEFAULT, + }, + ADMIN: { + role: EnumRoleType.ADMIN, + }, + DEVELOPER: { + role: EnumRoleType.DEVELOPER, + }, +} + +const adminUsers = [ + { + id: 0, + username: 'admin', + password: 'admin', + permissions: userPermission.ADMIN, + avatar: randomAvatar(), + }, + { + id: 1, + username: 'guest', + password: 'guest', + permissions: userPermission.DEFAULT, + avatar: randomAvatar(), + }, + { + id: 2, + username: '吴彦祖', + password: '123456', + permissions: userPermission.DEVELOPER, + avatar: randomAvatar(), + }, +] + +const queryArray = (array, key, keyAlias = 'key') => { + if (!(array instanceof Array)) { + return null + } + let data + + for (let item of array) { + if (item[keyAlias] === key) { + data = item + break + } + } + + if (data) { + return data + } + return null +} + +const NOTFOUND = { + message: 'Not Found', + documentation_url: 'http://localhost:8000/request', +} + +module.exports = { + [`POST ${ApiPrefix}/user/login`](req, res) { + const { username, password } = req.body + const user = adminUsers.filter(item => item.username === username) + + if (user.length > 0 && user[0].password === password) { + const now = new Date() + now.setDate(now.getDate() + 1) + res.cookie( + 'token', + JSON.stringify({ id: user[0].id, deadline: now.getTime() }), + { + maxAge: 900000, + httpOnly: true, + } + ) + res.json({ success: true, message: 'Ok' }) + } else { + res.status(400).end() + } + }, + + [`GET ${ApiPrefix}/user/logout`](req, res) { + res.clearCookie('token') + res.status(200).end() + }, + + [`GET ${ApiPrefix}/user`](req, res) { + const cookie = req.headers.cookie || '' + const cookies = qs.parse(cookie.replace(/\s/g, ''), { delimiter: ';' }) + const response = {} + let user = {} + if (!cookies.token) { + res.status(200).send({ message: 'Not Login' }) + return + } + const token = JSON.parse(cookies.token) + if (token) { + response.success = token.deadline > new Date().getTime() + } + if (response.success) { + const userItem = adminUsers.find(_ => _.id === token.id) + if (userItem) { + const { password, ...other } = userItem + user = other + } + } + response.user = user + res.json(response) + }, + + [`GET ${ApiPrefix}/users`](req, res) { + const { query } = req + let { pageSize, page, ...other } = query + pageSize = pageSize || 10 + page = page || 1 + + let newData = database + for (let key in other) { + if ({}.hasOwnProperty.call(other, key)) { + newData = newData.filter(item => { + if ({}.hasOwnProperty.call(item, key)) { + if (key === 'address') { + return other[key].every(iitem => item[key].indexOf(iitem) > -1) + } else if (key === 'createTime') { + const start = new Date(other[key][0]).getTime() + const end = new Date(other[key][1]).getTime() + const now = new Date(item[key]).getTime() + + if (start && end) { + return now >= start && now <= end + } + return true + } + return ( + String(item[key]) + .trim() + .indexOf(decodeURI(other[key]).trim()) > -1 + ) + } + return true + }) + } + } + + res.status(200).json({ + data: newData.slice((page - 1) * pageSize, page * pageSize), + total: newData.length, + }) + }, + + [`POST ${ApiPrefix}/users/delete`](req, res) { + const { ids=[] } = req.body + database = database.filter(item => !ids.some(_ => _ === item.id)) + res.status(204).end() + }, + + [`POST ${ApiPrefix}/user`](req, res) { + const newData = req.body + newData.createTime = Mock.mock('@now') + newData.avatar = + newData.avatar || + Mock.Random.image( + '100x100', + Mock.Random.color(), + '#757575', + 'png', + newData.nickName.substr(0, 1) + ) + newData.id = Mock.mock('@id') + + database.unshift(newData) + + res.status(200).end() + }, + + [`GET ${ApiPrefix}/user/:id`](req, res) { + const { id } = req.params + const data = queryArray(database, id, 'id') + if (data) { + res.status(200).json(data) + } else { + res.status(200).json(NOTFOUND) + } + }, + + [`DELETE ${ApiPrefix}/user/:id`](req, res) { + const { id } = req.params + const data = queryArray(database, id, 'id') + if (data) { + database = database.filter(item => item.id !== id) + res.status(204).end() + } else { + res.status(200).json(NOTFOUND) + } + }, + + [`PATCH ${ApiPrefix}/user/:id`](req, res) { + const { id } = req.params + const editItem = req.body + let isExist = false + + database = database.map(item => { + if (item.id === id) { + isExist = true + return Object.assign({}, item, editItem) + } + return item + }) + + if (isExist) { + res.status(201).end() + } else { + res.status(200).json(NOTFOUND) + } + }, +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4b1c72b --- /dev/null +++ b/package.json @@ -0,0 +1,129 @@ +{ + "name": "antd-admin", + "version": "5.3.0", + "license": "MIT", + "description": "An admin dashboard application demo built upon Ant Design and UmiJS", + "dependencies": { + "@ant-design/icons": "^4.6.2", + "@lingui/react": "^3.8.0", + "antd": "^4.0.0", + "axios": "^0.21.0", + "classnames": "^2.2.6", + "d3-shape": "^2.1.0", + "draft-js": "^0.11.7", + "draftjs-to-html": "^0.9.0", + "draftjs-to-markdown": "^0.6.0", + "dva-model-extend": "^0.1.2", + "echarts": "^5.0.0", + "echarts-for-react": "^3.0.0", + "echarts-gl": "^2.0.2", + "echarts-liquidfill": "^3.0.0", + "enquire-js": "^0.2.1", + "highcharts-exporting": "^0.1.7", + "highcharts-more": "^0.1.7", + "json-format": "^1.0.1", + "lodash": "^4.17.11", + "md5": "^2.2.1", + "nprogress": "^0.2.0", + "path-to-regexp": "^6.1.0", + "prop-types": "^15.7.0", + "qs": "^6.10.0", + "react-adsense": "^0.1.0", + "react-countup": "^4.2.0", + "react-draft-wysiwyg": "^1.13.0", + "react-helmet": "^6.0.0", + "react-highcharts": "^16.1.0", + "react-perfect-scrollbar": "^1.5.0", + "recharts": "^2.0.0", + "store": "^2.0.0" + }, + "devDependencies": { + "@babel/preset-react": "^7.12.13", + "@lingui/cli": "^3.8.0", + "@lingui/macro": "^3.8.0", + "@umijs/preset-react": "^1.8.0", + "babel-eslint": "^10.0.0", + "babel-plugin-dev-expression": "^0.2.0", + "babel-plugin-import": "^1.13.0", + "babel-plugin-macros": "^3.0.0", + "babel-plugin-module-resolver": "^4.0.0", + "cross-env": "^7.0.0", + "eslint": "^7.0.0", + "eslint-config-react-app": "^6.0.0", + "eslint-plugin-flowtype": "^5.1.0", + "eslint-plugin-import": "^2.18.0", + "eslint-plugin-jsx-a11y": "^6.2.1", + "eslint-plugin-react": "^7.23.0", + "eslint-plugin-react-hooks": "^4.0.0", + "husky": "^4.2.0", + "less-vars-to-js": "^1.3.0", + "lint-staged": "^10.0.0", + "mockjs": "^1.1.0", + "module": "^1.2.5", + "prettier": "^2.0.0", + "stylelint": "^13.2.0", + "stylelint-config-prettier": "^8.0.0", + "stylelint-config-standard": "^21.0.0", + "typescript": "^4.2.3", + "umi": "^3.4.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "lint-staged": { + "src/**/*.js": [ + "eslint --ext .js --fix", + "npm run prettier", + "git add" + ], + "**/*.less": [ + "stylelint --syntax less", + "npm run prettier", + "git add" + ] + }, + "lingui": { + "fallbackLocales": { + "default": "en" + }, + "sourceLocale": "en", + "locales": [ + "en", + "zh", + "pt-br" + ], + "catalogs": [ + { + "path": "src/locales/{locale}/messages", + "include": [ + "src/pages", + "src/layouts", + "src/components", + "src/layouts" + ] + } + ], + "format": "minimal", + "extractBabelOptions": { + "presets": [ + "@umijs/babel-preset-umi", + "@babel/preset-react" + ] + } + }, + "scripts": { + "analyze": "cross-env ANALYZE=1 umi build", + "build": "umi build", + "check:model": "umi dva list model", + "lint:js": "eslint --ext .js src", + "lint:style": "stylelint \"src/**/*.less\" --syntax less", + "start": "umi dev", + "test": "cross-env BABELRC=none umi test", + "prettier": "prettier --write 'src/**/*.{js,less}'", + "precommit": "lint-staged", + "add-locale": "lingui add-locale", + "extract": "lingui extract", + "trans": "lingui extract --clean && node ./scripts/translate.js", + "doc": "docsify serve docs" + } +} diff --git a/public/america.svg b/public/america.svg new file mode 100644 index 0000000..706cc00 --- /dev/null +++ b/public/america.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/china.svg b/public/china.svg new file mode 100644 index 0000000..709a1fe --- /dev/null +++ b/public/china.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ca2170ea0f4e0472c56924a402807e10ddf0220 GIT binary patch literal 67646 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 + + Created with Sketch. + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/logo/logo@128.png b/public/logo/logo@128.png new file mode 100755 index 0000000000000000000000000000000000000000..5e218d8c50d989908d1c1d57eb94857930215331 GIT binary patch literal 3184 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 JdS>aB`d_l#hME8X literal 0 HcmV?d00001 diff --git a/public/logo/logo@144.png b/public/logo/logo@144.png new file mode 100755 index 0000000000000000000000000000000000000000..347e0dfe245d7187f3961f5faadaf553ed942203 GIT binary patch literal 3604 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 literal 0 HcmV?d00001 diff --git a/public/logo/logo@192.png b/public/logo/logo@192.png new file mode 100755 index 0000000000000000000000000000000000000000..342ab1e9553dc1a890b73293d2e058d3bba4028a GIT binary patch literal 4785 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 literal 0 HcmV?d00001 diff --git a/public/logo/logo@72.png b/public/logo/logo@72.png new file mode 100755 index 0000000000000000000000000000000000000000..126e5efe62aff9bc28c5020187226c0fbe0b90f6 GIT binary patch literal 2138 zcmYjRdpwkB8y=-EVH^gT8Rs#Xp=eT~uav_uQ6|P=N2r;}DaQHCvQaZ4QjtbfW*u_a za;CJ2B!?)Z)v~`fW>1&ZW(B9uW``6yT_kEuCe&6eU?(2H4=lAA$(rIXAyfO-f zLc1NMGLZSG{8rkGjGVpBNhs8&kDkYUT#(eE7mRAa=muzIfo>^iq=LmDkbB|j+?;+b zXkP~HBGAYHwHUzgKo^1W0e=T{ihw)_`gege1eTLv@e;@*Ktc*fL9*9LEl!@A4};X! z4XH)G%8q`slXlRn25DF*p#!#G2h0V)3V`qc zq^HiP#e?}v*zpvMT0uPpu;n0&3?u#s28|%`W2r^M`nhPeC?NI#vLM3Es2TJs0UZV6 zJ&tHD$Z}%L$AI`qjz?;BOTeH?-p*_Q)RI7!6;0>@gS&tr5jliTK)`0tz@!5Ve*j`P zAX z9FW+bK-#Tm$B2&wqGLdo6uEYozMdV8;R7ZYG!j8I5@gvi`c;7c9x&$slLhNp(THkf z$1D)?Pr$4f#Pm}#Zn)T%CSh_ma$=D8QYLFXE?kxtC5?+jQuS1jU5J-CFk~KVsXq&H z6L!72qSsGWopC$=lOQXW2 zncOvJUkNu%mKG`HhNpX9KZqRnsze6e8>L84H$C)UL$t#D$h~_dR}&MNOveL6&Cd(- zGljg=IDe+EtDUum%9eGhcy)DodGR-qXzu;YPvc{wBg4akgMB@n9WBkxjg578g?DaU zFDbrKbh)rFFC`^8K8_O@;Opad*xJ}YAEPY(CstSFv5drDA3y%N_(3#3_ip0V=!+L4 zL%khM4fVA(w{I5n(o@ee=~O#AYcdY2x-BIrvKEC>%y6SR`Y`*KN_@u|UfR6f$tnMe zu8W17l%3ymwwiTv#8nwh32LIp1$zf^nJbTC**#?)FBif93({9dh@3CaZmIa5_V}GI(LOyYKfROK(vnAt7~*D6RF@SK^a*RWv<~k&OVxty ze=KruhaQRRp!_ZC!()R8q&c={Tk_J$Z#~@V{q3+pjQmmGPyPXPEIA}GZ|Zc2Rn%;! zr9ye1Kwa6jIK7ph5&cHVMg|c|UVr{{?_NM#h$laQ8S?t{$RG3EhM#2|Z|D7cOW0eg zT)J5c1GOFxqqv@%6{?Qq1^m)4bTA&@^q+z9w?71It#a9kJ2|MG?YPIJz^Zct%Xg0M zdW2Su*hCQzhfn&@MYU6xmnRh~kM=HVn$sxlXI|Z=OtSD~>zh+a2`Uk56?NOrbK;4t zRi$FyUZq=~Lk1b4aaDph=~#P<{8Ia#FH}>kzi6dz5o1L2=0Dgz@SLw0Q9V&Z?2yLJ5fDsGvRFWZnF-{ILGxy z^MO5u;%;&8!-Rt^CBc+21%829lAW_KVXCdI)Vj_@p^7G0Idy^j<-KE5GsS1KV=W2i zVPSBkevG1JgnDrgIb?`=i3(h!F35)W(?98h^?&|Fw)m|C8z9yj5v8%m;Z*Kg4bza4O zgu36d=8(*~rc*q?n3>4P9k_ouSR38*UFwVJfS#3d-gtg^L+JE6>6UN*y(vC;M`j6s=U)_m@r zQ(0;9V-r3Jxib=JMJ~iSs6gwt#-fG&68(Zn?J9oV4 zc2By@=a;G3Kz`m^!paq=t?I71nwvt6aN|qImA349Qu1{?XR0TYIg;J#iuZi~+J50R zDSdK4%;1*^EE1M~E7Tk2NnPI9_Exl+jCN`BGEy&|IP50u&sBLk#AZFm8ZWJjU%fk$ z;d-JcHh|5%*i%$_mYj5`k+L;pPnjtGx_eMN<#jVg0hh0TB&ng2!ofda^I2))ax;FX ztrIz)UAHjRGBWAVTe6>6Z~f$N_vy%VOxbI^aF>_O;N{_tvxSEHW144;mnuIvy6!sP z$}rkdk}o{2s$Fazi5kyZqd67@8<;pX?|9{2W*dX2`PF)>YCox;al?)8@oly6y;gHF xYNIr^u(8y`@a3w`GqQbWe5B|INCP$$?_PgU`NH;BL*%cCa&w_m?>n(_{tqC>NnQW| literal 0 HcmV?d00001 diff --git a/public/logo/logo@96.png b/public/logo/logo@96.png new file mode 100755 index 0000000000000000000000000000000000000000..de9a9fba69a2f4a547b6607c349edf746ef3486d GIT binary patch literal 2449 zcmYL~2{@E%8^@<3g^Xcr$-WH{(%4Ed*-f(L7{l9gE%;9aXG{L;8f6zZ-<2cUNwl+OT~4%j?U$N{AiFuVu4H$jv|!z6>r6Ik0x)NBUj5>PG& z%~lZ5D64oE5tDAf0`2RdkOgQeD5Qb*RnYGOTpyx}hRD!p0EE~#W`gOESQ1hl$)I}! zM9c(Xay(K_7#S%?2hj<-RXaCPT=cgzvOCq5VF^ zBmlRA!tf{oC7K@;zKVB3AoD{H^Y?`av+4Xp;fPwKcR^It8r~VnhFpk!t2_1zY~5vP zfai)`Q2hgp2E;9EUjwCLz%T%t4{}N3K*iHyK8R~bUkD|Y-vL3b*ClpP=cd>=VGbQ> zQ1`ajVr&7(XMq7*3{5^$?5x&RP$~uELBREc>Uq%nj~KoI2Xya%#$`Y!0JabW5s@0r zfIbSsOe#P4Frs<$1(2nJ@JI}wMCKm|LkKJ6g78@ER^)iJfqEkdQ{oKn1D_nBd=})h zVT~AU^cd7?KoA?fwm)Rel_ZF#toeq@r2v9Om_`*uN3Gd=iEXlWTO;_bI{N9eL690R zpvCZgLj~kWVQM@d3EZ{s)0c%Yq5VI$MN7!5X{mazkZ)E}a%16d34*krN4p zi;D{j^Ye3aU%!0$JU#h-{O#+pv5|rPJ|xFIHmj?-{`{HJ;=+PFCNnD~IVmB5PK}L; zp&SnOaj>#9QsOUt`Z)dW?-zHQiVHL8aj}6uCYTfbx$jXZ$#zedy#X=fUn+hk1ngBJ zXm^{Mq#XbMFnU!aB~!2CA$7|5_N&dm8mDBYQf9usIXE*k-0b*x-S`d4GB+y8;VITb zCkL1Y(<7vU4fy)Q?)%is< zSkKMP4bS-*(&a!y+|soszEqs3;ZIZVkg%`k=3rZn#N7Hemt^!He;9c`b(v0h8jnC5hK4{_+@|3 z^L)ZQk&D6M4{HhO=gb0qmU!#>27kY@v@<(^oH22RV%b7!_-bThFc`eJOr14eI8|Zh z8O1G?nfMy&KVR{*)eryFtn}r<{_hNL7L~EO4UHE^>RUAD|{wB$1&Y|-r+&+hBbCj((X40KdcQL)Jlv5~muws)7q&{JOzpYl=D zvYhI5Zcg5)rc|FC$z>DSd|knhTozAXKUtd@T8InkVHFg(r?!wD)M1j^)J7IIZ(WJw zZu(&2o-?EJwtzP-!Tzb`#t57|-D11|B zkso8dmEwC1g|flM^k1~tGHTRHDZZ@K5l_>VxT!sH7aTZ-oIb;v(blq;m7J4}cX81b z=so7OB+l8>=)&Y$`EF{LhsNhu?$MPt{^#Q|&dODE~Ym ztBpMVhEh5@+m<0(MH8wM-jx>o$hv|n{Vj#ZA8-8dq1^j(StF^D`f|NjS2)o|KY+zz z$u&k-nAzIy2|<;#F}(Qwj`KTzR;=8Q56bzG!~Msf_F;)vcI&UmZKEz+&8rlY@-+z# zqs84OxZ=7CzSb__2$ASzyRn60b=NRl`I~f^OQq*}(*mi%w(;BY&a9Q1t`VBFtF^O# z#0HbIt$#if^)8{U8+q{)rWq5nq}A6qn9&})G8+B zKcA;dC35*E%@y}-dsLUvg0 zw<^>gf^)C69iNtzXb-6FPT%%o%D^#crPLytK4qycT2;2L-f;EAJ$+8OFB@yOvolC? zhwa6b#4H(ajKe;)q3Y>dC+^)DNiZUAMZa;*-+s6L`;&t)TC4lpr48Qtb*GiQ_ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/translate.js b/scripts/translate.js new file mode 100644 index 0000000..b2d9444 --- /dev/null +++ b/scripts/translate.js @@ -0,0 +1,114 @@ +/** + * Youdao Translate, My private account is for testing purposes only. + * Please go to the official account to apply for an account. Thank you for your cooperation. + * APP ID:055c2d71f9a05214 + * Secret key:ZcpuQxQW3NkQeKVkqrXIKQYXH57g2KuN + */ + +/* eslint-disable */ +const md5 = require('md5') +const qs = require('qs') +const fs = require('fs') +const path = require('path') +const axios = require('axios') +const jsonFormat = require('json-format') +const { i18n } = require('../src/utils/config') +const { languages, defaultLanguage } = i18n + +const locales = {} + +languages.forEach(item => { + locales[item.key] = require(`../src/locales/${item.key}/messages.json`) +}) + +const youdao = ({ q, from, to }) => + new Promise((resolve, reject) => { + { + const appid = '055c2d71f9a05214' + const appse = 'ZcpuQxQW3NkQeKVkqrXIKQYXH57g2KuN' + const salt = Date.now() + + const sign = md5(appid + q + salt + appse) + const query = qs.stringify({ + q, + from, + to, + appKey: appid, + salt, + sign, + }) + + axios.get(`http://openapi.youdao.com/api?${query}`).then(({ data }) => { + if (data.query && data.translation[0]) { + resolve(data.translation[0]) + } else { + resolve(q) + } + }) + } + }) + +const transform = async ({ from, to, locales, outputPath }) => { + for (const key in locales[from]) { + if (locales[to][key]) { + console.log(`add to skip: ${key}`) + } else { + let res = key + let way = 'youdao' + if (key.indexOf('/') !== 0) { + const reg = '{([^{}]*)}' + const tasks = key + .match(new RegExp(`${reg}|((?<=(${reg}|^)).*?(?=(${reg}|$)))`, 'g')) + .map(item => { + if (new RegExp(reg).test(item)) { + return Promise.resolve(item) + } + return youdao({ + q: item, + from, + to, + }) + }) + + res = (await Promise.all(tasks)).join('') + } else { + res = `/${to + key}` + way = 'link' + } + if (res !== key) { + locales[to][key] = res + console.log(`${way}: ${from} -> ${to}: ${key} -> ${res}`) + } else { + console.log(`same: ${from} -> ${to}: ${key}`) + } + } + } + await fs.writeFileSync( + path.resolve(__dirname, outputPath), + jsonFormat(locales[to], { + type: 'space', + size: 2, + }) + ) +} +;(async () => { + const tasks = languages + .map(item => ({ + from: defaultLanguage, + to: item.key, + })) + .filter(item => item.from !== item.to) + + for (const item of tasks) { + console.log(`start: ${item.from} -> ${item.to}`) + await transform({ + from: item.from, + to: item.to, + locales, + outputPath: `../src/locales/${item.to}/messages.json`, + }) + console.log(`completed: ${item.from} -> ${item.to}`) + } + + console.log('All translations have been completed.') +})() diff --git a/src/components/DropOption/DropOption.js b/src/components/DropOption/DropOption.js new file mode 100644 index 0000000..1bb4ba2 --- /dev/null +++ b/src/components/DropOption/DropOption.js @@ -0,0 +1,35 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { BarsOutlined, DownOutlined } from '@ant-design/icons' +import { Dropdown, Button, Menu } from 'antd' + +const DropOption = ({ + onMenuClick, + menuOptions = [], + buttonStyle, + dropdownProps, +}) => { + const menu = menuOptions.map(item => ( + {item.name} + )) + return ( + {menu}} + {...dropdownProps} + > + + + ) +} + +DropOption.propTypes = { + onMenuClick: PropTypes.func, + menuOptions: PropTypes.array.isRequired, + buttonStyle: PropTypes.object, + dropdownProps: PropTypes.object, +} + +export default DropOption diff --git a/src/components/DropOption/package.json b/src/components/DropOption/package.json new file mode 100644 index 0000000..0a1dc40 --- /dev/null +++ b/src/components/DropOption/package.json @@ -0,0 +1,6 @@ +{ + "name": "DropOption", + "version": "0.0.0", + "private": true, + "main": "./DropOption.js" +} diff --git a/src/components/Editor/Editor.js b/src/components/Editor/Editor.js new file mode 100644 index 0000000..a89d167 --- /dev/null +++ b/src/components/Editor/Editor.js @@ -0,0 +1,17 @@ +import React from 'react' +import { Editor } from 'react-draft-wysiwyg' +import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css' +import styles from './Editor.less' + +const DraftEditor = props => { + return ( + + ) +} + +export default DraftEditor diff --git a/src/components/Editor/Editor.less b/src/components/Editor/Editor.less new file mode 100644 index 0000000..2cea380 --- /dev/null +++ b/src/components/Editor/Editor.less @@ -0,0 +1,106 @@ +.wrapper { + height: 500px; + + :global { + .rdw-dropdownoption-default { + padding: 6px; + } + + .rdw-dropdown-optionwrapper { + box-sizing: content-box; + width: 100%; + border-radius: 0 0 2px 2px; + &:hover { + box-shadow: none; + } + } + + .rdw-inline-wrapper { + flex-wrap: wrap; + margin-bottom: 0; + + .rdw-option-wrapper { + margin-bottom: 6px; + } + } + + .rdw-option-active { + box-shadow: 1px 1px 0 #e8e8e8 inset; + } + + .rdw-colorpicker-option { + box-shadow: none; + } + + .rdw-colorpicker-modal, + .rdw-embedded-modal, + .rdw-emoji-modal, + .rdw-image-modal, + .rdw-link-modal { + box-shadow: 4px 4px 40px rgba(0, 0, 0, 0.05); + } + + .rdw-colorpicker-modal, + .rdw-embedded-modal, + .rdw-link-modal { + height: auto; + } + + .rdw-emoji-modal { + width: 214px; + } + + .rdw-colorpicker-modal { + width: auto; + } + + .rdw-embedded-modal-btn, + .rdw-image-modal-btn, + .rdw-link-modal-btn { + height: 32px; + margin-top: 12px; + } + + .rdw-embedded-modal-input, + .rdw-embedded-modal-size-input, + .rdw-link-modal-input { + padding: 2px 6px; + height: 32px; + } + + .rdw-dropdown-selectedtext { + color: #000; + } + + .rdw-dropdown-wrapper, + .rdw-option-wrapper { + min-width: 36px; + transition: all 0.2s ease; + height: 30px; + + &:active { + box-shadow: 1px 1px 0 #e8e8e8 inset; + } + + &:hover { + box-shadow: 1px 1px 0 #e8e8e8; + } + } + + .rdw-dropdown-wrapper { + min-width: 60px; + } + + .rdw-editor-main { + box-sizing: border-box; + } + } + + .editor { + border: 1px solid #f1f1f1; + padding: 5px; + border-radius: 2px; + height: auto; + min-height: 200px; + } +} diff --git a/src/components/Editor/package.json b/src/components/Editor/package.json new file mode 100644 index 0000000..8069626 --- /dev/null +++ b/src/components/Editor/package.json @@ -0,0 +1,6 @@ +{ + "name": "Editor", + "version": "0.0.0", + "private": true, + "main": "./Editor.js" +} diff --git a/src/components/Ellipsis/index.d.ts b/src/components/Ellipsis/index.d.ts new file mode 100644 index 0000000..075fa78 --- /dev/null +++ b/src/components/Ellipsis/index.d.ts @@ -0,0 +1,21 @@ +import React from 'react'; +import { TooltipProps } from 'antd/lib/tooltip'; + +export interface EllipsisTooltipProps extends TooltipProps { + title?: undefined; + overlayStyle?: undefined; +} + +export interface EllipsisProps { + tooltip?: boolean | EllipsisTooltipProps; + length?: number; + lines?: number; + style?: React.CSSProperties; + className?: string; + fullWidthRecognition?: boolean; +} + +export function getStrFullLength(str: string): number; +export function cutStrByFullLength(str: string, maxLength: number): string; + +export default class Ellipsis extends React.Component {} diff --git a/src/components/Ellipsis/index.js b/src/components/Ellipsis/index.js new file mode 100644 index 0000000..de700b7 --- /dev/null +++ b/src/components/Ellipsis/index.js @@ -0,0 +1,270 @@ +import React, { Component } from 'react'; +import { Tooltip } from 'antd'; +import classNames from 'classnames'; +import styles from './index.less'; + +/* eslint react/no-did-mount-set-state: 0 */ +/* eslint no-param-reassign: 0 */ + +const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined; + +const TooltipOverlayStyle = { + overflowWrap: 'break-word', + wordWrap: 'break-word', +}; + +export const getStrFullLength = (str = '') => + str.split('').reduce((pre, cur) => { + const charCode = cur.charCodeAt(0); + if (charCode >= 0 && charCode <= 128) { + return pre + 1; + } + return pre + 2; + }, 0); + +export const cutStrByFullLength = (str = '', maxLength) => { + let showLength = 0; + return str.split('').reduce((pre, cur) => { + const charCode = cur.charCodeAt(0); + if (charCode >= 0 && charCode <= 128) { + showLength += 1; + } else { + showLength += 2; + } + if (showLength <= maxLength) { + return pre + cur; + } + return pre; + }, ''); +}; + +const getTooltip = ({ tooltip, overlayStyle, title, children }) => { + if (tooltip) { + const props = tooltip === true ? { overlayStyle, title } : { ...tooltip, overlayStyle, title }; + return {children}; + } + return children; +}; + +const EllipsisText = ({ text, length, tooltip, fullWidthRecognition, ...other }) => { + if (typeof text !== 'string') { + throw new Error('Ellipsis children must be string.'); + } + const textLength = fullWidthRecognition ? getStrFullLength(text) : text.length; + if (textLength <= length || length < 0) { + return {text}; + } + const tail = '...'; + let displayText; + if (length - tail.length <= 0) { + displayText = ''; + } else { + displayText = fullWidthRecognition ? cutStrByFullLength(text, length) : text.slice(0, length); + } + + const spanAttrs = tooltip ? {} : { ...other }; + return getTooltip({ + tooltip, + overlayStyle: TooltipOverlayStyle, + title: text, + children: ( + + {displayText} + {tail} + + ), + }); +}; + +export default class Ellipsis extends Component { + state = { + text: '', + targetCount: 0, + }; + + componentDidMount() { + if (this.node) { + this.computeLine(); + } + } + + componentDidUpdate(perProps) { + const { lines } = this.props; + if (lines !== perProps.lines) { + this.computeLine(); + } + } + + computeLine = () => { + const { lines } = this.props; + if (lines && !isSupportLineClamp) { + const text = this.shadowChildren.innerText || this.shadowChildren.textContent; + const lineHeight = parseInt(getComputedStyle(this.root).lineHeight, 10); + const targetHeight = lines * lineHeight; + this.content.style.height = `${targetHeight}px`; + const totalHeight = this.shadowChildren.offsetHeight; + const shadowNode = this.shadow.firstChild; + + if (totalHeight <= targetHeight) { + this.setState({ + text, + targetCount: text.length, + }); + return; + } + + // bisection + const len = text.length; + const mid = Math.ceil(len / 2); + + const count = this.bisection(targetHeight, mid, 0, len, text, shadowNode); + + this.setState({ + text, + targetCount: count, + }); + } + }; + + bisection = (th, m, b, e, text, shadowNode) => { + const suffix = '...'; + let mid = m; + let end = e; + let begin = b; + shadowNode.innerHTML = text.substring(0, mid) + suffix; + let sh = shadowNode.offsetHeight; + + if (sh <= th) { + shadowNode.innerHTML = text.substring(0, mid + 1) + suffix; + sh = shadowNode.offsetHeight; + if (sh > th || mid === begin) { + return mid; + } + begin = mid; + if (end - begin === 1) { + mid = 1 + begin; + } else { + mid = Math.floor((end - begin) / 2) + begin; + } + return this.bisection(th, mid, begin, end, text, shadowNode); + } + if (mid - 1 < 0) { + return mid; + } + shadowNode.innerHTML = text.substring(0, mid - 1) + suffix; + sh = shadowNode.offsetHeight; + if (sh <= th) { + return mid - 1; + } + end = mid; + mid = Math.floor((end - begin) / 2) + begin; + return this.bisection(th, mid, begin, end, text, shadowNode); + }; + + handleRoot = n => { + this.root = n; + }; + + handleContent = n => { + this.content = n; + }; + + handleNode = n => { + this.node = n; + }; + + handleShadow = n => { + this.shadow = n; + }; + + handleShadowChildren = n => { + this.shadowChildren = n; + }; + + render() { + const { text, targetCount } = this.state; + const { + children, + lines, + length, + className, + tooltip, + fullWidthRecognition, + ...restProps + } = this.props; + + const cls = classNames(styles.ellipsis, className, { + [styles.lines]: lines && !isSupportLineClamp, + [styles.lineClamp]: lines && isSupportLineClamp, + }); + + if (!lines && !length) { + return ( + + {children} + + ); + } + + // length + if (!lines) { + return ( + + ); + } + + const id = `antd-pro-ellipsis-${`${new Date().getTime()}${Math.floor(Math.random() * 100)}`}`; + + // support document.body.style.webkitLineClamp + if (isSupportLineClamp) { + const style = `#${id}{-webkit-line-clamp:${lines};-webkit-box-orient: vertical;}`; + + const node = ( +
+ + {children} +
+ ); + + return getTooltip({ + tooltip, + overlayStyle: TooltipOverlayStyle, + title: children, + children: node, + }); + } + + const childNode = ( + + {targetCount > 0 && text.substring(0, targetCount)} + {targetCount > 0 && targetCount < text.length && '...'} + + ); + + return ( +
+
+ {getTooltip({ + tooltip, + overlayStyle: TooltipOverlayStyle, + title: text, + children: childNode, + })} +
+ {children} +
+
+ {text} +
+
+
+ ); + } +} diff --git a/src/components/Ellipsis/index.less b/src/components/Ellipsis/index.less new file mode 100644 index 0000000..3c0360c --- /dev/null +++ b/src/components/Ellipsis/index.less @@ -0,0 +1,24 @@ +.ellipsis { + display: inline-block; + width: 100%; + overflow: hidden; + word-break: break-all; +} + +.lines { + position: relative; + .shadow { + position: absolute; + z-index: -999; + display: block; + color: transparent; + opacity: 0; + } +} + +.lineClamp { + position: relative; + display: -webkit-box; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/src/components/Ellipsis/index.md b/src/components/Ellipsis/index.md new file mode 100644 index 0000000..1875b17 --- /dev/null +++ b/src/components/Ellipsis/index.md @@ -0,0 +1,17 @@ +--- +title: Ellipsis +subtitle: 文本自动省略号 +cols: 1 +order: 10 +--- + +文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。 + +## API + +| 参数 | 说明 | 类型 | 默认值 | +| -------------------- | ------------------------------------------------ | ------- | ------ | +| tooltip | 移动到文本展示完整内容的提示 | boolean | - | +| length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | - | +| lines | 在按照行数截取下最大的行数,超过则截取省略 | number | `1` | +| fullWidthRecognition | 是否将全角字符的长度视为 2 来计算字符串长度 | boolean | - | diff --git a/src/components/Ellipsis/index.test.js b/src/components/Ellipsis/index.test.js new file mode 100644 index 0000000..4d057b2 --- /dev/null +++ b/src/components/Ellipsis/index.test.js @@ -0,0 +1,13 @@ +import { getStrFullLength, cutStrByFullLength } from './index'; + +describe('test calculateShowLength', () => { + it('get full length', () => { + expect(getStrFullLength('一二,a,')).toEqual(8); + }); + it('cut str by full length', () => { + expect(cutStrByFullLength('一二,a,', 7)).toEqual('一二,a'); + }); + it('cut str when length small', () => { + expect(cutStrByFullLength('一22三', 5)).toEqual('一22'); + }); +}); diff --git a/src/components/FilterItem/FilterItem.js b/src/components/FilterItem/FilterItem.js new file mode 100644 index 0000000..e701c8b --- /dev/null +++ b/src/components/FilterItem/FilterItem.js @@ -0,0 +1,28 @@ +import React from 'react' +import PropTypes from 'prop-types' +import styles from './FilterItem.less' + +const FilterItem = ({ label = '', children }) => { + const labelArray = label.split('') + return ( +
+ {labelArray.length > 0 && ( +
+ {labelArray.map((item, index) => ( + + {item} + + ))} +
+ )} +
{children}
+
+ ) +} + +FilterItem.propTypes = { + label: PropTypes.string, + children: PropTypes.element.isRequired, +} + +export default FilterItem diff --git a/src/components/FilterItem/FilterItem.less b/src/components/FilterItem/FilterItem.less new file mode 100644 index 0000000..6fe1e7b --- /dev/null +++ b/src/components/FilterItem/FilterItem.less @@ -0,0 +1,17 @@ +.filterItem { + display: flex; + justify-content: space-between; + + .labelWrap { + width: 80px; + line-height: 28px; + margin-right: 12px; + justify-content: space-between; + display: flex; + overflow: hidden; + } + + .item { + flex: 1; + } +} diff --git a/src/components/FilterItem/package.json b/src/components/FilterItem/package.json new file mode 100644 index 0000000..04c7d8a --- /dev/null +++ b/src/components/FilterItem/package.json @@ -0,0 +1,6 @@ +{ + "name": "FilterItem", + "version": "0.0.0", + "private": true, + "main": "./FilterItem.js" +} diff --git a/src/components/GlobalFooter/index.d.ts b/src/components/GlobalFooter/index.d.ts new file mode 100644 index 0000000..efde77d --- /dev/null +++ b/src/components/GlobalFooter/index.d.ts @@ -0,0 +1,14 @@ +import React from 'react'; +export interface GlobalFooterProps { + links?: Array<{ + key?: string; + title: React.ReactNode; + href: string; + blankTarget?: boolean; + }>; + copyright?: React.ReactNode; + style?: React.CSSProperties; + className?: string; +} + +export default class GlobalFooter extends React.Component {} diff --git a/src/components/GlobalFooter/index.js b/src/components/GlobalFooter/index.js new file mode 100644 index 0000000..1c2fb74 --- /dev/null +++ b/src/components/GlobalFooter/index.js @@ -0,0 +1,28 @@ +import React from 'react'; +import classNames from 'classnames'; +import styles from './index.less'; + +const GlobalFooter = ({ className, links, copyright }) => { + const clsString = classNames(styles.globalFooter, className); + return ( +
+ {links && ( +
+ {links.map(link => ( + + {link.title} + + ))} +
+ )} + {copyright &&
{copyright}
} +
+ ); +}; + +export default GlobalFooter; diff --git a/src/components/GlobalFooter/index.less b/src/components/GlobalFooter/index.less new file mode 100644 index 0000000..e4b3dfd --- /dev/null +++ b/src/components/GlobalFooter/index.less @@ -0,0 +1,29 @@ +@import '~antd/lib/style/themes/default.less'; + +.globalFooter { + margin: 48px 0 24px 0; + padding: 0 16px; + text-align: center; + + .links { + margin-bottom: 8px; + + a { + color: @text-color-secondary; + transition: all 0.3s; + + &:not(:last-child) { + margin-right: 40px; + } + + &:hover { + color: @text-color; + } + } + } + + .copyright { + color: @text-color-secondary; + font-size: @font-size-base; + } +} diff --git a/src/components/GlobalFooter/index.md b/src/components/GlobalFooter/index.md new file mode 100644 index 0000000..5d6058f --- /dev/null +++ b/src/components/GlobalFooter/index.md @@ -0,0 +1,15 @@ +--- +title: GlobalFooter +subtitle: 全局页脚 +cols: 1 +order: 7 +--- + +页脚属于全局导航的一部分,作为对顶部导航的补充,通过传递数据控制展示内容。 + +## API + +| 参数 | 说明 | 类型 | 默认值 | +| --------- | -------- | ---------------------------------------------------------------- | ------ | +| links | 链接数据 | array<{ title: ReactNode, href: string, blankTarget?: boolean }> | - | +| copyright | 版权信息 | ReactNode | - | diff --git a/src/components/Layout/Bread.js b/src/components/Layout/Bread.js new file mode 100644 index 0000000..ca86499 --- /dev/null +++ b/src/components/Layout/Bread.js @@ -0,0 +1,68 @@ +import React, { PureComponent, Fragment } from 'react' +import PropTypes from 'prop-types' +import { Breadcrumb } from 'antd' +import { Link, withRouter } from 'umi' +import { t } from "@lingui/macro" +import iconMap from 'utils/iconMap' +const { pathToRegexp } = require('path-to-regexp') +import { queryAncestors } from 'utils' +import styles from './Bread.less' + +@withRouter +class Bread extends PureComponent { + generateBreadcrumbs = (paths) => { + return paths.map((item, key) => { + const content = item && ( + + {item.icon && ( + {iconMap[item.icon]} + )} + {item.name} + + ) + + return ( + item && ( + + {paths.length - 1 !== key ? ( + {content} + ) : ( + content + )} + + ) + ) + }) + } + render() { + const { routeList, location } = this.props + + // Find a route that matches the pathname. + const currentRoute = routeList.find( + (_) => _.route && pathToRegexp(_.route).exec(location.pathname) + ) + + // Find the breadcrumb navigation of the current route match and all its ancestors. + const paths = currentRoute + ? queryAncestors(routeList, currentRoute, 'breadcrumbParentId').reverse() + : [ + routeList[0], + { + id: 404, + name: t`Not Found`, + }, + ] + + return ( + + {this.generateBreadcrumbs(paths)} + + ) + } +} + +Bread.propTypes = { + routeList: PropTypes.array, +} + +export default Bread diff --git a/src/components/Layout/Bread.less b/src/components/Layout/Bread.less new file mode 100644 index 0000000..d30a5f1 --- /dev/null +++ b/src/components/Layout/Bread.less @@ -0,0 +1,16 @@ +.bread { + margin-bottom: 24px; + + :global { + .ant-breadcrumb { + display: flex; + align-items: center; + } + } +} + +@media (max-width: 767px) { + .bread { + margin-bottom: 12px; + } +} diff --git a/src/components/Layout/Header.js b/src/components/Layout/Header.js new file mode 100644 index 0000000..3b37540 --- /dev/null +++ b/src/components/Layout/Header.js @@ -0,0 +1,169 @@ +import React, { PureComponent, Fragment } from 'react' +import PropTypes from 'prop-types' +import { Menu, Layout, Avatar, Popover, Badge, List } from 'antd' +import { Ellipsis } from 'components' +import { + BellOutlined, + RightOutlined, + MenuFoldOutlined, + MenuUnfoldOutlined, +} from '@ant-design/icons' +import { Trans } from "@lingui/macro" +import { getLocale, setLocale } from 'utils' +import moment from 'moment' +import classnames from 'classnames' +import config from 'config' +import styles from './Header.less' + +const { SubMenu } = Menu + +class Header extends PureComponent { + handleClickMenu = e => { + e.key === 'SignOut' && this.props.onSignOut() + } + render() { + const { + fixed, + avatar, + username, + collapsed, + notifications, + onCollapseChange, + onAllNotificationsRead, + } = this.props + + const rightContent = [ + + + + Hi, + + {username} + + + } + > + + Sign out + + + , + ] + + if (config.i18n) { + const { languages } = config.i18n + const language = getLocale() + const currentLanguage = languages.find( + item => item.key === language + ) + + rightContent.unshift( + { + setLocale(data.key) + }} + mode="horizontal" + > + }> + {languages.map(item => ( + + + {item.title} + + ))} + + + ) + } + + rightContent.unshift( + document.querySelector('#primaryLayout')} + content={ +
+ You have viewed all notifications., + }} + renderItem={item => ( + + + {item.title} + + } + description={moment(item.date).fromNow()} + /> + + + )} + /> + {notifications.length ? ( +
+ Clear notifications +
+ ) : null} +
+ } + > + + + +
+ ) + + return ( + +
+ {collapsed ? : } +
+
{rightContent}
+
+ ) + } +} + +Header.propTypes = { + fixed: PropTypes.bool, + user: PropTypes.object, + menus: PropTypes.array, + collapsed: PropTypes.bool, + onSignOut: PropTypes.func, + notifications: PropTypes.array, + onCollapseChange: PropTypes.func, + onAllNotificationsRead: PropTypes.func, +} + +export default Header diff --git a/src/components/Layout/Header.less b/src/components/Layout/Header.less new file mode 100644 index 0000000..1709b6d --- /dev/null +++ b/src/components/Layout/Header.less @@ -0,0 +1,154 @@ +@import '~themes/vars.less'; + +.header { + padding: 0; + box-shadow: @shadow-2; + position: relative; + display: flex; + justify-content: space-between; + height: 72px; + z-index: 9; + align-items: center; + background-color: #fff; + + &.fixed { + position: fixed; + top: 0; + right: 0; + width: ~'calc(100% - 256px)'; + z-index: 29; + transition: width 0.2s; + + &.collapsed { + width: ~'calc(100% - 80px)'; + } + } + + :global { + .ant-menu-submenu-title { + height: 72px; + } + + .ant-menu-horizontal { + line-height: 72px; + + & > .ant-menu-submenu:hover { + color: @primary-color; + background-color: @hover-color; + } + } + + .ant-menu { + border-bottom: none; + height: 72px; + } + + .ant-menu-horizontal > .ant-menu-submenu { + top: 0; + margin-top: 0; + } + + .ant-menu-horizontal > .ant-menu-item, + .ant-menu-horizontal > .ant-menu-submenu { + border-bottom: none; + } + + .ant-menu-horizontal > .ant-menu-item-active, + .ant-menu-horizontal > .ant-menu-item-open, + .ant-menu-horizontal > .ant-menu-item-selected, + .ant-menu-horizontal > .ant-menu-item:hover, + .ant-menu-horizontal > .ant-menu-submenu-active, + .ant-menu-horizontal > .ant-menu-submenu-open, + .ant-menu-horizontal > .ant-menu-submenu-selected, + .ant-menu-horizontal > .ant-menu-submenu:hover { + border-bottom: none; + } + } + + .rightContainer { + display: flex; + align-items: center; + } + + .button { + width: 72px; + height: 72px; + line-height: 72px; + text-align: center; + font-size: 18px; + cursor: pointer; + transition: @transition-ease-in; + + &:hover { + color: @primary-color; + background-color: @hover-color; + } + } +} + +.iconButton { + width: 48px; + height: 48px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 24px; + cursor: pointer; + .background-hover(); + + &:hover { + .iconFont { + color: @primary-color; + } + } + + & + .iconButton { + margin-left: 8px; + } + + .iconFont { + color: #b2b0c7; + font-size: 24px; + } +} + +.notification { + padding: 24px 0; + width: 320px; + .notificationItem { + transition: all 0.3s; + padding: 12px 24px; + cursor: pointer; + &:hover { + background-color: @hover-color; + } + } + .clearButton { + text-align: center; + height: 48px; + line-height: 48px; + cursor: pointer; + .background-hover(); + } +} + +.notificationPopover { + :global { + .ant-popover-inner-content { + padding: 0; + } + .ant-popover-arrow { + display: none; + } + .ant-list-item-content { + flex: 0; + margin-left: 16px; + } + } +} + +@media (max-width: 767px) { + .header { + width: 100% !important; + } +} diff --git a/src/components/Layout/Menu.js b/src/components/Layout/Menu.js new file mode 100644 index 0000000..8438599 --- /dev/null +++ b/src/components/Layout/Menu.js @@ -0,0 +1,122 @@ +import React, { PureComponent, Fragment } from 'react' +import PropTypes from 'prop-types' +import { Menu } from 'antd' +import { NavLink, withRouter } from 'umi' +import { pathToRegexp } from 'path-to-regexp' +import { arrayToTree, queryAncestors } from 'utils' +import iconMap from 'utils/iconMap' +import store from 'store' + +const { SubMenu } = Menu + +@withRouter +class SiderMenu extends PureComponent { + state = { + openKeys: store.get('openKeys') || [], + } + + onOpenChange = openKeys => { + const { menus } = this.props + const rootSubmenuKeys = menus.filter(_ => !_.menuParentId).map(_ => _.id) + + const latestOpenKey = openKeys.find( + key => this.state.openKeys.indexOf(key) === -1 + ) + + let newOpenKeys = openKeys + if (rootSubmenuKeys.indexOf(latestOpenKey) !== -1) { + newOpenKeys = latestOpenKey ? [latestOpenKey] : [] + } + + this.setState({ + openKeys: newOpenKeys, + }) + store.set('openKeys', newOpenKeys) + } + + generateMenus = data => { + return data.map(item => { + if (item.children) { + return ( + + {item.icon && iconMap[item.icon]} + {item.name} + + } + > + {this.generateMenus(item.children)} + + ) + } + return ( + + + {item.icon && iconMap[item.icon]} + {item.name} + + + ) + }) + } + + render() { + const { + collapsed, + theme, + menus, + location, + isMobile, + onCollapseChange, + } = this.props + + // Generating tree-structured data for menu content. + const menuTree = arrayToTree(menus, 'id', 'menuParentId') + + // Find a menu that matches the pathname. + const currentMenu = menus.find( + _ => _.route && pathToRegexp(_.route).exec(location.pathname) + ) + + // Find the key that should be selected according to the current menu. + const selectedKeys = currentMenu + ? queryAncestors(menus, currentMenu, 'menuParentId').map(_ => _.id) + : [] + + const menuProps = collapsed + ? {} + : { + openKeys: this.state.openKeys, + } + + return ( + { + onCollapseChange(true) + } + : undefined + } + {...menuProps} + > + {this.generateMenus(menuTree)} + + ) + } +} + +SiderMenu.propTypes = { + menus: PropTypes.array, + theme: PropTypes.string, + isMobile: PropTypes.bool, + onCollapseChange: PropTypes.func, +} + +export default SiderMenu diff --git a/src/components/Layout/Sider.js b/src/components/Layout/Sider.js new file mode 100644 index 0000000..575311d --- /dev/null +++ b/src/components/Layout/Sider.js @@ -0,0 +1,88 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import { Switch, Layout } from 'antd' +import { t } from "@lingui/macro" +import { Trans } from "@lingui/macro" +import { BulbOutlined } from '@ant-design/icons' +import ScrollBar from '../ScrollBar' +import { config } from 'utils' +import SiderMenu from './Menu' +import styles from './Sider.less' + +class Sider extends PureComponent { + render() { + const { + menus, + theme, + isMobile, + collapsed, + onThemeChange, + onCollapseChange, + } = this.props + + return ( + +
+
+ logo + {!collapsed &&

{config.siteName}

} +
+
+ +
+ + + +
+ {!collapsed && ( +
+ + + Switch Theme + + +
+ )} +
+ ) + } +} + +Sider.propTypes = { + menus: PropTypes.array, + theme: PropTypes.string, + isMobile: PropTypes.bool, + collapsed: PropTypes.bool, + onThemeChange: PropTypes.func, + onCollapseChange: PropTypes.func, +} + +export default Sider diff --git a/src/components/Layout/Sider.less b/src/components/Layout/Sider.less new file mode 100644 index 0000000..9f41821 --- /dev/null +++ b/src/components/Layout/Sider.less @@ -0,0 +1,110 @@ +@import '~themes/vars.less'; + +.sider { + box-shadow: fade(@primary-color, 10%) 0 0 28px 0; + z-index: 10; + :global { + .ant-layout-sider-children { + display: flex; + flex-direction: column; + justify-content: space-between; + } + } +} + +.brand { + z-index: 1; + height: 72px; + display: flex; + align-items: center; + justify-content: center; + padding: 0 24px; + box-shadow: 0 1px 9px -3px rgba(0, 0, 0, 0.2); + .logo { + display: flex; + align-items: center; + justify-content: center; + + img { + width: 36px; + margin-right: 8px; + } + + h1 { + vertical-align: text-bottom; + font-size: 16px; + text-transform: uppercase; + display: inline-block; + font-weight: 700; + color: @primary-color; + white-space: nowrap; + margin-bottom: 0; + .text-gradient(); + + :local { + animation: fadeRightIn 300ms @ease-in-out; + animation-fill-mode: both; + } + } + } +} + +.menuContainer { + height: ~'calc(100vh - 120px)'; + overflow-x: hidden; + flex: 1; + padding: 24px 0; + + &::-webkit-scrollbar-thumb { + background-color: transparent; + } + + &:hover { + &::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.2); + } + } + + :global { + .ant-menu-inline { + border-right: none; + } + } +} + +.switchTheme { + width: 100%; + height: 48px; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 16px; + overflow: hidden; + transition: all 0.3s; + + span { + white-space: nowrap; + overflow: hidden; + font-size: 12px; + } + + :global { + .anticon { + min-width: 14px; + margin-right: 4px; + font-size: 14px; + } + } +} + +@keyframes fadeLeftIn { + 0% { + transform: translateX(5px); + opacity: 0; + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} diff --git a/src/components/Layout/index.js b/src/components/Layout/index.js new file mode 100644 index 0000000..3ad0894 --- /dev/null +++ b/src/components/Layout/index.js @@ -0,0 +1,6 @@ +import Header from './Header' +import Menu from './Menu' +import Bread from './Bread' +import Sider from './Sider' + +export { Header, Menu, Bread, Sider } diff --git a/src/components/Loader/Loader.js b/src/components/Loader/Loader.js new file mode 100644 index 0000000..5a5a021 --- /dev/null +++ b/src/components/Loader/Loader.js @@ -0,0 +1,27 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classNames from 'classnames' +import styles from './Loader.less' + +const Loader = ({ spinning = false, fullScreen }) => { + return ( +
+
+
+
LOADING
+
+
+ ) +} + +Loader.propTypes = { + spinning: PropTypes.bool, + fullScreen: PropTypes.bool, +} + +export default Loader diff --git a/src/components/Loader/Loader.less b/src/components/Loader/Loader.less new file mode 100644 index 0000000..9fa02dc --- /dev/null +++ b/src/components/Loader/Loader.less @@ -0,0 +1,67 @@ +.loader { + background-color: #fff; + width: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + z-index: 100000; + display: flex; + justify-content: center; + align-items: center; + opacity: 1; + text-align: center; + + &.fullScreen { + position: fixed; + } + + .warpper { + width: 100px; + height: 100px; + display: inline-flex; + flex-direction: column; + justify-content: space-around; + } + + .inner { + width: 40px; + height: 40px; + margin: 0 auto; + text-indent: -12345px; + border-top: 1px solid rgba(0, 0, 0, 0.08); + border-right: 1px solid rgba(0, 0, 0, 0.08); + border-bottom: 1px solid rgba(0, 0, 0, 0.08); + border-left: 1px solid rgba(0, 0, 0, 0.7); + border-radius: 50%; + z-index: 100001; + + :local { + animation: spinner 600ms infinite linear; + } + } + + .text { + width: 100px; + height: 20px; + text-align: center; + font-size: 12px; + letter-spacing: 4px; + color: #000; + } + + &.hidden { + z-index: -1; + opacity: 0; + transition: opacity 1s ease 0.5s, z-index 0.1s ease 1.5s; + } +} +@keyframes spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/src/components/Loader/package.json b/src/components/Loader/package.json new file mode 100644 index 0000000..15bde9a --- /dev/null +++ b/src/components/Loader/package.json @@ -0,0 +1,6 @@ +{ + "name": "Loader", + "version": "0.0.0", + "private": true, + "main": "./Loader.js" +} diff --git a/src/components/Page/Page.js b/src/components/Page/Page.js new file mode 100644 index 0000000..532bf31 --- /dev/null +++ b/src/components/Page/Page.js @@ -0,0 +1,33 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import Loader from '../Loader' +import styles from './Page.less' + +export default class Page extends Component { + render() { + const { className, children, loading = false, inner = false } = this.props + const loadingStyle = { + height: 'calc(100vh - 184px)', + overflow: 'hidden', + } + return ( +
+ {loading ? : ''} + {children} +
+ ) + } +} + +Page.propTypes = { + className: PropTypes.string, + children: PropTypes.node, + loading: PropTypes.bool, + inner: PropTypes.bool, +} diff --git a/src/components/Page/Page.less b/src/components/Page/Page.less new file mode 100644 index 0000000..e180131 --- /dev/null +++ b/src/components/Page/Page.less @@ -0,0 +1,16 @@ +@import '~themes/vars.less'; + +.contentInner { + background: #fff; + padding: 24px; + box-shadow: @shadow-1; + min-height: ~'calc(100vh - 230px)'; + position: relative; +} + +@media (max-width: 767px) { + .contentInner { + padding: 12px; + min-height: ~'calc(100vh - 160px)'; + } +} diff --git a/src/components/Page/package.json b/src/components/Page/package.json new file mode 100644 index 0000000..a3811bd --- /dev/null +++ b/src/components/Page/package.json @@ -0,0 +1,6 @@ +{ + "name": "Page", + "version": "0.0.0", + "private": true, + "main": "./Page.js" +} diff --git a/src/components/ScrollBar/index.js b/src/components/ScrollBar/index.js new file mode 100644 index 0000000..ce752b5 --- /dev/null +++ b/src/components/ScrollBar/index.js @@ -0,0 +1,5 @@ +import ScrollBar from 'react-perfect-scrollbar' +import 'react-perfect-scrollbar/dist/css/styles.css' +import './index.less' + +export default ScrollBar diff --git a/src/components/ScrollBar/index.less b/src/components/ScrollBar/index.less new file mode 100644 index 0000000..31e149b --- /dev/null +++ b/src/components/ScrollBar/index.less @@ -0,0 +1,31 @@ +:global { + .ps--active-x > .ps__rail-x, + .ps--active-y > .ps__rail-y { + background-color: transparent; + } + + .ps__rail-x:hover > .ps__thumb-x, + .ps__rail-x:focus > .ps__thumb-x { + height: 8px; + } + + .ps__rail-y:hover > .ps__thumb-y, + .ps__rail-y:focus > .ps__thumb-y { + width: 8px; + } + + .ps__rail-y, + .ps__rail-x { + z-index: 9; + } + + .ps__thumb-y { + width: 4px; + right: 4px; + } + + .ps__thumb-x { + height: 4px; + bottom: 4px; + } +} diff --git a/src/components/index.js b/src/components/index.js new file mode 100644 index 0000000..d3d3750 --- /dev/null +++ b/src/components/index.js @@ -0,0 +1,11 @@ +import Editor from './Editor' +import FilterItem from './FilterItem' +import DropOption from './DropOption' +import Loader from './Loader' +import ScrollBar from './ScrollBar' +import GlobalFooter from './GlobalFooter' +import Ellipsis from './Ellipsis' +import * as MyLayout from './Layout/index.js' +import Page from './Page' + +export { MyLayout, Editor, GlobalFooter, Ellipsis, FilterItem, DropOption, Loader, Page, ScrollBar } diff --git a/src/e2e/login.e2e.js b/src/e2e/login.e2e.js new file mode 100644 index 0000000..7c8fd0e --- /dev/null +++ b/src/e2e/login.e2e.js @@ -0,0 +1,41 @@ +import puppeteer from 'puppeteer' + +describe('Login', () => { + let browser + let page + + beforeAll(async () => { + browser = await puppeteer.launch({ args: ['--no-sandbox'] }) + }) + + beforeEach(async () => { + page = await browser.newPage() + await page.goto('http://localhost:8000/en/login', { + waitUntil: 'networkidle2', + }) + }) + + afterEach(() => page.close()) + + it('should login with failure', async () => { + await page.waitFor(selector => !!document.querySelector('#username'), { + timeout: 3000, + }) + await page.type('#username', 'wrong_user') + await page.type('#password', 'wrong_password') + await page.click('button[type="button"]') + await page.waitForSelector('.anticon-close-circle') // should display error + }) + + it('should login successfully', async () => { + await page.waitForSelector('#username', { timeout: 3000 }) + await page.type('#username', 'admin') + await page.type('#password', 'admin') + await page.click('button[type="button"]') + await page.waitForSelector('.ant-layout-footer') + const text = await page.evaluate(() => document.body.innerHTML) + expect(text).toContain('Ant Design Admin') + }) + + afterAll(() => browser.close()) +}) diff --git a/src/layouts/BaseLayout.js b/src/layouts/BaseLayout.js new file mode 100644 index 0000000..4e36bed --- /dev/null +++ b/src/layouts/BaseLayout.js @@ -0,0 +1,55 @@ +import React, { PureComponent, Fragment } from 'react' +import PropTypes from 'prop-types' +import { connect } from 'umi' +import { Helmet } from 'react-helmet' +import { Loader } from 'components' +import { queryLayout } from 'utils' +import NProgress from 'nprogress' +import config from 'utils/config' +import { withRouter } from 'umi' + +import PublicLayout from './PublicLayout' +import PrimaryLayout from './PrimaryLayout' +import './BaseLayout.less' + +const LayoutMap = { + primary: PrimaryLayout, + public: PublicLayout, +} + +@withRouter +@connect(({ loading }) => ({ loading })) +class BaseLayout extends PureComponent { + previousPath = '' + + render() { + const { loading, children, location } = this.props + const Container = LayoutMap[queryLayout(config.layouts, location.pathname)] + + const currentPath = location.pathname + location.search + if (currentPath !== this.previousPath) { + NProgress.start() + } + + if (!loading.global) { + NProgress.done() + this.previousPath = currentPath + } + + return ( + + + {config.siteName} + + + {children} + + ) + } +} + +BaseLayout.propTypes = { + loading: PropTypes.object, +} + +export default BaseLayout diff --git a/src/layouts/BaseLayout.less b/src/layouts/BaseLayout.less new file mode 100644 index 0000000..d958d75 --- /dev/null +++ b/src/layouts/BaseLayout.less @@ -0,0 +1,74 @@ +@import '~themes/vars.less'; +@import '~themes/index.less'; + +:global { + #nprogress { + pointer-events: none; + + .bar { + background: @primary-color; + position: fixed; + z-index: 2048; + top: 0; + left: 0; + right: 0; + width: 100%; + height: 2px; + } + + .peg { + display: block; + position: absolute; + right: 0; + width: 100px; + height: 100%; + box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; + opacity: 1; + transform: rotate(3deg) translate(0, -4px); + } + + .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; + } + + .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + border: solid 2px transparent; + border-top-color: @primary-color; + border-left-color: @primary-color; + border-radius: 50%; + + :local { + animation: nprogress-spinner 400ms linear infinite; + } + } + } + + .nprogress-custom-parent { + overflow: hidden; + position: relative; + + #nprogress { + .bar, + .spinner { + position: absolute; + } + } + } +} + +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} diff --git a/src/layouts/PrimaryLayout.js b/src/layouts/PrimaryLayout.js new file mode 100644 index 0000000..b054705 --- /dev/null +++ b/src/layouts/PrimaryLayout.js @@ -0,0 +1,168 @@ +/* global window */ +/* global document */ +import React, { PureComponent, Fragment } from 'react' +import PropTypes from 'prop-types' +import { withRouter } from 'umi' +import { connect } from 'umi' +import { MyLayout, GlobalFooter } from 'components' +import { BackTop, Layout, Drawer } from 'antd' +import { enquireScreen, unenquireScreen } from 'enquire-js' +const { pathToRegexp } = require("path-to-regexp") +import { config, getLocale } from 'utils' +import Error from '../pages/404' +import styles from './PrimaryLayout.less' +import store from 'store' + +const { Content } = Layout +const { Header, Bread, Sider } = MyLayout + +@withRouter +@connect(({ app, loading }) => ({ app, loading })) +class PrimaryLayout extends PureComponent { + state = { + isMobile: false, + } + + componentDidMount() { + this.enquireHandler = enquireScreen(mobile => { + const { isMobile } = this.state + if (isMobile !== mobile) { + this.setState({ + isMobile: mobile, + }) + } + }) + } + + componentWillUnmount() { + unenquireScreen(this.enquireHandler) + } + + onCollapseChange = collapsed => { + this.props.dispatch({ + type: 'app/handleCollapseChange', + payload: collapsed, + }) + } + + render() { + const { app, location, dispatch, children } = this.props + const { theme, collapsed, notifications } = app + const user = store.get('user') || {} + const permissions = store.get('permissions') || {} + const routeList = store.get('routeList') || [] + const { isMobile } = this.state + const { onCollapseChange } = this + + // Localized route name. + + const lang = getLocale() + const newRouteList = + lang !== 'en' + ? routeList.map(item => { + const { name, ...other } = item + return { + ...other, + name: (item[lang] || {}).name || name, + } + }) + : routeList + + // Find a route that matches the pathname. + const currentRoute = newRouteList.find( + _ => _.route && pathToRegexp(_.route).exec(location.pathname) + ) + + // Query whether you have permission to enter this page + const hasPermission = currentRoute + ? permissions.visit.includes(currentRoute.id) + : false + + // MenuParentId is equal to -1 is not a available menu. + const menus = newRouteList.filter(_ => _.menuParentId !== '-1') + + const headerProps = { + menus, + collapsed, + notifications, + onCollapseChange, + avatar: user.avatar, + username: user.username, + fixed: config.fixedHeader, + onAllNotificationsRead() { + dispatch({ type: 'app/allNotificationsRead' }) + }, + onSignOut() { + dispatch({ type: 'app/signOut' }) + }, + } + + const siderProps = { + theme, + menus, + isMobile, + collapsed, + onCollapseChange, + onThemeChange(theme) { + dispatch({ + type: 'app/handleThemeChange', + payload: theme, + }) + }, + } + + return ( + + + {isMobile ? ( + + + + ) : ( + + )} +
+
+ + + {hasPermission ? children : } + + document.querySelector('#primaryLayout')} + /> + +
+
+
+ ) + } +} + +PrimaryLayout.propTypes = { + children: PropTypes.element.isRequired, + location: PropTypes.object, + dispatch: PropTypes.func, + app: PropTypes.object, + loading: PropTypes.object, +} + +export default PrimaryLayout diff --git a/src/layouts/PrimaryLayout.less b/src/layouts/PrimaryLayout.less new file mode 100644 index 0000000..6ee60c9 --- /dev/null +++ b/src/layouts/PrimaryLayout.less @@ -0,0 +1,58 @@ +@import '~themes/vars.less'; + +.backTop { + right: 50px; + + :global { + .ant-back-top-content { + background: @primary-color; + opacity: 0.3; + transition: all 0.3s; + box-shadow: 0 0 15px 1px rgba(69, 65, 78, 0.1); + + &:hover { + opacity: 1; + } + } + } +} + +.content { + padding: 24px; + min-height: ~'calc(100% - 72px)'; + // overflow-y: scroll; +} + +.container { + height: 100vh; + flex: 1; + width: ~'calc(100% - 256px)'; + overflow-y: scroll; + overflow-x: hidden; +} + +.footer { + background: #fff; + margin-top: 0; + margin-bottom: 0; + padding-top: 24px; + padding-bottom: 24px; + min-height: 72px; +} + +@media (max-width: 767px) { + .content { + padding: 12px; + } + + .backTop { + right: 20px; + bottom: 20px; + } + + .container { + height: 100vh; + flex: 1; + width: 100%; + } +} diff --git a/src/layouts/PublicLayout.js b/src/layouts/PublicLayout.js new file mode 100644 index 0000000..caaaf5c --- /dev/null +++ b/src/layouts/PublicLayout.js @@ -0,0 +1,3 @@ +export default ({ children }) => { + return children +} diff --git a/src/layouts/index.js b/src/layouts/index.js new file mode 100644 index 0000000..cd45ffe --- /dev/null +++ b/src/layouts/index.js @@ -0,0 +1,71 @@ +import React, { Component } from 'react' +import { withRouter } from 'umi' +import { ConfigProvider } from 'antd' +import { i18n } from "@lingui/core" +import { I18nProvider } from '@lingui/react' +import { getLocale } from 'utils' +import { zh, en, pt } from 'make-plural/plurals' +import zhCN from 'antd/lib/locale-provider/zh_CN' +import enUS from 'antd/lib/locale-provider/en_US' +import ptBR from 'antd/lib/locale-provider/pt_BR' + +import BaseLayout from './BaseLayout' + +i18n.loadLocaleData({ + en: { plurals: en }, + zh: { plurals: zh }, + 'pt-br': { plurals: pt } +}) + +// antd +const languages = { + zh: zhCN, + en: enUS, + 'pt-br': ptBR +} + +const { defaultLanguage } = i18n + +@withRouter +class Layout extends Component { + state = { + } + + componentDidMount() { + } + + loadCatalog = async (lan) => { + const catalog = await import( + `../locales/${lan}/messages.json` + ) + + i18n.load(lan, catalog) + i18n.activate(lan) + + // if (lan != i18n.locale) { + // i18n.load(lan, catalog) + // i18n.activate(lan) + // } + + } + + render() { + const { children } = this.props + + let language = getLocale() + + if (!languages[language]) language = defaultLanguage + + this.loadCatalog(language) + + return ( + + + {children} + + + ) + } +} + +export default Layout diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json new file mode 100644 index 0000000..538126f --- /dev/null +++ b/src/locales/en/messages.json @@ -0,0 +1,56 @@ +{ + "/dashboard": "/dashboard", + "Add Param": "Add Param", + "Address": "Address", + "Age": "Age", + "Are you sure delete this record?": "Are you sure delete this record?", + "Author": "Author", + "Avatar": "Avatar", + "Categories": "Categories", + "Clear notifications": "Clear notifications", + "Comments": "Comments", + "Create": "Create", + "Create User": "Create User", + "CreateTime": "CreateTime", + "LastLoginTime": "LastLoginTime", + "Dark": "Dark", + "Delete": "Delete", + "Email": "Email", + "Female": "Female", + "Gender": "Gender", + "Hi,": "Hi,", + "Image": "Image", + "Light": "Light", + "Male": "Male", + "Name": "Name", + "NickName": "NickName", + "Not Found": "Not Found", + "Operation": "Operation", + "Params": "Params", + "Password": "Password", + "Phone": "Phone", + "Pick an address": "Pick an address", + "Please pick an address": "Please pick an address", + "Publised": "Publised", + "Publish Date": "Publish Date", + "Reset": "Reset", + "Search": "Search", + "Search Name": "Search Name", + "Send": "Send", + "Sign in": "Sign in", + "Sign out": "Sign out", + "Switch Theme": "Switch Theme", + "Tags": "Tags", + "The input is not valid E-mail!": "The input is not valid E-mail!", + "The input is not valid phone!": "The input is not valid phone!", + "Title": "Title", + "Total {total} Items": "Total {total} Items", + "Unpublished": "Unpublished", + "Update": "Update", + "Update User": "Update User", + "Username": "Username", + "Views": "Views", + "Visibility": "Visibility", + "You have viewed all notifications.": "You have viewed all notifications.", + "Status": "Status" +} \ No newline at end of file diff --git a/src/locales/pt-br/messages.json b/src/locales/pt-br/messages.json new file mode 100644 index 0000000..2e931da --- /dev/null +++ b/src/locales/pt-br/messages.json @@ -0,0 +1,54 @@ +{ + "/dashboard": "/dashboard", + "Add Param": "Add Parametro", + "Address": "Endereço", + "Age": "Ano", + "Are you sure delete this record?": "Tem certeza de excluir este registro?", + "Author": "Autor", + "Avatar": "Avatar", + "Categories": "Categorias", + "Clear notifications": "limpar notificações", + "Comments": "Comentarios", + "Create": "Criar", + "Create User": "Criar Usuário", + "CreateTime": "CreateTime", + "Dark": "Escuro", + "Delete": "Deletar", + "Email": "Email", + "Female": "Feminino", + "Gender": "Genero", + "Hi,": "Olá,", + "Image": "Imagem", + "Light": "Claro", + "Male": "masculino", + "Name": "Nome", + "NickName": "NickName", + "Not Found": "Não Encontrado", + "Operation": "Operation", + "Params": "Parametros", + "Password": "Senha", + "Phone": "Fone", + "Pick an address": "Escolha um endereço", + "Please pick an address": "Por favor, escolha um endereço", + "Publised": "Publicado", + "Publish Date": "Data de publicação", + "Reset": "Reset", + "Search": "procurar", + "Search Name": "Search Name", + "Send": "Enviar", + "Sign in": "Sign in", + "Sign out": "Sign out", + "Switch Theme": "Trocar tema", + "Tags": "Tags", + "The input is not valid E-mail!": "Não é um E-mail valido!", + "The input is not valid phone!": "Não é um telefone Valido!", + "Title": "Titulo", + "Total {total} Items": "Total {total} Items", + "Unpublished": "Não publicado", + "Update": "Atualizar", + "Update User": "Atualizar Usuário", + "Username": "Usuário", + "Views": "visualizações", + "Visibility": "Visibilidade", + "You have viewed all notifications.": "Você visualizou todas as notificações." +} diff --git a/src/locales/zh/messages.json b/src/locales/zh/messages.json new file mode 100644 index 0000000..ac2df4a --- /dev/null +++ b/src/locales/zh/messages.json @@ -0,0 +1,56 @@ +{ + "/dashboard": "/zh/dashboard", + "Add Param": "添加参数", + "Address": "地址", + "Age": "年龄", + "Are you sure delete this record?": "您确定要删除这条记录吗?", + "Author": "作者", + "Avatar": "头像", + "Categories": "类别", + "Clear notifications": "清空消息", + "Comments": "评论数", + "Create": "创建", + "Create User": "创建用户", + "CreateTime": "创建时间", + "LastLoginTime": "上次登录时间", + "Dark": "暗", + "Delete": "删除", + "Email": "电子邮件", + "Female": "女", + "Gender": "性别", + "Hi,": "你好,", + "Image": "图像", + "Light": "明", + "Male": "男性", + "Name": "名字", + "NickName": "昵称", + "Not Found": "未找到", + "Operation": "操作", + "Params": "参数", + "Password": "密码", + "Phone": "电话", + "Pick an address": "选择地址", + "Please pick an address": "选择地址", + "Publised": "已发布", + "Publish Date": "发布日期", + "Reset": "重置", + "Search": "搜索", + "Search Name": "搜索名字", + "Send": "发送", + "Sign in": "登录", + "Sign out": "退出登录", + "Switch Theme": "切换主题", + "Tags": "标签", + "The input is not valid E-mail!": "输入的电子邮件无效!", + "The input is not valid phone!": "输入无效的手机!", + "Title": "标题", + "Total {total} Items": "总共 {total} 条记录", + "Unpublished": "未发布", + "Update": "更新", + "Update User": "更新用户", + "Username": "用户名", + "Views": "浏览数", + "Visibility": "可见性", + "You have viewed all notifications.": "您已查看所有通知", + "Status": "状态" +} \ No newline at end of file diff --git a/src/models/app.js b/src/models/app.js new file mode 100644 index 0000000..a868eca --- /dev/null +++ b/src/models/app.js @@ -0,0 +1,161 @@ +/* global window */ + +import { history } from 'umi' +import { stringify } from 'qs' +import store from 'store' +const { pathToRegexp } = require("path-to-regexp") +import { ROLE_TYPE } from 'utils/constant' +import { queryLayout } from 'utils' +import { CANCEL_REQUEST_MESSAGE } from 'utils/constant' +import api from 'api' +import config from 'config' + +const { queryRouteList, logoutUser, queryUserInfo } = api + +const goDashboard = () => { + if (pathToRegexp(['/', '/login']).exec(window.location.pathname)) { + history.push({ + pathname: '/dashboard', + }) + } +} + +export default { + namespace: 'app', + state: { + routeList: [ + { + id: '1', + icon: 'laptop', + name: 'Dashboard', + zhName: '仪表盘', + router: '/dashboard', + }, + ], + locationPathname: '', + locationQuery: {}, + theme: store.get('theme') || 'light', + collapsed: store.get('collapsed') || false, + notifications: [ + { + title: 'New User is registered.', + date: new Date(Date.now() - 10000000), + }, + { + title: 'Application has been approved.', + date: new Date(Date.now() - 50000000), + }, + ], + }, + subscriptions: { + setup({ dispatch }) { + dispatch({ type: 'query' }) + }, + setupHistory({ dispatch, history }) { + history.listen(location => { + dispatch({ + type: 'updateState', + payload: { + locationPathname: location.pathname, + locationQuery: location.query, + }, + }) + }) + }, + + setupRequestCancel({ history }) { + history.listen(() => { + const { cancelRequest = new Map() } = window + + cancelRequest.forEach((value, key) => { + if (value.pathname !== window.location.pathname) { + value.cancel(CANCEL_REQUEST_MESSAGE) + cancelRequest.delete(key) + } + }) + }) + }, + }, + effects: { + *query({ payload }, { call, put, select }) { + // store isInit to prevent query trigger by refresh + const isInit = store.get('isInit') + if (isInit) { + goDashboard() + return + } + const { locationPathname } = yield select(_ => _.app) + const { success, user } = yield call(queryUserInfo, payload) + if (success && user) { + const { list } = yield call(queryRouteList) + const { permissions } = user + let routeList = list + if ( + permissions.role === ROLE_TYPE.ADMIN || + permissions.role === ROLE_TYPE.DEVELOPER + ) { + permissions.visit = list.map(item => item.id) + } else { + routeList = list.filter(item => { + const cases = [ + permissions.visit.includes(item.id), + item.mpid + ? permissions.visit.includes(item.mpid) || item.mpid === '-1' + : true, + item.bpid ? permissions.visit.includes(item.bpid) : true, + ] + return cases.every(_ => _) + }) + } + store.set('routeList', routeList) + store.set('permissions', permissions) + store.set('user', user) + store.set('isInit', true) + goDashboard() + } else if (queryLayout(config.layouts, locationPathname) !== 'public') { + history.push({ + pathname: '/login', + search: stringify({ + from: locationPathname, + }), + }) + } + }, + + *signOut({ payload }, { call, put }) { + const data = yield call(logoutUser) + if (data.success) { + store.set('routeList', []) + store.set('permissions', { visit: [] }) + store.set('user', {}) + store.set('isInit', false) + store.set('token', false) + yield put({ type: 'query' }) + } else { + throw data + } + }, + }, + reducers: { + updateState(state, { payload }) { + return { + ...state, + ...payload, + } + }, + + handleThemeChange(state, { payload }) { + store.set('theme', payload) + state.theme = payload + }, + + handleCollapseChange(state, { payload }) { + store.set('collapsed', payload) + state.collapsed = payload + }, + + allNotificationsRead(state) { + state.notifications = [] + }, + }, +} diff --git a/src/pages/404.less b/src/pages/404.less new file mode 100644 index 0000000..f5300b1 --- /dev/null +++ b/src/pages/404.less @@ -0,0 +1,19 @@ +.error { + color: black; + text-align: center; + position: absolute; + top: 30%; + margin-top: -50px; + left: 50%; + margin-left: -100px; + width: 200px; + + :global .anticon { + font-size: 48px; + margin-bottom: 16px; + } + + h1 { + font-family: cursive; + } +} diff --git a/src/pages/404.tsx b/src/pages/404.tsx new file mode 100644 index 0000000..cff81d3 --- /dev/null +++ b/src/pages/404.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import { FrownOutlined } from '@ant-design/icons' +import { Page } from 'components' +import styles from './404.less' + +const Error = () => ( + +
+ +

404 Not Found

+
+
+) + +export default Error diff --git a/src/pages/chart/ECharts/AirportCoordComponent.js b/src/pages/chart/ECharts/AirportCoordComponent.js new file mode 100644 index 0000000..6b8c2ba --- /dev/null +++ b/src/pages/chart/ECharts/AirportCoordComponent.js @@ -0,0 +1,321 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +require('./map/js/china.js') + +const AirportCoordComponent = () => { + let geoCoordMap = { + 上海: [121.4648, 31.2891], + 东莞: [113.8953, 22.901], + 东营: [118.7073, 37.5513], + 中山: [113.4229, 22.478], + 临汾: [111.4783, 36.1615], + 临沂: [118.3118, 35.2936], + 丹东: [124.541, 40.4242], + 丽水: [119.5642, 28.1854], + 乌鲁木齐: [87.9236, 43.5883], + 佛山: [112.8955, 23.1097], + 保定: [115.0488, 39.0948], + 兰州: [103.5901, 36.3043], + 包头: [110.3467, 41.4899], + 北京: [116.4551, 40.2539], + 北海: [109.314, 21.6211], + 南京: [118.8062, 31.9208], + 南宁: [108.479, 23.1152], + 南昌: [116.0046, 28.6633], + 南通: [121.1023, 32.1625], + 厦门: [118.1689, 24.6478], + 台州: [121.1353, 28.6688], + 合肥: [117.29, 32.0581], + 呼和浩特: [111.4124, 40.4901], + 咸阳: [108.4131, 34.8706], + 哈尔滨: [127.9688, 45.368], + 唐山: [118.4766, 39.6826], + 嘉兴: [120.9155, 30.6354], + 大同: [113.7854, 39.8035], + 大连: [122.2229, 39.4409], + 天津: [117.4219, 39.4189], + 太原: [112.3352, 37.9413], + 威海: [121.9482, 37.1393], + 宁波: [121.5967, 29.6466], + 宝鸡: [107.1826, 34.3433], + 宿迁: [118.5535, 33.7775], + 常州: [119.4543, 31.5582], + 广州: [113.5107, 23.2196], + 廊坊: [116.521, 39.0509], + 延安: [109.1052, 36.4252], + 张家口: [115.1477, 40.8527], + 徐州: [117.5208, 34.3268], + 德州: [116.6858, 37.2107], + 惠州: [114.6204, 23.1647], + 成都: [103.9526, 30.7617], + 扬州: [119.4653, 32.8162], + 承德: [117.5757, 41.4075], + 拉萨: [91.1865, 30.1465], + 无锡: [120.3442, 31.5527], + 日照: [119.2786, 35.5023], + 昆明: [102.9199, 25.4663], + 杭州: [119.5313, 29.8773], + 枣庄: [117.323, 34.8926], + 柳州: [109.3799, 24.9774], + 株洲: [113.5327, 27.0319], + 武汉: [114.3896, 30.6628], + 汕头: [117.1692, 23.3405], + 江门: [112.6318, 22.1484], + 沈阳: [123.1238, 42.1216], + 沧州: [116.8286, 38.2104], + 河源: [114.917, 23.9722], + 泉州: [118.3228, 25.1147], + 泰安: [117.0264, 36.0516], + 泰州: [120.0586, 32.5525], + 济南: [117.1582, 36.8701], + 济宁: [116.8286, 35.3375], + 海口: [110.3893, 19.8516], + 淄博: [118.0371, 36.6064], + 淮安: [118.927, 33.4039], + 深圳: [114.5435, 22.5439], + 清远: [112.9175, 24.3292], + 温州: [120.498, 27.8119], + 渭南: [109.7864, 35.0299], + 湖州: [119.8608, 30.7782], + 湘潭: [112.5439, 27.7075], + 滨州: [117.8174, 37.4963], + 潍坊: [119.0918, 36.524], + 烟台: [120.7397, 37.5128], + 玉溪: [101.9312, 23.8898], + 珠海: [113.7305, 22.1155], + 盐城: [120.2234, 33.5577], + 盘锦: [121.9482, 41.0449], + 石家庄: [114.4995, 38.1006], + 福州: [119.4543, 25.9222], + 秦皇岛: [119.2126, 40.0232], + 绍兴: [120.564, 29.7565], + 聊城: [115.9167, 36.4032], + 肇庆: [112.1265, 23.5822], + 舟山: [122.2559, 30.2234], + 苏州: [120.6519, 31.3989], + 莱芜: [117.6526, 36.2714], + 菏泽: [115.6201, 35.2057], + 营口: [122.4316, 40.4297], + 葫芦岛: [120.1575, 40.578], + 衡水: [115.8838, 37.7161], + 衢州: [118.6853, 28.8666], + 西宁: [101.4038, 36.8207], + 西安: [109.1162, 34.2004], + 贵阳: [106.6992, 26.7682], + 连云港: [119.1248, 34.552], + 邢台: [114.8071, 37.2821], + 邯郸: [114.4775, 36.535], + 郑州: [113.4668, 34.6234], + 鄂尔多斯: [108.9734, 39.2487], + 重庆: [107.7539, 30.1904], + 金华: [120.0037, 29.1028], + 铜川: [109.0393, 35.1947], + 银川: [106.3586, 38.1775], + 镇江: [119.4763, 31.9702], + 长春: [125.8154, 44.2584], + 长沙: [113.0823, 28.2568], + 长治: [112.8625, 36.4746], + 阳泉: [113.4778, 38.0951], + 青岛: [120.4651, 36.3373], + 韶关: [113.7964, 24.7028], + } + + let BJData = [ + [{ name: '北京' }, { name: '上海', value: 95 }], + [{ name: '北京' }, { name: '广州', value: 90 }], + [{ name: '北京' }, { name: '大连', value: 80 }], + [{ name: '北京' }, { name: '南宁', value: 70 }], + [{ name: '北京' }, { name: '南昌', value: 60 }], + [{ name: '北京' }, { name: '拉萨', value: 50 }], + [{ name: '北京' }, { name: '长春', value: 40 }], + [{ name: '北京' }, { name: '包头', value: 30 }], + [{ name: '北京' }, { name: '重庆', value: 20 }], + [{ name: '北京' }, { name: '常州', value: 10 }], + ] + + let SHData = [ + [{ name: '上海' }, { name: '包头', value: 95 }], + [{ name: '上海' }, { name: '昆明', value: 90 }], + [{ name: '上海' }, { name: '广州', value: 80 }], + [{ name: '上海' }, { name: '郑州', value: 70 }], + [{ name: '上海' }, { name: '长春', value: 60 }], + [{ name: '上海' }, { name: '重庆', value: 50 }], + [{ name: '上海' }, { name: '长沙', value: 40 }], + [{ name: '上海' }, { name: '北京', value: 30 }], + [{ name: '上海' }, { name: '丹东', value: 20 }], + [{ name: '上海' }, { name: '大连', value: 10 }], + ] + + let GZData = [ + [{ name: '广州' }, { name: '福州', value: 95 }], + [{ name: '广州' }, { name: '太原', value: 90 }], + [{ name: '广州' }, { name: '长春', value: 80 }], + [{ name: '广州' }, { name: '重庆', value: 70 }], + [{ name: '广州' }, { name: '西安', value: 60 }], + [{ name: '广州' }, { name: '成都', value: 50 }], + [{ name: '广州' }, { name: '常州', value: 40 }], + [{ name: '广州' }, { name: '北京', value: 30 }], + [{ name: '广州' }, { name: '北海', value: 20 }], + [{ name: '广州' }, { name: '海口', value: 10 }], + ] + + let planePath = + 'path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z' + + let convertData = function(data) { + let res = [] + for (let i = 0; i < data.length; i += 1) { + let dataItem = data[i] + let fromCoord = geoCoordMap[dataItem[0].name] + let toCoord = geoCoordMap[dataItem[1].name] + if (fromCoord && toCoord) { + res.push({ + fromName: dataItem[0].name, + toName: dataItem[1].name, + coords: [fromCoord, toCoord], + }) + } + } + return res + } + + let color = ['#a6c84c', '#ffa022', '#46bee9'] + let series = [] + ;[['北京', BJData], ['上海', SHData], ['广州', GZData]].forEach((item, i) => { + series.push( + { + name: `${item[0]} Top10`, + type: 'lines', + zlevel: 1, + effect: { + show: true, + period: 6, + trailLength: 0.7, + color: '#fff', + symbolSize: 3, + }, + lineStyle: { + normal: { + color: color[i], + width: 0, + curveness: 0.2, + }, + }, + data: convertData(item[1]), + }, + { + name: `${item[0]} Top10`, + type: 'lines', + zlevel: 2, + symbol: ['none', 'arrow'], + symbolSize: 10, + effect: { + show: true, + period: 6, + trailLength: 0, + symbol: planePath, + symbolSize: 15, + }, + lineStyle: { + normal: { + color: color[i], + width: 1, + opacity: 0.6, + curveness: 0.2, + }, + }, + data: convertData(item[1]), + }, + { + name: `${item[0]} Top10`, + type: 'effectScatter', + coordinateSystem: 'geo', + zlevel: 2, + rippleEffect: { + brushType: 'stroke', + }, + label: { + normal: { + show: true, + position: 'right', + formatter: '{b}', + }, + }, + symbolSize(val) { + return val[2] / 8 + }, + itemStyle: { + normal: { + color: color[i], + }, + }, + data: item[1].map(dataItem => { + return { + name: dataItem[1].name, + value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value]), + } + }), + } + ) + }) + + let option = { + backgroundColor: '#404a59', + title: { + text: '模拟迁徙', + subtext: '数据纯属虚构', + left: 'center', + textStyle: { + color: '#fff', + }, + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + top: 'bottom', + left: 'right', + data: ['北京 Top10', '上海 Top10', '广州 Top10'], + textStyle: { + color: '#fff', + }, + selectedMode: 'single', + }, + geo: { + map: 'china', + label: { + emphasis: { + show: false, + }, + }, + roam: true, + itemStyle: { + normal: { + areaColor: '#323c48', + borderColor: '#404a59', + }, + emphasis: { + areaColor: '#2a333d', + }, + }, + }, + series, + } + + return ( +
+
+ + +
+
+ ) +} + +export default AirportCoordComponent diff --git a/src/pages/chart/ECharts/BubbleGradientComponent.js b/src/pages/chart/ECharts/BubbleGradientComponent.js new file mode 100644 index 0000000..813f8a2 --- /dev/null +++ b/src/pages/chart/ECharts/BubbleGradientComponent.js @@ -0,0 +1,165 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import * as echarts from 'echarts' + +const currentData = [ + [ + [28604, 77, 17096869, 'Australia', 1990], + [31163, 77.4, 27662440, 'Canada', 1990], + [1516, 68, 1154605773, 'China', 1990], + [13670, 74.7, 10582082, 'Cuba', 1990], + [28599, 75, 4986705, 'Finland', 1990], + [29476, 77.1, 56943299, 'France', 1990], + [31476, 75.4, 78958237, 'Germany', 1990], + [28666, 78.1, 254830, 'Iceland', 1990], + [1777, 57.7, 870601776, 'India', 1990], + [29550, 79.1, 122249285, 'Japan', 1990], + [2076, 67.9, 20194354, 'North Korea', 1990], + [12087, 72, 42972254, 'South Korea', 1990], + [24021, 75.4, 3397534, 'New Zealand', 1990], + [43296, 76.8, 4240375, 'Norway', 1990], + [10088, 70.8, 38195258, 'Poland', 1990], + [19349, 69.6, 147568552, 'Russia', 1990], + [10670, 67.3, 53994605, 'Turkey', 1990], + [26424, 75.7, 57110117, 'United Kingdom', 1990], + [37062, 75.4, 252847810, 'United States', 1990], + ], + [ + [44056, 81.8, 23968973, 'Australia', 2015], + [43294, 81.7, 35939927, 'Canada', 2015], + [13334, 76.9, 1376048943, 'China', 2015], + [21291, 78.5, 11389562, 'Cuba', 2015], + [38923, 80.8, 5503457, 'Finland', 2015], + [37599, 81.9, 64395345, 'France', 2015], + [44053, 81.1, 80688545, 'Germany', 2015], + [42182, 82.8, 329425, 'Iceland', 2015], + [5903, 66.8, 1311050527, 'India', 2015], + [36162, 83.5, 126573481, 'Japan', 2015], + [1390, 71.4, 25155317, 'North Korea', 2015], + [34644, 80.7, 50293439, 'South Korea', 2015], + [34186, 80.6, 4528526, 'New Zealand', 2015], + [64304, 81.6, 5210967, 'Norway', 2015], + [24787, 77.3, 38611794, 'Poland', 2015], + [23038, 73.13, 143456918, 'Russia', 2015], + [19360, 76.5, 78665830, 'Turkey', 2015], + [38225, 81.4, 64715810, 'United Kingdom', 2015], + [53354, 79.1, 321773631, 'United States', 2015], + ], +] + +const option = { + backgroundColor: new echarts.graphic.RadialGradient(0.3, 0.3, 0.8, [ + { + offset: 0, + color: '#f7f8fa', + }, + { + offset: 1, + color: '#cdd0d5', + }, + ]), + title: { + text: '1990 与 2015 年各国家人均寿命与 GDP', + }, + legend: { + right: 10, + data: ['1990', '2015'], + }, + xAxis: { + splitLine: { + lineStyle: { + type: 'dashed', + }, + }, + }, + yAxis: { + splitLine: { + lineStyle: { + type: 'dashed', + }, + }, + scale: true, + }, + series: [ + { + name: '1990', + data: currentData[0], + type: 'scatter', + symbolSize(data) { + return Math.sqrt(data[2]) / 5e2 + }, + label: { + emphasis: { + show: true, + formatter(param) { + return param.data[3] + }, + position: 'top', + }, + }, + itemStyle: { + normal: { + shadowBlur: 10, + shadowColor: 'rgba(120, 36, 50, 0.5)', + shadowOffsetY: 5, + color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [ + { + offset: 0, + color: 'rgb(251, 118, 123)', + }, + { + offset: 1, + color: 'rgb(204, 46, 72)', + }, + ]), + }, + }, + }, + { + name: '2015', + data: currentData[1], + type: 'scatter', + symbolSize(data) { + return Math.sqrt(data[2]) / 5e2 + }, + label: { + emphasis: { + show: true, + formatter(param) { + return param.data[3] + }, + position: 'top', + }, + }, + itemStyle: { + normal: { + shadowBlur: 10, + shadowColor: 'rgba(25, 100, 150, 0.5)', + shadowOffsetY: 5, + color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [ + { + offset: 0, + color: 'rgb(129, 227, 238)', + }, + { + offset: 1, + color: 'rgb(25, 183, 207)', + }, + ]), + }, + }, + }, + ], +} + +const BubbleGradientComponent = () => { + return ( + + ) +} + +export default BubbleGradientComponent diff --git a/src/pages/chart/ECharts/CalendarComponent.js b/src/pages/chart/ECharts/CalendarComponent.js new file mode 100644 index 0000000..79dd50c --- /dev/null +++ b/src/pages/chart/ECharts/CalendarComponent.js @@ -0,0 +1,193 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import * as echarts from 'echarts' + +const CalendarComponent = () => { + const getVirtulData = year => { + year = year || '2017' + let date = +echarts.number.parseDate(`${year}-01-01`) + let end = +echarts.number.parseDate(`${+year + 1}-01-01`) + let dayTime = 3600 * 24 * 1000 + let data = [] + for (let time = date; time < end; time += dayTime) { + data.push([ + echarts.format.formatTime('yyyy-MM-dd', time), + Math.floor(Math.random() * 1000), + ]) + } + return data + } + + let graphData = [ + [1485878400000, 260], + [1486137600000, 200], + [1486569600000, 279], + [1486915200000, 847], + [1487347200000, 241], + [1487779200000, 411], + [1488124800000, 985], + ] + + let links = graphData.map((item, idx) => { + return { + source: idx, + target: idx + 1, + } + }) + links.pop() + + const option = { + tooltip: { + position: 'top', + }, + visualMap: [ + { + min: 0, + max: 1000, + calculable: true, + seriesIndex: [2, 3, 4], + orient: 'horizontal', + left: '55%', + bottom: 20, + }, + { + min: 0, + max: 1000, + inRange: { + color: ['grey'], + opacity: [0, 0.3], + }, + controller: { + inRange: { + opacity: [0.3, 0.6], + }, + outOfRange: { + color: '#ccc', + }, + }, + calculable: true, + seriesIndex: [1], + orient: 'horizontal', + left: '10%', + bottom: 20, + }, + ], + + calendar: [ + { + orient: 'vertical', + yearLabel: { + margin: 40, + }, + monthLabel: { + nameMap: 'cn', + margin: 20, + }, + dayLabel: { + firstDay: 1, + nameMap: 'cn', + }, + cellSize: 40, + range: '2017-02', + }, + { + orient: 'vertical', + yearLabel: { + margin: 40, + }, + monthLabel: { + margin: 20, + }, + cellSize: 40, + left: 460, + range: '2017-01', + }, + { + orient: 'vertical', + yearLabel: { + margin: 40, + }, + monthLabel: { + margin: 20, + }, + cellSize: 40, + top: 350, + range: '2017-03', + }, + { + orient: 'vertical', + yearLabel: { + margin: 40, + }, + dayLabel: { + firstDay: 1, + nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], + }, + monthLabel: { + nameMap: 'cn', + margin: 20, + }, + cellSize: 40, + top: 350, + left: 460, + range: '2017-04', + }, + ], + + series: [ + { + type: 'graph', + edgeSymbol: ['none', 'arrow'], + coordinateSystem: 'calendar', + links, + symbolSize: 10, + calendarIndex: 0, + data: graphData, + }, + { + type: 'heatmap', + coordinateSystem: 'calendar', + data: getVirtulData(2017), + }, + { + type: 'effectScatter', + coordinateSystem: 'calendar', + calendarIndex: 1, + symbolSize(val) { + return val[1] / 40 + }, + data: getVirtulData(2017), + }, + { + type: 'scatter', + coordinateSystem: 'calendar', + calendarIndex: 2, + symbolSize(val) { + return val[1] / 60 + }, + data: getVirtulData(2017), + }, + { + type: 'heatmap', + coordinateSystem: 'calendar', + calendarIndex: 3, + data: getVirtulData(2017), + }, + ], + } + + return ( +
+
+ + +
+
+ ) +} + +export default CalendarComponent diff --git a/src/pages/chart/ECharts/ChartAPIComponent.js b/src/pages/chart/ECharts/ChartAPIComponent.js new file mode 100644 index 0000000..35b97f7 --- /dev/null +++ b/src/pages/chart/ECharts/ChartAPIComponent.js @@ -0,0 +1,130 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +class ChartAPIComponent extends React.Component { + render() { + const option = { + title: { + text: '漏斗图', + subtext: '纯属虚构', + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c}%', + }, + toolbox: { + feature: { + dataView: { readOnly: false }, + restore: {}, + saveAsImage: {}, + }, + }, + legend: { + data: ['展现', '点击', '访问', '咨询', '订单'], + }, + series: [ + { + name: '预期', + type: 'funnel', + left: '10%', + width: '80%', + label: { + normal: { + formatter: '{b}预期', + }, + emphasis: { + position: 'inside', + formatter: '{b}预期: {c}%', + }, + }, + labelLine: { + normal: { + show: false, + }, + }, + itemStyle: { + normal: { + opacity: 0.7, + }, + }, + data: [ + { value: 60, name: '访问' }, + { value: 40, name: '咨询' }, + { value: 20, name: '订单' }, + { value: 80, name: '点击' }, + { value: 100, name: '展现' }, + ], + }, + { + name: '实际', + type: 'funnel', + left: '10%', + width: '80%', + maxSize: '80%', + label: { + normal: { + position: 'inside', + formatter: '{c}%', + textStyle: { + color: '#fff', + }, + }, + emphasis: { + position: 'inside', + formatter: '{b}实际: {c}%', + }, + }, + itemStyle: { + normal: { + opacity: 0.5, + borderColor: '#fff', + borderWidth: 2, + }, + }, + data: [ + { value: 30, name: '访问' }, + { value: 10, name: '咨询' }, + { value: 5, name: '订单' }, + { value: 50, name: '点击' }, + { value: 80, name: '展现' }, + ], + }, + ], + } + + let code = + ' { this.echarts_react = e; }} \n' + + ' option={this.getOtion()} /> \n' + + '\n' + + '// use echarts API: http://echarts.baidu.com/api.html#echartsInstance' + + 'this.echarts_react.getEchartsInstance().getDataURL();' + return ( +
+
+ + { + this.echarts_react = e + }} + option={option} + /> + +
+            {code}
+          
+
+
+ ) + } +} + +export default ChartAPIComponent diff --git a/src/pages/chart/ECharts/ChartShowLoadingComponent.js b/src/pages/chart/ECharts/ChartShowLoadingComponent.js new file mode 100644 index 0000000..26a83fd --- /dev/null +++ b/src/pages/chart/ECharts/ChartShowLoadingComponent.js @@ -0,0 +1,104 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +class ChartShowLoadingComponent extends React.Component { + constructor() { + super() + this._t = null + this.onChartReady = this.onChartReady.bind(this) + } + componentWillUnmount() { + clearTimeout(this._t) + } + + onChartReady(chart) { + this._t = setTimeout(() => { + chart.hideLoading() + }, 3000) + } + + render() { + const getOtion = () => { + const option = { + title: { + text: '基础雷达图', + }, + tooltip: {}, + legend: { + data: ['预算分配(Allocated Budget)', '实际开销(Actual Spending)'], + }, + radar: { + indicator: [ + { name: '销售(sales)', max: 6500 }, + { name: '管理(Administration)', max: 16000 }, + { name: '信息技术(Information Techology)', max: 30000 }, + { name: '客服(Customer Support)', max: 38000 }, + { name: '研发(Development)', max: 52000 }, + { name: '市场(Marketing)', max: 25000 }, + ], + }, + series: [ + { + name: '预算 vs 开销(Budget vs spending)', + type: 'radar', + data: [ + { + value: [4300, 10000, 28000, 35000, 50000, 19000], + name: '预算分配(Allocated Budget)', + }, + { + value: [5000, 14000, 28000, 31000, 42000, 21000], + name: '实际开销(Actual Spending)', + }, + ], + }, + ], + } + return option + } + const getLoadingOption = () => { + const option = { + text: '加载中...', + color: '#4413c2', + textColor: '#270240', + maskColor: 'rgba(194, 88, 86, 0.3)', + zlevel: 0, + } + return option + } + + let code = + 'onChartReady: function(chart) {\n' + + " 'chart.hideLoading();\n" + + '}\n\n' + + '' + + return ( +
+
+ + + +
+            {code}
+          
+
+
+ ) + } +} + +export default ChartShowLoadingComponent diff --git a/src/pages/chart/ECharts/ChartWithEventComponent.js b/src/pages/chart/ECharts/ChartWithEventComponent.js new file mode 100644 index 0000000..7103a01 --- /dev/null +++ b/src/pages/chart/ECharts/ChartWithEventComponent.js @@ -0,0 +1,95 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +const ChartWithEventComponent = () => { + const onChartReady = echart => { + /* eslint-disable */ + console.log('echart is ready', echart) + } + const onChartLegendselectchanged = (param, echart) => { + console.log(param, echart) + } + const onChartClick = (param, echart) => { + console.log(param, echart) + } + const getOtion = () => { + const option = { + title: { + text: '某站点用户访问来源', + subtext: '纯属虚构', + x: 'center', + }, + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c} ({d}%)', + }, + legend: { + orient: 'vertical', + left: 'left', + data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'], + }, + series: [ + { + name: '访问来源', + type: 'pie', + radius: '55%', + center: ['50%', '60%'], + data: [ + { value: 335, name: '直接访问' }, + { value: 310, name: '邮件营销' }, + { value: 234, name: '联盟广告' }, + { value: 135, name: '视频广告' }, + { value: 1548, name: '搜索引擎' }, + ], + itemStyle: { + emphasis: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)', + }, + }, + }, + ], + } + return option + } + + let onEvents = { + click: onChartClick, + legendselectchanged: onChartLegendselectchanged, + } + let code = + 'let onEvents = {\n' + + " 'click': onChartClick,\n" + + " 'legendselectchanged': onChartLegendselectchanged\n" + + '}\n\n' + + '' + + return ( +
+
+ + + +
+          {code}
+        
+
+
+ ) +} + +export default ChartWithEventComponent diff --git a/src/pages/chart/ECharts/DynamicChartComponent.js b/src/pages/chart/ECharts/DynamicChartComponent.js new file mode 100644 index 0000000..cce8296 --- /dev/null +++ b/src/pages/chart/ECharts/DynamicChartComponent.js @@ -0,0 +1,217 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +class DynamicChartComponent extends React.Component { + constructor(props) { + super(props) + this.timeTicket = null + this.count = 51 + + const option = { + title: { + text: 'Hello Echarts-for-react.', + }, + tooltip: { + trigger: 'axis', + }, + legend: { + data: ['最新成交价', '预购队列'], + }, + toolbox: { + show: true, + feature: { + dataView: { readOnly: false }, + restore: {}, + saveAsImage: {}, + }, + }, + grid: { + top: 60, + left: 30, + right: 60, + bottom: 30, + }, + dataZoom: { + show: false, + start: 0, + end: 100, + }, + visualMap: { + show: false, + min: 0, + max: 1000, + color: [ + '#BE002F', + '#F20C00', + '#F00056', + '#FF2D51', + '#FF2121', + '#FF4C00', + '#FF7500', + '#FF8936', + '#FFA400', + '#F0C239', + '#FFF143', + '#FAFF72', + '#C9DD22', + '#AFDD22', + '#9ED900', + '#00E500', + '#0EB83A', + '#0AA344', + '#0C8918', + '#057748', + '#177CB0', + ], + }, + xAxis: [ + { + type: 'category', + boundaryGap: true, + data: (function() { + let now = new Date() + let res = [] + let len = 50 + while (len--) { + res.unshift(now.toLocaleTimeString().replace(/^\D*/, '')) + now = new Date(now - 2000) + } + return res + })(), + }, + { + type: 'category', + boundaryGap: true, + data: (function() { + let res = [] + let len = 50 + while (len--) { + res.push(50 - len + 1) + } + return res + })(), + }, + ], + yAxis: [ + { + type: 'value', + scale: true, + name: '价格', + max: 20, + min: 0, + boundaryGap: [0.2, 0.2], + }, + { + type: 'value', + scale: true, + name: '预购量', + max: 1200, + min: 0, + boundaryGap: [0.2, 0.2], + }, + ], + series: [ + { + name: '预购队列', + type: 'bar', + xAxisIndex: 1, + yAxisIndex: 1, + itemStyle: { + normal: { + barBorderRadius: 4, + }, + }, + animationEasing: 'elasticOut', + animationDelay(idx) { + return idx * 10 + }, + animationDelayUpdate(idx) { + return idx * 10 + }, + data: (function() { + let res = [] + let len = 50 + while (len--) { + res.push(Math.round(Math.random() * 1000)) + } + return res + })(), + }, + { + name: '最新成交价', + type: 'line', + data: (function() { + let res = [] + let len = 0 + while (len < 50) { + res.push((Math.random() * 10 + 5).toFixed(1) - 0) + len++ + } + return res + })(), + }, + ], + } + + this.state = { + option, + } + + this.fetchNewDate = this.fetchNewDate.bind(this) + } + + fetchNewDate() { + let axisData = new Date().toLocaleTimeString().replace(/^\D*/, '') + let { option } = this.state + option.title.text = `Hello Echarts-for-react.${new Date().getSeconds()}` + let data0 = option.series[0].data + let data1 = option.series[1].data + data0.shift() + data0.push(Math.round(Math.random() * 1000)) + data1.shift() + data1.push((Math.random() * 10 + 5).toFixed(1) - 0) + + option.xAxis[0].data.shift() + option.xAxis[0].data.push(axisData) + option.xAxis[1].data.shift() + option.xAxis[1].data.push((this.count += 1)) + this.setState({ option }) + } + + componentDidMount() { + if (this.timeTicket) { + clearInterval(this.timeTicket) + } + this.timeTicket = setInterval(this.fetchNewDate, 1000) + } + + componentWillUnmount() { + if (this.timeTicket) { + clearInterval(this.timeTicket) + } + } + + render() { + let code = + "\n' + return ( +
+
+ + + +
+            {code}
+          
+
+
+ ) + } +} + +export default DynamicChartComponent diff --git a/src/pages/chart/ECharts/EchartsComponent.js b/src/pages/chart/ECharts/EchartsComponent.js new file mode 100644 index 0000000..b2fa38e --- /dev/null +++ b/src/pages/chart/ECharts/EchartsComponent.js @@ -0,0 +1,49 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import SimpleChartComponent from './SimpleChartComponent' +import ChartWithEventComponent from './ChartWithEventComponent' +import ThemeChartComponent from './ThemeChartComponent' +import ChartShowLoadingComponent from './ChartShowLoadingComponent' +import ChartAPIComponent from './ChartAPIComponent' +import DynamicChartComponent from './DynamicChartComponent' +import MapChartComponent from './MapChartComponent' + +// v1.2.0 add 7 demo. +import AirportCoordComponent from './AirportCoordComponent' +import CalendarComponent from './CalendarComponent' +import GaugeComponent from './GaugeComponent' +import GCalendarComponent from './GCalendarComponent' +import GraphComponent from './GraphComponent' +import LunarCalendarComponent from './LunarCalendarComponent' +import TreemapComponent from './TreemapComponent' +import LiquidfillComponent from './LiquidfillComponent' +import BubbleGradientComponent from './BubbleGradientComponent' +import TransparentBar3DComPonent from './TransparentBar3DComPonent' + +const EchartsComponent = ({ type }) => { + if (type === 'simple') return + if (type === 'loading') return + if (type === 'api') return + if (type === 'events') return + if (type === 'theme') return + if (type === 'dynamic') return + if (type === 'map') return + if (type === 'airport') return + if (type === 'graph') return + if (type === 'calendar') return + if (type === 'treemap') return + if (type === 'gauge') return + if (type === 'gcalendar') return + if (type === 'lunar') return + if (type === 'liquid') return + if (type === 'BubbleGradientComponent') return + if (type === 'TransparentBar3DComPonent') return + return +} + +EchartsComponent.propTypes = { + type: PropTypes.string, +} + +export default EchartsComponent diff --git a/src/pages/chart/ECharts/GCalendarComponent.js b/src/pages/chart/ECharts/GCalendarComponent.js new file mode 100644 index 0000000..da81e14 --- /dev/null +++ b/src/pages/chart/ECharts/GCalendarComponent.js @@ -0,0 +1,76 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import * as echarts from 'echarts' + +const GCalendarComponent = () => { + const getVirtulData = year => { + year = year || '2017' + let date = +echarts.number.parseDate(`${year}-01-01`) + let end = +echarts.number.parseDate(`${+year + 1}-01-01`) + let dayTime = 3600 * 24 * 1000 + let data = [] + for (let time = date; time < end; time += dayTime) { + data.push([ + echarts.format.formatTime('yyyy-MM-dd', time), + Math.floor(Math.random() * 1000), + ]) + } + return data + } + + const option = { + tooltip: { + position: 'top', + }, + visualMap: { + min: 0, + max: 1000, + calculable: true, + orient: 'horizontal', + left: 'center', + top: 'top', + }, + + calendar: [ + { + range: '2017', + cellSize: ['auto', 20], + }, + { + top: 260, + range: '2016', + cellSize: ['auto', 20], + }, + ], + + series: [ + { + type: 'heatmap', + coordinateSystem: 'calendar', + calendarIndex: 0, + data: getVirtulData(2017), + }, + { + type: 'heatmap', + coordinateSystem: 'calendar', + calendarIndex: 1, + data: getVirtulData(2016), + }, + ], + } + + return ( +
+
+ + +
+
+ ) +} + +export default GCalendarComponent diff --git a/src/pages/chart/ECharts/GaugeComponent.js b/src/pages/chart/ECharts/GaugeComponent.js new file mode 100644 index 0000000..665908b --- /dev/null +++ b/src/pages/chart/ECharts/GaugeComponent.js @@ -0,0 +1,370 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +class GaugeComponent extends React.Component { + constructor() { + super() + const option = { + backgroundColor: '#1b1b1b', + tooltip: { + formatter: '{a}
{c} {b}', + }, + toolbox: { + show: true, + feature: { + mark: { show: true }, + restore: { show: true }, + saveAsImage: { show: true }, + }, + }, + series: [ + { + name: '速度', + type: 'gauge', + min: 0, + max: 220, + splitNumber: 11, + radius: '50%', + axisLine: { + // 坐标轴线 + lineStyle: { + // 属性lineStyle控制线条样式 + color: [[0.09, 'lime'], [0.82, '#1e90ff'], [1, '#ff4500']], + width: 3, + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisLabel: { + // 坐标轴小标记 + textStyle: { + // 属性lineStyle控制线条样式 + fontWeight: 'bolder', + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisTick: { + // 坐标轴小标记 + length: 15, // 属性length控制线长 + lineStyle: { + // 属性lineStyle控制线条样式 + color: 'auto', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + splitLine: { + // 分隔线 + length: 25, // 属性length控制线长 + lineStyle: { + // 属性lineStyle(详见lineStyle)控制线条样式 + width: 3, + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + pointer: { + // 分隔线 + shadowColor: '#fff', // 默认透明 + shadowBlur: 5, + }, + title: { + textStyle: { + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder', + fontSize: 20, + fontStyle: 'italic', + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + detail: { + backgroundColor: 'rgba(30,144,255,0.8)', + borderWidth: 1, + borderColor: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 5, + offsetCenter: [0, '50%'], // x, y,单位px + textStyle: { + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder', + color: '#fff', + }, + }, + data: [{ value: 40, name: 'km/h' }], + }, + { + name: '转速', + type: 'gauge', + center: ['25%', '55%'], // 默认全局居中 + radius: '30%', + min: 0, + max: 7, + endAngle: 45, + splitNumber: 7, + axisLine: { + // 坐标轴线 + lineStyle: { + // 属性lineStyle控制线条样式 + color: [[0.29, 'lime'], [0.86, '#1e90ff'], [1, '#ff4500']], + width: 2, + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisLabel: { + // 坐标轴小标记 + textStyle: { + // 属性lineStyle控制线条样式 + fontWeight: 'bolder', + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisTick: { + // 坐标轴小标记 + length: 12, // 属性length控制线长 + lineStyle: { + // 属性lineStyle控制线条样式 + color: 'auto', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + splitLine: { + // 分隔线 + length: 20, // 属性length控制线长 + lineStyle: { + // 属性lineStyle(详见lineStyle)控制线条样式 + width: 3, + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + pointer: { + width: 5, + shadowColor: '#fff', // 默认透明 + shadowBlur: 5, + }, + title: { + offsetCenter: [0, '-30%'], // x, y,单位px + textStyle: { + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder', + fontStyle: 'italic', + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + detail: { + // backgroundColor: 'rgba(30,144,255,0.8)', + // borderWidth: 1, + borderColor: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 5, + width: 80, + height: 30, + offsetCenter: [25, '20%'], // x, y,单位px + textStyle: { + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + fontWeight: 'bolder', + color: '#fff', + }, + }, + data: [{ value: 1.5, name: 'x1000 r/min' }], + }, + { + name: '油表', + type: 'gauge', + center: ['75%', '50%'], // 默认全局居中 + radius: '30%', + min: 0, + max: 2, + startAngle: 135, + endAngle: 45, + splitNumber: 2, + axisLine: { + // 坐标轴线 + lineStyle: { + // 属性lineStyle控制线条样式 + color: [[0.2, 'lime'], [0.8, '#1e90ff'], [1, '#ff4500']], + width: 2, + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisTick: { + // 坐标轴小标记 + length: 12, // 属性length控制线长 + lineStyle: { + // 属性lineStyle控制线条样式 + color: 'auto', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisLabel: { + textStyle: { + // 属性lineStyle控制线条样式 + fontWeight: 'bolder', + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + formatter(v) { + switch (`${v}`) { + case '0': + return 'E' + case '1': + return 'Gas' + case '2': + return 'F' + default: + return null + } + }, + }, + splitLine: { + // 分隔线 + length: 15, // 属性length控制线长 + lineStyle: { + // 属性lineStyle(详见lineStyle)控制线条样式 + width: 3, + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + pointer: { + width: 2, + shadowColor: '#fff', // 默认透明 + shadowBlur: 5, + }, + title: { + show: false, + }, + detail: { + show: false, + }, + data: [{ value: 0.5, name: 'gas' }], + }, + { + name: '水表', + type: 'gauge', + center: ['75%', '50%'], // 默认全局居中 + radius: '30%', + min: 0, + max: 2, + startAngle: 315, + endAngle: 225, + splitNumber: 2, + axisLine: { + // 坐标轴线 + lineStyle: { + // 属性lineStyle控制线条样式 + color: [[0.2, 'lime'], [0.8, '#1e90ff'], [1, '#ff4500']], + width: 2, + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + axisTick: { + // 坐标轴小标记 + show: false, + }, + axisLabel: { + textStyle: { + // 属性lineStyle控制线条样式 + fontWeight: 'bolder', + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + formatter(v) { + switch (`${v}`) { + case '0': + return 'H' + case '1': + return 'Water' + case '2': + return 'C' + default: + return null + } + }, + }, + splitLine: { + // 分隔线 + length: 15, // 属性length控制线长 + lineStyle: { + // 属性lineStyle(详见lineStyle)控制线条样式 + width: 3, + color: '#fff', + shadowColor: '#fff', // 默认透明 + shadowBlur: 10, + }, + }, + pointer: { + width: 2, + shadowColor: '#fff', // 默认透明 + shadowBlur: 5, + }, + title: { + show: false, + }, + detail: { + show: false, + }, + data: [{ value: 0.5, name: 'gas' }], + }, + ], + } + this.state = { + option, + } + } + + componentDidMount() { + if (this.timeTicket) { + clearInterval(this.timeTicket) + } + this.timeTicket = setInterval(() => { + let { option } = this.state + option.series[0].data[0].value = (Math.random() * 100).toFixed(2) - 0 + option.series[1].data[0].value = (Math.random() * 7).toFixed(2) - 0 + option.series[2].data[0].value = (Math.random() * 2).toFixed(2) - 0 + option.series[3].data[0].value = (Math.random() * 2).toFixed(2) - 0 + this.setState({ option }) + }, 1000) + } + + componentWillUnmount() { + if (this.timeTicket) { + clearInterval(this.timeTicket) + } + } + + render() { + return ( +
+
+ + +
+
+ ) + } +} + +export default GaugeComponent diff --git a/src/pages/chart/ECharts/GraphComponent.js b/src/pages/chart/ECharts/GraphComponent.js new file mode 100644 index 0000000..1621cd8 --- /dev/null +++ b/src/pages/chart/ECharts/GraphComponent.js @@ -0,0 +1,1365 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +const GraphComponent = () => { + const getOtion = () => { + const webkitDep = { + type: 'force', + categories: [ + { name: 'HTMLElement', keyword: {}, base: 'HTMLElement' }, + { name: 'WebGL', keyword: {}, base: 'WebGLRenderingContext' }, + { name: 'SVG', keyword: {}, base: 'SVGElement' }, + { name: 'CSS', keyword: {}, base: 'CSSRule' }, + { name: 'Other', keyword: {} }, + ], + nodes: [ + { name: 'AnalyserNode', value: 1, category: 4 }, + { name: 'AudioNode', value: 1, category: 4 }, + { name: 'Uint8Array', value: 1, category: 4 }, + { name: 'Float32Array', value: 1, category: 4 }, + { name: 'ArrayBuffer', value: 1, category: 4 }, + { name: 'ArrayBufferView', value: 1, category: 4 }, + { name: 'Attr', value: 1, category: 4 }, + { name: 'Node', value: 1, category: 4 }, + { name: 'Element', value: 1, category: 4 }, + { name: 'AudioBuffer', value: 1, category: 4 }, + { name: 'AudioBufferCallback', value: 1, category: 4 }, + { name: 'AudioBufferSourceNode', value: 1, category: 4 }, + { name: 'AudioSourceNode', value: 1, category: 4 }, + { name: 'AudioGain', value: 1, category: 4 }, + { name: 'AudioParam', value: 1, category: 4 }, + { name: 'AudioContext', value: 1, category: 4 }, + { name: 'AudioDestinationNode', value: 1, category: 4 }, + { name: 'AudioListener', value: 1, category: 4 }, + { name: 'BiquadFilterNode', value: 1, category: 4 }, + { name: 'ChannelMergerNode', value: 1, category: 4 }, + { name: 'ChannelSplitterNode', value: 1, category: 4 }, + { name: 'ConvolverNode', value: 1, category: 4 }, + { name: 'DelayNode', value: 1, category: 4 }, + { name: 'DynamicsCompressorNode', value: 1, category: 4 }, + { name: 'GainNode', value: 1, category: 4 }, + { name: 'MediaElementAudioSourceNode', value: 1, category: 4 }, + { name: 'MediaStreamAudioDestinationNode', value: 1, category: 4 }, + { name: 'MediaStreamAudioSourceNode', value: 1, category: 4 }, + { name: 'OscillatorNode', value: 1, category: 4 }, + { name: 'PannerNode', value: 1, category: 4 }, + { name: 'ScriptProcessorNode', value: 1, category: 4 }, + { name: 'WaveShaperNode', value: 1, category: 4 }, + { name: 'WaveTable', value: 1, category: 4 }, + { name: 'CanvasRenderingContext', value: 1, category: 4 }, + { name: 'HTMLCanvasElement', value: 1, category: 0 }, + { name: 'CanvasRenderingContext2D', value: 1, category: 4 }, + { name: 'ImageData', value: 1, category: 4 }, + { name: 'CanvasGradient', value: 1, category: 4 }, + { name: 'CanvasPattern', value: 1, category: 4 }, + { name: 'HTMLImageElement', value: 1, category: 0 }, + { name: 'HTMLVideoElement', value: 1, category: 0 }, + { name: 'TextMetrics', value: 1, category: 4 }, + { name: 'CDATASection', value: 1, category: 4 }, + { name: 'Text', value: 1, category: 4 }, + { name: 'CharacterData', value: 1, category: 4 }, + { name: 'ClientRectList', value: 1, category: 4 }, + { name: 'ClientRect', value: 1, category: 4 }, + { name: 'Clipboard', value: 1, category: 4 }, + { name: 'FileList', value: 1, category: 4 }, + { name: 'DataTransferItemList', value: 1, category: 4 }, + { name: 'Comment', value: 1, category: 4 }, + { name: 'Console', value: 1, category: 4 }, + { name: 'MemoryInfo', value: 1, category: 4 }, + { name: 'Crypto', value: 1, category: 4 }, + { name: 'CSSCharsetRule', value: 1, category: 3 }, + { name: 'CSSRule', value: 3, category: 3 }, + { name: 'CSSFontFaceRule', value: 1, category: 3 }, + { name: 'CSSStyleDeclaration', value: 1, category: 3 }, + { name: 'CSSImportRule', value: 1, category: 3 }, + { name: 'MediaList', value: 1, category: 4 }, + { name: 'CSSStyleSheet', value: 1, category: 3 }, + { name: 'CSSMediaRule', value: 1, category: 3 }, + { name: 'CSSRuleList', value: 1, category: 3 }, + { name: 'CSSPageRule', value: 1, category: 3 }, + { name: 'CSSPrimitiveValue', value: 1, category: 3 }, + { name: 'CSSValue', value: 1, category: 3 }, + { name: 'Counter', value: 1, category: 4 }, + { name: 'RGBColor', value: 1, category: 4 }, + { name: 'Rect', value: 1, category: 4 }, + { name: 'CSSStyleRule', value: 1, category: 3 }, + { name: 'StyleSheet', value: 1, category: 4 }, + { name: 'CSSUnknownRule', value: 1, category: 3 }, + { name: 'CSSValueList', value: 1, category: 3 }, + { name: 'Database', value: 1, category: 4 }, + { name: 'SQLTransactionCallback', value: 1, category: 4 }, + { name: 'DatabaseCallback', value: 1, category: 4 }, + { name: 'DatabaseSync', value: 1, category: 4 }, + { name: 'SQLTransactionSyncCallback', value: 1, category: 4 }, + { name: 'DataTransferItem', value: 1, category: 4 }, + { name: 'StringCallback', value: 1, category: 4 }, + { name: 'Entry', value: 1, category: 4 }, + { name: 'File', value: 1, category: 4 }, + { name: 'DataView', value: 1, category: 4 }, + { name: 'DedicatedWorkerContext', value: 1, category: 4 }, + { name: 'WorkerContext', value: 1, category: 4 }, + { name: 'DirectoryEntry', value: 1, category: 4 }, + { name: 'DirectoryReader', value: 1, category: 4 }, + { name: 'VoidCallback', value: 1, category: 4 }, + { name: 'DirectoryEntrySync', value: 1, category: 4 }, + { name: 'EntrySync', value: 1, category: 4 }, + { name: 'DirectoryReaderSync', value: 1, category: 4 }, + { name: 'FileEntrySync', value: 1, category: 4 }, + { name: 'EntriesCallback', value: 1, category: 4 }, + { name: 'EntryArraySync', value: 1, category: 4 }, + { name: 'DocumentFragment', value: 1, category: 4 }, + { name: 'NodeList', value: 1, category: 4 }, + { name: 'DocumentType', value: 1, category: 4 }, + { name: 'NamedNodeMap', value: 1, category: 4 }, + { name: 'DOMFileSystem', value: 1, category: 4 }, + { name: 'DOMFileSystemSync', value: 1, category: 4 }, + { name: 'DOMImplementation', value: 1, category: 4 }, + { name: 'HTMLDocument', value: 1, category: 0 }, + { name: 'DOMMimeType', value: 1, category: 4 }, + { name: 'DOMPlugin', value: 1, category: 4 }, + { name: 'DOMMimeTypeArray', value: 1, category: 4 }, + { name: 'DOMPluginArray', value: 1, category: 4 }, + { name: 'DOMSelection', value: 1, category: 4 }, + { name: 'Range', value: 1, category: 4 }, + { name: 'DOMSettableTokenList', value: 1, category: 4 }, + { name: 'DOMTokenList', value: 1, category: 4 }, + { name: 'DOMStringMap', value: 1, category: 4 }, + { name: 'ShadowRoot', value: 1, category: 4 }, + { name: 'Entity', value: 1, category: 4 }, + { name: 'EntityReference', value: 1, category: 4 }, + { name: 'EntryArray', value: 1, category: 4 }, + { name: 'MetadataCallback', value: 1, category: 4 }, + { name: 'EntryCallback', value: 1, category: 4 }, + { name: 'Metadata', value: 1, category: 4 }, + { name: 'ErrorCallback', value: 1, category: 4 }, + { name: 'FileError', value: 1, category: 4 }, + { name: 'FileCallback', value: 1, category: 4 }, + { name: 'FileEntry', value: 1, category: 4 }, + { name: 'FileWriterCallback', value: 1, category: 4 }, + { name: 'FileWriterSync', value: 1, category: 4 }, + { name: 'FileReader', value: 1, category: 4 }, + { name: 'FileReaderSync', value: 1, category: 4 }, + { name: 'FileSystemCallback', value: 1, category: 4 }, + { name: 'FileWriter', value: 1, category: 4 }, + { name: 'Float64Array', value: 1, category: 4 }, + { name: 'GamepadList', value: 1, category: 4 }, + { name: 'Gamepad', value: 1, category: 4 }, + { name: 'Geolocation', value: 1, category: 4 }, + { name: 'PositionCallback', value: 1, category: 4 }, + { name: 'Geoposition', value: 1, category: 4 }, + { name: 'Coordinates', value: 1, category: 4 }, + { name: 'HTMLAllCollection', value: 1, category: 0 }, + { name: 'HTMLAnchorElement', value: 1, category: 0 }, + { name: 'HTMLElement', value: 3, category: 0 }, + { name: 'HTMLAppletElement', value: 1, category: 0 }, + { name: 'HTMLAreaElement', value: 1, category: 0 }, + { name: 'HTMLAudioElement', value: 1, category: 0 }, + { name: 'HTMLMediaElement', value: 1, category: 0 }, + { name: 'HTMLBaseElement', value: 1, category: 0 }, + { name: 'HTMLBaseFontElement', value: 1, category: 0 }, + { name: 'HTMLBodyElement', value: 1, category: 0 }, + { name: 'HTMLBRElement', value: 1, category: 0 }, + { name: 'HTMLButtonElement', value: 1, category: 0 }, + { name: 'HTMLFormElement', value: 1, category: 0 }, + { name: 'ValidityState', value: 1, category: 4 }, + { name: 'HTMLCollection', value: 1, category: 0 }, + { name: 'HTMLContentElement', value: 1, category: 0 }, + { name: 'HTMLDataListElement', value: 1, category: 0 }, + { name: 'HTMLDetailsElement', value: 1, category: 0 }, + { name: 'HTMLDirectoryElement', value: 1, category: 0 }, + { name: 'HTMLDivElement', value: 1, category: 0 }, + { name: 'HTMLDListElement', value: 1, category: 0 }, + { name: 'HTMLEmbedElement', value: 1, category: 0 }, + { name: 'SVGDocument', value: 1, category: 2 }, + { name: 'HTMLFieldSetElement', value: 1, category: 0 }, + { name: 'HTMLFontElement', value: 1, category: 0 }, + { name: 'HTMLFormControlsCollection', value: 1, category: 0 }, + { name: 'HTMLFrameElement', value: 1, category: 0 }, + { name: 'HTMLFrameSetElement', value: 1, category: 0 }, + { name: 'HTMLHeadElement', value: 1, category: 0 }, + { name: 'HTMLHeadingElement', value: 1, category: 0 }, + { name: 'HTMLHRElement', value: 1, category: 0 }, + { name: 'HTMLHtmlElement', value: 1, category: 0 }, + { name: 'HTMLIFrameElement', value: 1, category: 0 }, + { name: 'HTMLInputElement', value: 1, category: 0 }, + { name: 'HTMLKeygenElement', value: 1, category: 0 }, + { name: 'HTMLLabelElement', value: 1, category: 0 }, + { name: 'HTMLLegendElement', value: 1, category: 0 }, + { name: 'HTMLLIElement', value: 1, category: 0 }, + { name: 'HTMLLinkElement', value: 1, category: 0 }, + { name: 'HTMLMapElement', value: 1, category: 0 }, + { name: 'HTMLMarqueeElement', value: 1, category: 0 }, + { name: 'TimeRanges', value: 1, category: 4 }, + { name: 'MediaController', value: 1, category: 4 }, + { name: 'MediaError', value: 1, category: 4 }, + { name: 'TextTrackList', value: 1, category: 4 }, + { name: 'TextTrack', value: 1, category: 4 }, + { name: 'HTMLMenuElement', value: 1, category: 0 }, + { name: 'HTMLMetaElement', value: 1, category: 0 }, + { name: 'HTMLMeterElement', value: 1, category: 0 }, + { name: 'HTMLModElement', value: 1, category: 0 }, + { name: 'HTMLObjectElement', value: 1, category: 0 }, + { name: 'HTMLOListElement', value: 1, category: 0 }, + { name: 'HTMLOptGroupElement', value: 1, category: 0 }, + { name: 'HTMLOptionElement', value: 1, category: 0 }, + { name: 'HTMLOptionsCollection', value: 1, category: 0 }, + { name: 'HTMLOutputElement', value: 1, category: 0 }, + { name: 'HTMLParagraphElement', value: 1, category: 0 }, + { name: 'HTMLParamElement', value: 1, category: 0 }, + { name: 'HTMLPreElement', value: 1, category: 0 }, + { name: 'HTMLProgressElement', value: 1, category: 0 }, + { name: 'HTMLQuoteElement', value: 1, category: 0 }, + { name: 'HTMLScriptElement', value: 1, category: 0 }, + { name: 'HTMLSelectElement', value: 1, category: 0 }, + { name: 'HTMLShadowElement', value: 1, category: 0 }, + { name: 'HTMLSourceElement', value: 1, category: 0 }, + { name: 'HTMLSpanElement', value: 1, category: 0 }, + { name: 'HTMLStyleElement', value: 1, category: 0 }, + { name: 'HTMLTableCaptionElement', value: 1, category: 0 }, + { name: 'HTMLTableCellElement', value: 1, category: 0 }, + { name: 'HTMLTableColElement', value: 1, category: 0 }, + { name: 'HTMLTableElement', value: 1, category: 0 }, + { name: 'HTMLTableSectionElement', value: 1, category: 0 }, + { name: 'HTMLTableRowElement', value: 1, category: 0 }, + { name: 'HTMLTextAreaElement', value: 1, category: 0 }, + { name: 'HTMLTitleElement', value: 1, category: 0 }, + { name: 'HTMLTrackElement', value: 1, category: 0 }, + { name: 'HTMLUListElement', value: 1, category: 0 }, + { name: 'HTMLUnknownElement', value: 1, category: 0 }, + { name: 'IDBCursor', value: 1, category: 4 }, + { name: 'IDBAny', value: 1, category: 4 }, + { name: 'IDBKey', value: 1, category: 4 }, + { name: 'IDBRequest', value: 1, category: 4 }, + { name: 'IDBCursorWithValue', value: 1, category: 4 }, + { name: 'IDBDatabase', value: 1, category: 4 }, + { name: 'DOMStringList', value: 1, category: 4 }, + { name: 'IDBObjectStore', value: 1, category: 4 }, + { name: 'IDBTransaction', value: 1, category: 4 }, + { name: 'IDBFactory', value: 1, category: 4 }, + { name: 'IDBVersionChangeRequest', value: 1, category: 4 }, + { name: 'IDBOpenDBRequest', value: 1, category: 4 }, + { name: 'IDBIndex', value: 1, category: 4 }, + { name: 'IDBKeyRange', value: 1, category: 4 }, + { name: 'DOMError', value: 1, category: 4 }, + { name: 'Int16Array', value: 1, category: 4 }, + { name: 'Int32Array', value: 1, category: 4 }, + { name: 'Int8Array', value: 1, category: 4 }, + { name: 'JavaScriptCallFrame', value: 1, category: 4 }, + { name: 'LocalMediaStream', value: 1, category: 4 }, + { name: 'MediaStream', value: 1, category: 4 }, + { name: 'Location', value: 1, category: 4 }, + { name: 'MediaQueryList', value: 1, category: 4 }, + { name: 'MediaQueryListListener', value: 1, category: 4 }, + { name: 'MediaSource', value: 1, category: 4 }, + { name: 'SourceBufferList', value: 1, category: 4 }, + { name: 'SourceBuffer', value: 1, category: 4 }, + { name: 'MediaStreamTrackList', value: 1, category: 4 }, + { name: 'MediaStreamList', value: 1, category: 4 }, + { name: 'MediaStreamTrack', value: 1, category: 4 }, + { name: 'MessageChannel', value: 1, category: 4 }, + { name: 'MessagePort', value: 1, category: 4 }, + { name: 'MutationObserver', value: 1, category: 4 }, + { name: 'MutationRecord', value: 1, category: 4 }, + { name: 'Navigator', value: 1, category: 4 }, + { name: 'BatteryManager', value: 1, category: 4 }, + { name: 'NavigatorUserMediaErrorCallback', value: 1, category: 4 }, + { name: 'NavigatorUserMediaError', value: 1, category: 4 }, + { name: 'NavigatorUserMediaSuccessCallback', value: 1, category: 4 }, + { name: 'NodeFilter', value: 1, category: 4 }, + { name: 'NodeIterator', value: 1, category: 4 }, + { name: 'Notation', value: 1, category: 4 }, + { name: 'Notification', value: 1, category: 4 }, + { name: 'NotificationPermissionCallback', value: 1, category: 4 }, + { name: 'NotificationCenter', value: 1, category: 4 }, + { name: 'OESVertexArrayObject', value: 1, category: 4 }, + { name: 'WebGLVertexArrayObjectOES', value: 1, category: 1 }, + { name: 'Performance', value: 1, category: 4 }, + { name: 'PerformanceNavigation', value: 1, category: 4 }, + { name: 'PerformanceTiming', value: 1, category: 4 }, + { name: 'PositionErrorCallback', value: 1, category: 4 }, + { name: 'PositionError', value: 1, category: 4 }, + { name: 'ProcessingInstruction', value: 1, category: 4 }, + { name: 'RadioNodeList', value: 1, category: 4 }, + { name: 'RTCDataChannel', value: 1, category: 4 }, + { name: 'RTCPeerConnection', value: 1, category: 4 }, + { name: 'RTCSessionDescription', value: 1, category: 4 }, + { name: 'RTCIceCandidate', value: 1, category: 4 }, + { name: 'RTCSessionDescriptionCallback', value: 1, category: 4 }, + { name: 'RTCStatsCallback', value: 1, category: 4 }, + { name: 'RTCStatsResponse', value: 1, category: 4 }, + { name: 'RTCStatsReport', value: 1, category: 4 }, + { name: 'RTCStatsElement', value: 1, category: 4 }, + { name: 'ScriptProfile', value: 1, category: 4 }, + { name: 'ScriptProfileNode', value: 1, category: 4 }, + { name: 'SharedWorker', value: 1, category: 4 }, + { name: 'AbstractWorker', value: 1, category: 4 }, + { name: 'SharedWorkerContext', value: 1, category: 4 }, + { name: 'SpeechGrammarList', value: 1, category: 4 }, + { name: 'SpeechGrammar', value: 1, category: 4 }, + { name: 'SpeechInputResultList', value: 1, category: 4 }, + { name: 'SpeechInputResult', value: 1, category: 4 }, + { name: 'SpeechRecognition', value: 1, category: 4 }, + { name: 'SpeechRecognitionResult', value: 1, category: 4 }, + { name: 'SpeechRecognitionAlternative', value: 1, category: 4 }, + { name: 'SpeechRecognitionResultList', value: 1, category: 4 }, + { name: 'SQLResultSet', value: 1, category: 4 }, + { name: 'SQLResultSetRowList', value: 1, category: 4 }, + { name: 'SQLStatementCallback', value: 1, category: 4 }, + { name: 'SQLTransaction', value: 1, category: 4 }, + { name: 'SQLStatementErrorCallback', value: 1, category: 4 }, + { name: 'SQLTransactionErrorCallback', value: 1, category: 4 }, + { name: 'SQLError', value: 1, category: 4 }, + { name: 'SQLTransactionSync', value: 1, category: 4 }, + { name: 'StorageInfo', value: 1, category: 4 }, + { name: 'StorageInfoUsageCallback', value: 1, category: 4 }, + { name: 'StorageInfoQuotaCallback', value: 1, category: 4 }, + { name: 'StorageInfoErrorCallback', value: 1, category: 4 }, + { name: 'DOMCoreException', value: 1, category: 4 }, + { name: 'StyleSheetList', value: 1, category: 4 }, + { name: 'SVGAElement', value: 1, category: 2 }, + { name: 'SVGTransformable', value: 1, category: 2 }, + { name: 'SVGAnimatedString', value: 1, category: 2 }, + { name: 'SVGAltGlyphDefElement', value: 1, category: 2 }, + { name: 'SVGElement', value: 3, category: 2 }, + { name: 'SVGAltGlyphElement', value: 1, category: 2 }, + { name: 'SVGURIReference', value: 1, category: 2 }, + { name: 'SVGAltGlyphItemElement', value: 1, category: 2 }, + { name: 'SVGAnimateColorElement', value: 1, category: 2 }, + { name: 'SVGAnimationElement', value: 1, category: 2 }, + { name: 'SVGAnimatedAngle', value: 1, category: 2 }, + { name: 'SVGAngle', value: 1, category: 2 }, + { name: 'SVGAnimatedLength', value: 1, category: 2 }, + { name: 'SVGLength', value: 1, category: 2 }, + { name: 'SVGAnimatedLengthList', value: 1, category: 2 }, + { name: 'SVGLengthList', value: 1, category: 2 }, + { name: 'SVGAnimatedNumberList', value: 1, category: 2 }, + { name: 'SVGNumberList', value: 1, category: 2 }, + { name: 'SVGAnimatedPreserveAspectRatio', value: 1, category: 2 }, + { name: 'SVGPreserveAspectRatio', value: 1, category: 2 }, + { name: 'SVGAnimatedRect', value: 1, category: 2 }, + { name: 'SVGRect', value: 1, category: 2 }, + { name: 'SVGAnimatedTransformList', value: 1, category: 2 }, + { name: 'SVGTransformList', value: 1, category: 2 }, + { name: 'SVGAnimateElement', value: 1, category: 2 }, + { name: 'SVGAnimateMotionElement', value: 1, category: 2 }, + { name: 'SVGAnimateTransformElement', value: 1, category: 2 }, + { name: 'ElementTimeControl', value: 1, category: 4 }, + { name: 'SVGCircleElement', value: 1, category: 2 }, + { name: 'SVGClipPathElement', value: 1, category: 2 }, + { name: 'SVGAnimatedEnumeration', value: 1, category: 2 }, + { name: 'SVGColor', value: 1, category: 2 }, + { name: 'SVGComponentTransferFunctionElement', value: 1, category: 2 }, + { name: 'SVGAnimatedNumber', value: 1, category: 2 }, + { name: 'SVGCursorElement', value: 1, category: 2 }, + { name: 'SVGExternalResourcesRequired', value: 1, category: 2 }, + { name: 'SVGDefsElement', value: 1, category: 2 }, + { name: 'SVGDescElement', value: 1, category: 2 }, + { name: 'SVGStylable', value: 1, category: 2 }, + { name: 'SVGSVGElement', value: 1, category: 2 }, + { name: 'SVGElementInstance', value: 1, category: 2 }, + { name: 'EventTarget', value: 1, category: 4 }, + { name: 'SVGElementInstanceList', value: 1, category: 2 }, + { name: 'SVGUseElement', value: 1, category: 2 }, + { name: 'SVGEllipseElement', value: 1, category: 2 }, + { name: 'SVGAnimatedBoolean', value: 1, category: 2 }, + { name: 'SVGFEBlendElement', value: 1, category: 2 }, + { name: 'SVGFilterPrimitiveStandardAttributes', value: 1, category: 2 }, + { name: 'SVGFEColorMatrixElement', value: 1, category: 2 }, + { name: 'SVGFEComponentTransferElement', value: 1, category: 2 }, + { name: 'SVGFECompositeElement', value: 1, category: 2 }, + { name: 'SVGFEConvolveMatrixElement', value: 1, category: 2 }, + { name: 'SVGAnimatedInteger', value: 1, category: 2 }, + { name: 'SVGFEDiffuseLightingElement', value: 1, category: 2 }, + { name: 'SVGFEDisplacementMapElement', value: 1, category: 2 }, + { name: 'SVGFEDistantLightElement', value: 1, category: 2 }, + { name: 'SVGFEDropShadowElement', value: 1, category: 2 }, + { name: 'SVGFEFloodElement', value: 1, category: 2 }, + { name: 'SVGFEFuncAElement', value: 1, category: 2 }, + { name: 'SVGFEFuncBElement', value: 1, category: 2 }, + { name: 'SVGFEFuncGElement', value: 1, category: 2 }, + { name: 'SVGFEFuncRElement', value: 1, category: 2 }, + { name: 'SVGFEGaussianBlurElement', value: 1, category: 2 }, + { name: 'SVGFEImageElement', value: 1, category: 2 }, + { name: 'SVGFEMergeElement', value: 1, category: 2 }, + { name: 'SVGFEMergeNodeElement', value: 1, category: 2 }, + { name: 'SVGFEMorphologyElement', value: 1, category: 2 }, + { name: 'SVGFEOffsetElement', value: 1, category: 2 }, + { name: 'SVGFEPointLightElement', value: 1, category: 2 }, + { name: 'SVGFESpecularLightingElement', value: 1, category: 2 }, + { name: 'SVGFESpotLightElement', value: 1, category: 2 }, + { name: 'SVGFETileElement', value: 1, category: 2 }, + { name: 'SVGFETurbulenceElement', value: 1, category: 2 }, + { name: 'SVGFilterElement', value: 1, category: 2 }, + { name: 'SVGFitToViewBox', value: 1, category: 2 }, + { name: 'SVGFontElement', value: 1, category: 2 }, + { name: 'SVGFontFaceElement', value: 1, category: 2 }, + { name: 'SVGFontFaceFormatElement', value: 1, category: 2 }, + { name: 'SVGFontFaceNameElement', value: 1, category: 2 }, + { name: 'SVGFontFaceSrcElement', value: 1, category: 2 }, + { name: 'SVGFontFaceUriElement', value: 1, category: 2 }, + { name: 'SVGForeignObjectElement', value: 1, category: 2 }, + { name: 'SVGGElement', value: 1, category: 2 }, + { name: 'SVGGlyphElement', value: 1, category: 2 }, + { name: 'SVGGlyphRefElement', value: 1, category: 2 }, + { name: 'SVGGradientElement', value: 1, category: 2 }, + { name: 'SVGHKernElement', value: 1, category: 2 }, + { name: 'SVGImageElement', value: 1, category: 2 }, + { name: 'SVGLinearGradientElement', value: 1, category: 2 }, + { name: 'SVGLineElement', value: 1, category: 2 }, + { name: 'SVGLocatable', value: 1, category: 2 }, + { name: 'SVGMatrix', value: 1, category: 2 }, + { name: 'SVGMarkerElement', value: 1, category: 2 }, + { name: 'SVGMaskElement', value: 1, category: 2 }, + { name: 'SVGMetadataElement', value: 1, category: 2 }, + { name: 'SVGMissingGlyphElement', value: 1, category: 2 }, + { name: 'SVGMPathElement', value: 1, category: 2 }, + { name: 'SVGNumber', value: 1, category: 2 }, + { name: 'SVGPaint', value: 1, category: 2 }, + { name: 'SVGPathElement', value: 1, category: 2 }, + { name: 'SVGPathSegList', value: 1, category: 2 }, + { name: 'SVGPathSegArcAbs', value: 1, category: 2 }, + { name: 'SVGPathSegArcRel', value: 1, category: 2 }, + { name: 'SVGPathSegClosePath', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoCubicAbs', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoCubicRel', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoCubicSmoothAbs', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoCubicSmoothRel', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoQuadraticAbs', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoQuadraticRel', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoQuadraticSmoothAbs', value: 1, category: 2 }, + { name: 'SVGPathSegCurvetoQuadraticSmoothRel', value: 1, category: 2 }, + { name: 'SVGPathSegLinetoAbs', value: 1, category: 2 }, + { name: 'SVGPathSegLinetoHorizontalAbs', value: 1, category: 2 }, + { name: 'SVGPathSegLinetoHorizontalRel', value: 1, category: 2 }, + { name: 'SVGPathSegLinetoRel', value: 1, category: 2 }, + { name: 'SVGPathSegLinetoVerticalAbs', value: 1, category: 2 }, + { name: 'SVGPathSegLinetoVerticalRel', value: 1, category: 2 }, + { name: 'SVGPathSegMovetoAbs', value: 1, category: 2 }, + { name: 'SVGPathSegMovetoRel', value: 1, category: 2 }, + { name: 'SVGPoint', value: 1, category: 2 }, + { name: 'SVGPathSeg', value: 1, category: 2 }, + { name: 'SVGPatternElement', value: 1, category: 2 }, + { name: 'SVGPointList', value: 1, category: 2 }, + { name: 'SVGPolygonElement', value: 1, category: 2 }, + { name: 'SVGPolylineElement', value: 1, category: 2 }, + { name: 'SVGRadialGradientElement', value: 1, category: 2 }, + { name: 'SVGRectElement', value: 1, category: 2 }, + { name: 'SVGScriptElement', value: 1, category: 2 }, + { name: 'SVGSetElement', value: 1, category: 2 }, + { name: 'SVGStopElement', value: 1, category: 2 }, + { name: 'SVGStyleElement', value: 1, category: 2 }, + { name: 'SVGLangSpace', value: 1, category: 2 }, + { name: 'SVGZoomAndPan', value: 1, category: 2 }, + { name: 'SVGViewSpec', value: 1, category: 2 }, + { name: 'SVGTransform', value: 1, category: 2 }, + { name: 'SVGSwitchElement', value: 1, category: 2 }, + { name: 'SVGSymbolElement', value: 1, category: 2 }, + { name: 'SVGTests', value: 1, category: 2 }, + { name: 'SVGStringList', value: 1, category: 2 }, + { name: 'SVGTextContentElement', value: 1, category: 2 }, + { name: 'SVGTextElement', value: 1, category: 2 }, + { name: 'SVGTextPathElement', value: 1, category: 2 }, + { name: 'SVGTextPositioningElement', value: 1, category: 2 }, + { name: 'SVGTitleElement', value: 1, category: 2 }, + { name: 'SVGTRefElement', value: 1, category: 2 }, + { name: 'SVGTSpanElement', value: 1, category: 2 }, + { name: 'SVGViewElement', value: 1, category: 2 }, + { name: 'SVGVKernElement', value: 1, category: 2 }, + { name: 'TextTrackCueList', value: 1, category: 4 }, + { name: 'TextTrackCue', value: 1, category: 4 }, + { name: 'Touch', value: 1, category: 4 }, + { name: 'TouchList', value: 1, category: 4 }, + { name: 'TreeWalker', value: 1, category: 4 }, + { name: 'Uint16Array', value: 1, category: 4 }, + { name: 'Uint32Array', value: 1, category: 4 }, + { name: 'Uint8ClampedArray', value: 1, category: 4 }, + { name: 'WebGLRenderingContext', value: 3, category: 1 }, + { name: 'WebGLProgram', value: 1, category: 1 }, + { name: 'WebGLBuffer', value: 1, category: 1 }, + { name: 'WebGLFramebuffer', value: 1, category: 1 }, + { name: 'WebGLRenderbuffer', value: 1, category: 1 }, + { name: 'WebGLTexture', value: 1, category: 1 }, + { name: 'WebGLShader', value: 1, category: 1 }, + { name: 'WebGLActiveInfo', value: 1, category: 1 }, + { name: 'WebGLContextAttributes', value: 1, category: 1 }, + { name: 'WebGLShaderPrecisionFormat', value: 1, category: 1 }, + { name: 'WebGLUniformLocation', value: 1, category: 1 }, + { name: 'WebKitAnimationList', value: 1, category: 4 }, + { name: 'WebKitAnimation', value: 1, category: 4 }, + { name: 'WebKitCSSFilterValue', value: 1, category: 4 }, + { name: 'WebKitCSSKeyframeRule', value: 1, category: 4 }, + { name: 'WebKitCSSKeyframesRule', value: 1, category: 4 }, + { name: 'WebKitCSSMatrix', value: 1, category: 4 }, + { name: 'WebKitCSSMixFunctionValue', value: 1, category: 4 }, + { name: 'WebKitCSSTransformValue', value: 1, category: 4 }, + { name: 'WebKitNamedFlow', value: 1, category: 4 }, + { name: 'WebSocket', value: 1, category: 4 }, + { name: 'Worker', value: 1, category: 4 }, + { name: 'WorkerLocation', value: 1, category: 4 }, + { name: 'WorkerNavigator', value: 1, category: 4 }, + { name: 'XMLHttpRequest', value: 1, category: 4 }, + { name: 'XMLHttpRequestUpload', value: 1, category: 4 }, + { name: 'DOMFormData', value: 1, category: 4 }, + { name: 'XPathEvaluator', value: 1, category: 4 }, + { name: 'XPathExpression', value: 1, category: 4 }, + { name: 'XPathNSResolver', value: 1, category: 4 }, + { name: 'XPathResult', value: 1, category: 4 }, + { name: 'XSLTProcessor', value: 1, category: 4 }, + ], + links: [ + { source: 0, target: 1 }, + { source: 0, target: 2 }, + { source: 0, target: 3 }, + { source: 4, target: 4 }, + { source: 5, target: 4 }, + { source: 6, target: 7 }, + { source: 6, target: 8 }, + { source: 9, target: 3 }, + { source: 10, target: 9 }, + { source: 11, target: 12 }, + { source: 11, target: 9 }, + { source: 11, target: 13 }, + { source: 11, target: 14 }, + { source: 15, target: 16 }, + { source: 15, target: 17 }, + { source: 15, target: 0 }, + { source: 15, target: 18 }, + { source: 15, target: 9 }, + { source: 15, target: 11 }, + { source: 15, target: 19 }, + { source: 15, target: 20 }, + { source: 15, target: 21 }, + { source: 15, target: 22 }, + { source: 15, target: 23 }, + { source: 15, target: 24 }, + { source: 15, target: 25 }, + { source: 15, target: 26 }, + { source: 15, target: 27 }, + { source: 15, target: 28 }, + { source: 15, target: 29 }, + { source: 15, target: 30 }, + { source: 15, target: 31 }, + { source: 15, target: 32 }, + { source: 15, target: 4 }, + { source: 16, target: 1 }, + { source: 13, target: 14 }, + { source: 1, target: 15 }, + { source: 1, target: 1 }, + { source: 1, target: 14 }, + { source: 14, target: 3 }, + { source: 12, target: 1 }, + { source: 18, target: 1 }, + { source: 18, target: 14 }, + { source: 18, target: 3 }, + { source: 33, target: 34 }, + { source: 35, target: 33 }, + { source: 35, target: 36 }, + { source: 35, target: 37 }, + { source: 35, target: 38 }, + { source: 35, target: 39 }, + { source: 35, target: 34 }, + { source: 35, target: 40 }, + { source: 35, target: 41 }, + { source: 42, target: 43 }, + { source: 19, target: 1 }, + { source: 20, target: 1 }, + { source: 44, target: 7 }, + { source: 45, target: 46 }, + { source: 47, target: 48 }, + { source: 47, target: 49 }, + { source: 47, target: 39 }, + { source: 50, target: 44 }, + { source: 51, target: 52 }, + { source: 21, target: 1 }, + { source: 21, target: 9 }, + { source: 53, target: 5 }, + { source: 54, target: 55 }, + { source: 56, target: 55 }, + { source: 56, target: 57 }, + { source: 58, target: 55 }, + { source: 58, target: 59 }, + { source: 58, target: 60 }, + { source: 61, target: 55 }, + { source: 61, target: 62 }, + { source: 61, target: 59 }, + { source: 63, target: 55 }, + { source: 63, target: 57 }, + { source: 64, target: 65 }, + { source: 64, target: 66 }, + { source: 64, target: 67 }, + { source: 64, target: 68 }, + { source: 55, target: 55 }, + { source: 55, target: 60 }, + { source: 62, target: 55 }, + { source: 57, target: 55 }, + { source: 57, target: 65 }, + { source: 69, target: 55 }, + { source: 69, target: 57 }, + { source: 60, target: 70 }, + { source: 60, target: 62 }, + { source: 60, target: 55 }, + { source: 71, target: 55 }, + { source: 72, target: 65 }, + { source: 73, target: 74 }, + { source: 75, target: 73 }, + { source: 75, target: 76 }, + { source: 76, target: 77 }, + { source: 78, target: 79 }, + { source: 78, target: 80 }, + { source: 49, target: 81 }, + { source: 49, target: 78 }, + { source: 82, target: 5 }, + { source: 83, target: 84 }, + { source: 22, target: 1 }, + { source: 22, target: 14 }, + { source: 85, target: 80 }, + { source: 85, target: 86 }, + { source: 85, target: 87 }, + { source: 88, target: 89 }, + { source: 88, target: 90 }, + { source: 88, target: 88 }, + { source: 88, target: 91 }, + { source: 86, target: 92 }, + { source: 90, target: 93 }, + { source: 94, target: 7 }, + { source: 94, target: 8 }, + { source: 94, target: 95 }, + { source: 96, target: 7 }, + { source: 96, target: 97 }, + { source: 98, target: 85 }, + { source: 99, target: 88 }, + { source: 100, target: 60 }, + { source: 100, target: 96 }, + { source: 100, target: 101 }, + { source: 102, target: 103 }, + { source: 104, target: 102 }, + { source: 103, target: 102 }, + { source: 105, target: 103 }, + { source: 106, target: 7 }, + { source: 106, target: 107 }, + { source: 108, target: 109 }, + { source: 23, target: 1 }, + { source: 23, target: 14 }, + { source: 8, target: 7 }, + { source: 8, target: 109 }, + { source: 8, target: 110 }, + { source: 8, target: 8 }, + { source: 8, target: 57 }, + { source: 8, target: 6 }, + { source: 8, target: 46 }, + { source: 8, target: 45 }, + { source: 8, target: 95 }, + { source: 8, target: 111 }, + { source: 112, target: 7 }, + { source: 113, target: 7 }, + { source: 92, target: 114 }, + { source: 80, target: 98 }, + { source: 80, target: 85 }, + { source: 80, target: 115 }, + { source: 80, target: 116 }, + { source: 80, target: 87 }, + { source: 114, target: 80 }, + { source: 93, target: 89 }, + { source: 116, target: 80 }, + { source: 89, target: 99 }, + { source: 89, target: 89 }, + { source: 89, target: 117 }, + { source: 89, target: 88 }, + { source: 118, target: 119 }, + { source: 120, target: 81 }, + { source: 121, target: 80 }, + { source: 121, target: 122 }, + { source: 121, target: 120 }, + { source: 91, target: 89 }, + { source: 91, target: 123 }, + { source: 91, target: 81 }, + { source: 48, target: 81 }, + { source: 124, target: 119 }, + { source: 125, target: 4 }, + { source: 126, target: 98 }, + { source: 127, target: 119 }, + { source: 122, target: 127 }, + { source: 3, target: 5 }, + { source: 3, target: 3 }, + { source: 128, target: 5 }, + { source: 128, target: 128 }, + { source: 24, target: 1 }, + { source: 24, target: 13 }, + { source: 129, target: 130 }, + { source: 131, target: 132 }, + { source: 133, target: 134 }, + { source: 135, target: 7 }, + { source: 135, target: 95 }, + { source: 136, target: 137 }, + { source: 138, target: 137 }, + { source: 139, target: 137 }, + { source: 140, target: 141 }, + { source: 142, target: 137 }, + { source: 143, target: 137 }, + { source: 144, target: 137 }, + { source: 145, target: 137 }, + { source: 146, target: 137 }, + { source: 146, target: 147 }, + { source: 146, target: 95 }, + { source: 146, target: 148 }, + { source: 34, target: 137 }, + { source: 149, target: 7 }, + { source: 150, target: 137 }, + { source: 150, target: 95 }, + { source: 151, target: 137 }, + { source: 151, target: 149 }, + { source: 152, target: 137 }, + { source: 153, target: 137 }, + { source: 154, target: 137 }, + { source: 155, target: 137 }, + { source: 101, target: 8 }, + { source: 101, target: 135 }, + { source: 101, target: 149 }, + { source: 137, target: 8 }, + { source: 137, target: 149 }, + { source: 156, target: 137 }, + { source: 156, target: 157 }, + { source: 158, target: 137 }, + { source: 158, target: 149 }, + { source: 158, target: 147 }, + { source: 158, target: 148 }, + { source: 159, target: 137 }, + { source: 160, target: 149 }, + { source: 160, target: 7 }, + { source: 147, target: 137 }, + { source: 147, target: 149 }, + { source: 161, target: 137 }, + { source: 161, target: 157 }, + { source: 162, target: 137 }, + { source: 163, target: 137 }, + { source: 164, target: 137 }, + { source: 165, target: 137 }, + { source: 166, target: 137 }, + { source: 167, target: 137 }, + { source: 167, target: 157 }, + { source: 39, target: 137 }, + { source: 168, target: 137 }, + { source: 168, target: 48 }, + { source: 168, target: 147 }, + { source: 168, target: 95 }, + { source: 168, target: 148 }, + { source: 168, target: 114 }, + { source: 169, target: 137 }, + { source: 169, target: 147 }, + { source: 169, target: 95 }, + { source: 169, target: 148 }, + { source: 170, target: 137 }, + { source: 170, target: 147 }, + { source: 171, target: 137 }, + { source: 171, target: 147 }, + { source: 172, target: 137 }, + { source: 173, target: 137 }, + { source: 173, target: 70 }, + { source: 173, target: 108 }, + { source: 174, target: 137 }, + { source: 174, target: 149 }, + { source: 175, target: 137 }, + { source: 141, target: 137 }, + { source: 141, target: 176 }, + { source: 141, target: 177 }, + { source: 141, target: 178 }, + { source: 141, target: 179 }, + { source: 141, target: 180 }, + { source: 181, target: 137 }, + { source: 182, target: 137 }, + { source: 183, target: 137 }, + { source: 183, target: 95 }, + { source: 184, target: 137 }, + { source: 185, target: 137 }, + { source: 185, target: 147 }, + { source: 185, target: 148 }, + { source: 185, target: 157 }, + { source: 186, target: 137 }, + { source: 187, target: 137 }, + { source: 188, target: 137 }, + { source: 188, target: 147 }, + { source: 189, target: 149 }, + { source: 189, target: 188 }, + { source: 189, target: 7 }, + { source: 190, target: 137 }, + { source: 190, target: 147 }, + { source: 190, target: 108 }, + { source: 190, target: 95 }, + { source: 190, target: 148 }, + { source: 191, target: 137 }, + { source: 192, target: 137 }, + { source: 193, target: 137 }, + { source: 194, target: 137 }, + { source: 194, target: 95 }, + { source: 195, target: 137 }, + { source: 196, target: 137 }, + { source: 197, target: 137 }, + { source: 197, target: 147 }, + { source: 197, target: 95 }, + { source: 197, target: 189 }, + { source: 197, target: 149 }, + { source: 197, target: 148 }, + { source: 197, target: 7 }, + { source: 198, target: 137 }, + { source: 199, target: 137 }, + { source: 200, target: 137 }, + { source: 201, target: 137 }, + { source: 201, target: 70 }, + { source: 202, target: 137 }, + { source: 203, target: 137 }, + { source: 204, target: 137 }, + { source: 205, target: 137 }, + { source: 205, target: 202 }, + { source: 205, target: 149 }, + { source: 205, target: 206 }, + { source: 207, target: 137 }, + { source: 207, target: 149 }, + { source: 206, target: 137 }, + { source: 206, target: 149 }, + { source: 208, target: 137 }, + { source: 208, target: 147 }, + { source: 208, target: 95 }, + { source: 208, target: 148 }, + { source: 209, target: 137 }, + { source: 210, target: 137 }, + { source: 210, target: 180 }, + { source: 211, target: 137 }, + { source: 212, target: 137 }, + { source: 40, target: 141 }, + { source: 213, target: 214 }, + { source: 213, target: 215 }, + { source: 213, target: 216 }, + { source: 217, target: 213 }, + { source: 218, target: 219 }, + { source: 218, target: 214 }, + { source: 218, target: 220 }, + { source: 218, target: 221 }, + { source: 222, target: 215 }, + { source: 222, target: 223 }, + { source: 222, target: 224 }, + { source: 222, target: 216 }, + { source: 225, target: 214 }, + { source: 225, target: 220 }, + { source: 225, target: 216 }, + { source: 226, target: 215 }, + { source: 226, target: 226 }, + { source: 220, target: 219 }, + { source: 220, target: 214 }, + { source: 220, target: 221 }, + { source: 220, target: 216 }, + { source: 220, target: 225 }, + { source: 224, target: 216 }, + { source: 216, target: 227 }, + { source: 216, target: 214 }, + { source: 216, target: 221 }, + { source: 221, target: 218 }, + { source: 221, target: 227 }, + { source: 221, target: 220 }, + { source: 223, target: 216 }, + { source: 228, target: 5 }, + { source: 228, target: 228 }, + { source: 229, target: 5 }, + { source: 229, target: 229 }, + { source: 230, target: 5 }, + { source: 230, target: 230 }, + { source: 231, target: 231 }, + { source: 232, target: 233 }, + { source: 234, target: 219 }, + { source: 177, target: 176 }, + { source: 25, target: 12 }, + { source: 25, target: 141 }, + { source: 235, target: 236 }, + { source: 236, target: 235 }, + { source: 237, target: 238 }, + { source: 237, target: 239 }, + { source: 233, target: 240 }, + { source: 26, target: 12 }, + { source: 26, target: 233 }, + { source: 27, target: 12 }, + { source: 27, target: 233 }, + { source: 241, target: 233 }, + { source: 240, target: 242 }, + { source: 243, target: 244 }, + { source: 115, target: 117 }, + { source: 245, target: 7 }, + { source: 246, target: 95 }, + { source: 246, target: 7 }, + { source: 97, target: 7 }, + { source: 247, target: 131 }, + { source: 247, target: 104 }, + { source: 247, target: 105 }, + { source: 247, target: 248 }, + { source: 247, target: 129 }, + { source: 249, target: 250 }, + { source: 251, target: 232 }, + { source: 7, target: 97 }, + { source: 7, target: 95 }, + { source: 7, target: 7 }, + { source: 7, target: 8 }, + { source: 252, target: 7 }, + { source: 253, target: 252 }, + { source: 253, target: 7 }, + { source: 95, target: 7 }, + { source: 254, target: 7 }, + { source: 255, target: 256 }, + { source: 257, target: 255 }, + { source: 257, target: 87 }, + { source: 258, target: 259 }, + { source: 28, target: 12 }, + { source: 28, target: 14 }, + { source: 28, target: 32 }, + { source: 29, target: 1 }, + { source: 260, target: 52 }, + { source: 260, target: 261 }, + { source: 260, target: 262 }, + { source: 132, target: 133 }, + { source: 263, target: 264 }, + { source: 265, target: 7 }, + { source: 265, target: 70 }, + { source: 266, target: 95 }, + { source: 107, target: 7 }, + { source: 107, target: 94 }, + { source: 107, target: 107 }, + { source: 107, target: 46 }, + { source: 107, target: 45 }, + { source: 68, target: 64 }, + { source: 67, target: 64 }, + { source: 267, target: 4 }, + { source: 267, target: 5 }, + { source: 268, target: 269 }, + { source: 268, target: 241 }, + { source: 268, target: 270 }, + { source: 268, target: 233 }, + { source: 268, target: 271 }, + { source: 268, target: 267 }, + { source: 268, target: 272 }, + { source: 271, target: 269 }, + { source: 272, target: 273 }, + { source: 274, target: 275 }, + { source: 30, target: 1 }, + { source: 276, target: 277 }, + { source: 111, target: 94 }, + { source: 111, target: 8 }, + { source: 111, target: 7 }, + { source: 111, target: 95 }, + { source: 111, target: 106 }, + { source: 278, target: 279 }, + { source: 278, target: 244 }, + { source: 280, target: 84 }, + { source: 239, target: 176 }, + { source: 239, target: 2 }, + { source: 238, target: 239 }, + { source: 281, target: 282 }, + { source: 283, target: 284 }, + { source: 285, target: 281 }, + { source: 286, target: 287 }, + { source: 288, target: 286 }, + { source: 289, target: 290 }, + { source: 291, target: 292 }, + { source: 293, target: 292 }, + { source: 74, target: 292 }, + { source: 294, target: 295 }, + { source: 296, target: 289 }, + { source: 77, target: 296 }, + { source: 297, target: 298 }, + { source: 297, target: 299 }, + { source: 300, target: 301 }, + { source: 70, target: 59 }, + { source: 70, target: 7 }, + { source: 70, target: 70 }, + { source: 302, target: 70 }, + { source: 303, target: 304 }, + { source: 303, target: 305 }, + { source: 306, target: 307 }, + { source: 308, target: 309 }, + { source: 310, target: 307 }, + { source: 311, target: 312 }, + { source: 313, target: 314 }, + { source: 315, target: 316 }, + { source: 317, target: 318 }, + { source: 319, target: 320 }, + { source: 321, target: 322 }, + { source: 323, target: 324 }, + { source: 325, target: 326 }, + { source: 327, target: 312 }, + { source: 328, target: 312 }, + { source: 329, target: 312 }, + { source: 312, target: 330 }, + { source: 312, target: 307 }, + { source: 331, target: 304 }, + { source: 331, target: 315 }, + { source: 332, target: 304 }, + { source: 332, target: 333 }, + { source: 334, target: 65 }, + { source: 334, target: 67 }, + { source: 335, target: 307 }, + { source: 335, target: 336 }, + { source: 335, target: 319 }, + { source: 335, target: 333 }, + { source: 337, target: 338 }, + { source: 337, target: 315 }, + { source: 339, target: 304 }, + { source: 340, target: 341 }, + { source: 157, target: 342 }, + { source: 307, target: 8 }, + { source: 307, target: 342 }, + { source: 307, target: 307 }, + { source: 343, target: 344 }, + { source: 343, target: 345 }, + { source: 343, target: 307 }, + { source: 343, target: 346 }, + { source: 343, target: 343 }, + { source: 345, target: 343 }, + { source: 347, target: 304 }, + { source: 347, target: 315 }, + { source: 338, target: 348 }, + { source: 349, target: 350 }, + { source: 349, target: 305 }, + { source: 349, target: 333 }, + { source: 351, target: 350 }, + { source: 351, target: 305 }, + { source: 351, target: 333 }, + { source: 351, target: 319 }, + { source: 352, target: 350 }, + { source: 352, target: 305 }, + { source: 353, target: 350 }, + { source: 353, target: 305 }, + { source: 353, target: 336 }, + { source: 353, target: 333 }, + { source: 354, target: 350 }, + { source: 354, target: 336 }, + { source: 354, target: 333 }, + { source: 354, target: 305 }, + { source: 354, target: 319 }, + { source: 354, target: 355 }, + { source: 354, target: 348 }, + { source: 356, target: 350 }, + { source: 356, target: 336 }, + { source: 356, target: 305 }, + { source: 357, target: 350 }, + { source: 357, target: 305 }, + { source: 357, target: 336 }, + { source: 357, target: 333 }, + { source: 358, target: 307 }, + { source: 358, target: 336 }, + { source: 359, target: 350 }, + { source: 359, target: 336 }, + { source: 359, target: 305 }, + { source: 360, target: 350 }, + { source: 361, target: 335 }, + { source: 362, target: 335 }, + { source: 363, target: 335 }, + { source: 364, target: 335 }, + { source: 365, target: 350 }, + { source: 365, target: 305 }, + { source: 365, target: 336 }, + { source: 366, target: 350 }, + { source: 366, target: 321 }, + { source: 367, target: 350 }, + { source: 368, target: 307 }, + { source: 368, target: 305 }, + { source: 369, target: 350 }, + { source: 369, target: 305 }, + { source: 369, target: 333 }, + { source: 369, target: 336 }, + { source: 370, target: 350 }, + { source: 370, target: 336 }, + { source: 370, target: 305 }, + { source: 371, target: 307 }, + { source: 371, target: 336 }, + { source: 372, target: 350 }, + { source: 372, target: 305 }, + { source: 372, target: 336 }, + { source: 373, target: 307 }, + { source: 373, target: 336 }, + { source: 374, target: 350 }, + { source: 374, target: 305 }, + { source: 375, target: 350 }, + { source: 375, target: 336 }, + { source: 375, target: 355 }, + { source: 375, target: 333 }, + { source: 376, target: 341 }, + { source: 376, target: 355 }, + { source: 376, target: 333 }, + { source: 376, target: 315 }, + { source: 350, target: 341 }, + { source: 350, target: 315 }, + { source: 350, target: 305 }, + { source: 377, target: 321 }, + { source: 377, target: 323 }, + { source: 378, target: 307 }, + { source: 379, target: 307 }, + { source: 380, target: 307 }, + { source: 381, target: 307 }, + { source: 382, target: 307 }, + { source: 383, target: 307 }, + { source: 384, target: 304 }, + { source: 384, target: 315 }, + { source: 385, target: 304 }, + { source: 386, target: 307 }, + { source: 387, target: 341 }, + { source: 388, target: 341 }, + { source: 388, target: 325 }, + { source: 388, target: 333 }, + { source: 389, target: 307 }, + { source: 390, target: 304 }, + { source: 390, target: 315 }, + { source: 390, target: 321 }, + { source: 318, target: 316 }, + { source: 391, target: 388 }, + { source: 391, target: 315 }, + { source: 392, target: 304 }, + { source: 392, target: 315 }, + { source: 393, target: 307 }, + { source: 393, target: 324 }, + { source: 393, target: 394 }, + { source: 395, target: 377 }, + { source: 395, target: 315 }, + { source: 395, target: 333 }, + { source: 395, target: 313 }, + { source: 395, target: 314 }, + { source: 396, target: 341 }, + { source: 396, target: 315 }, + { source: 396, target: 333 }, + { source: 394, target: 394 }, + { source: 397, target: 307 }, + { source: 398, target: 307 }, + { source: 399, target: 338 }, + { source: 320, target: 400 }, + { source: 401, target: 334 }, + { source: 402, target: 304 }, + { source: 402, target: 403 }, + { source: 402, target: 336 }, + { source: 402, target: 404 }, + { source: 402, target: 405 }, + { source: 402, target: 406 }, + { source: 402, target: 407 }, + { source: 402, target: 408 }, + { source: 402, target: 409 }, + { source: 402, target: 410 }, + { source: 402, target: 411 }, + { source: 402, target: 412 }, + { source: 402, target: 413 }, + { source: 402, target: 414 }, + { source: 402, target: 415 }, + { source: 402, target: 416 }, + { source: 402, target: 417 }, + { source: 402, target: 418 }, + { source: 402, target: 419 }, + { source: 402, target: 420 }, + { source: 402, target: 421 }, + { source: 402, target: 422 }, + { source: 402, target: 423 }, + { source: 404, target: 424 }, + { source: 405, target: 424 }, + { source: 406, target: 424 }, + { source: 407, target: 424 }, + { source: 408, target: 424 }, + { source: 409, target: 424 }, + { source: 410, target: 424 }, + { source: 411, target: 424 }, + { source: 412, target: 424 }, + { source: 413, target: 424 }, + { source: 414, target: 424 }, + { source: 415, target: 424 }, + { source: 416, target: 424 }, + { source: 417, target: 424 }, + { source: 418, target: 424 }, + { source: 419, target: 424 }, + { source: 420, target: 424 }, + { source: 403, target: 424 }, + { source: 421, target: 424 }, + { source: 422, target: 424 }, + { source: 425, target: 377 }, + { source: 425, target: 315 }, + { source: 425, target: 333 }, + { source: 425, target: 325 }, + { source: 423, target: 423 }, + { source: 426, target: 423 }, + { source: 427, target: 304 }, + { source: 427, target: 426 }, + { source: 428, target: 304 }, + { source: 428, target: 426 }, + { source: 429, target: 388 }, + { source: 429, target: 315 }, + { source: 430, target: 304 }, + { source: 430, target: 315 }, + { source: 431, target: 338 }, + { source: 432, target: 312 }, + { source: 433, target: 341 }, + { source: 433, target: 336 }, + { source: 341, target: 305 }, + { source: 341, target: 57 }, + { source: 341, target: 65 }, + { source: 434, target: 435 }, + { source: 342, target: 436 }, + { source: 342, target: 423 }, + { source: 342, target: 437 }, + { source: 342, target: 315 }, + { source: 342, target: 324 }, + { source: 342, target: 307 }, + { source: 342, target: 314 }, + { source: 342, target: 316 }, + { source: 342, target: 394 }, + { source: 342, target: 400 }, + { source: 342, target: 438 }, + { source: 342, target: 8 }, + { source: 342, target: 95 }, + { source: 439, target: 304 }, + { source: 440, target: 377 }, + { source: 441, target: 442 }, + { source: 443, target: 341 }, + { source: 443, target: 333 }, + { source: 443, target: 315 }, + { source: 443, target: 423 }, + { source: 443, target: 324 }, + { source: 444, target: 304 }, + { source: 445, target: 309 }, + { source: 445, target: 333 }, + { source: 445, target: 315 }, + { source: 446, target: 443 }, + { source: 446, target: 317 }, + { source: 446, target: 319 }, + { source: 447, target: 341 }, + { source: 438, target: 394 }, + { source: 304, target: 393 }, + { source: 304, target: 325 }, + { source: 326, target: 438 }, + { source: 448, target: 309 }, + { source: 449, target: 446 }, + { source: 309, target: 305 }, + { source: 346, target: 304 }, + { source: 346, target: 343 }, + { source: 346, target: 315 }, + { source: 450, target: 436 }, + { source: 450, target: 442 }, + { source: 437, target: 321 }, + { source: 437, target: 326 }, + { source: 437, target: 323 }, + { source: 437, target: 307 }, + { source: 451, target: 307 }, + { source: 43, target: 44 }, + { source: 43, target: 43 }, + { source: 180, target: 452 }, + { source: 180, target: 453 }, + { source: 453, target: 180 }, + { source: 453, target: 94 }, + { source: 452, target: 453 }, + { source: 179, target: 180 }, + { source: 454, target: 344 }, + { source: 455, target: 454 }, + { source: 456, target: 7 }, + { source: 456, target: 252 }, + { source: 457, target: 5 }, + { source: 457, target: 457 }, + { source: 458, target: 5 }, + { source: 458, target: 458 }, + { source: 2, target: 5 }, + { source: 2, target: 2 }, + { source: 459, target: 2 }, + { source: 459, target: 459 }, + { source: 31, target: 1 }, + { source: 31, target: 3 }, + { source: 460, target: 33 }, + { source: 460, target: 461 }, + { source: 460, target: 462 }, + { source: 460, target: 463 }, + { source: 460, target: 464 }, + { source: 460, target: 465 }, + { source: 460, target: 4 }, + { source: 460, target: 5 }, + { source: 460, target: 466 }, + { source: 460, target: 467 }, + { source: 460, target: 468 }, + { source: 460, target: 469 }, + { source: 460, target: 470 }, + { source: 460, target: 36 }, + { source: 460, target: 39 }, + { source: 460, target: 34 }, + { source: 460, target: 40 }, + { source: 460, target: 3 }, + { source: 471, target: 472 }, + { source: 473, target: 72 }, + { source: 474, target: 55 }, + { source: 474, target: 57 }, + { source: 475, target: 55 }, + { source: 475, target: 62 }, + { source: 475, target: 474 }, + { source: 476, target: 476 }, + { source: 477, target: 72 }, + { source: 478, target: 72 }, + { source: 479, target: 95 }, + { source: 480, target: 4 }, + { source: 480, target: 5 }, + { source: 481, target: 279 }, + { source: 84, target: 222 }, + { source: 84, target: 482 }, + { source: 84, target: 483 }, + { source: 84, target: 84 }, + { source: 84, target: 257 }, + { source: 84, target: 73 }, + { source: 84, target: 76 }, + { source: 84, target: 126 }, + { source: 84, target: 99 }, + { source: 84, target: 89 }, + { source: 484, target: 485 }, + { source: 484, target: 4 }, + { source: 484, target: 5 }, + { source: 484, target: 486 }, + { source: 487, target: 488 }, + { source: 487, target: 489 }, + { source: 487, target: 490 }, + { source: 488, target: 490 }, + { source: 490, target: 7 }, + { source: 491, target: 7 }, + { source: 491, target: 94 }, + ], + } + const option = { + legend: { + data: ['HTMLElement', 'WebGL', 'SVG', 'CSS', 'Other'], + }, + series: [ + { + type: 'graph', + layout: 'force', + animation: false, + label: { + normal: { + position: 'right', + formatter: '{b}', + }, + }, + draggable: true, + data: webkitDep.nodes.map((node, idx) => { + node.id = idx + return node + }), + categories: webkitDep.categories, + force: { + edgeLength: 5, + repulsion: 20, + gravity: 0.2, + }, + edges: webkitDep.links, + }, + ], + } + return option + } + + return ( +
+
+ + +
+
+ ) +} + +export default GraphComponent diff --git a/src/pages/chart/ECharts/LiquidfillComponent.js b/src/pages/chart/ECharts/LiquidfillComponent.js new file mode 100644 index 0000000..b119217 --- /dev/null +++ b/src/pages/chart/ECharts/LiquidfillComponent.js @@ -0,0 +1,32 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +require('echarts-liquidfill') + +const LiquidfillComponent = () => { + const option = { + series: [ + { + type: 'liquidFill', + data: [0.6], + }, + ], + } + return ( +
+
+ + +
+
+ ) +} + +export default LiquidfillComponent diff --git a/src/pages/chart/ECharts/LunarCalendarComponent.js b/src/pages/chart/ECharts/LunarCalendarComponent.js new file mode 100644 index 0000000..0d4e7c4 --- /dev/null +++ b/src/pages/chart/ECharts/LunarCalendarComponent.js @@ -0,0 +1,490 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import * as echarts from 'echarts' + +const LunarCalendarComponent = () => { + const getOtion = () => { + let dateList = [ + ['2017-1-1', '初四'], + ['2017-1-2', '初五'], + ['2017-1-3', '初六'], + ['2017-1-4', '初七'], + ['2017-1-5', '初八', '小寒'], + ['2017-1-6', '初九'], + ['2017-1-7', '初十'], + ['2017-1-8', '十一'], + ['2017-1-9', '十二'], + ['2017-1-10', '十三'], + ['2017-1-11', '十四'], + ['2017-1-12', '十五'], + ['2017-1-13', '十六'], + ['2017-1-14', '十七'], + ['2017-1-15', '十八'], + ['2017-1-16', '十九'], + ['2017-1-17', '二十'], + ['2017-1-18', '廿一'], + ['2017-1-19', '廿二'], + ['2017-1-20', '廿三', '大寒'], + ['2017-1-21', '廿四'], + ['2017-1-22', '廿五'], + ['2017-1-23', '廿六'], + ['2017-1-24', '廿七'], + ['2017-1-25', '廿八'], + ['2017-1-26', '廿九'], + ['2017-1-27', '三十'], + ['2017-1-28', '正月'], + ['2017-1-29', '初二'], + ['2017-1-30', '初三'], + ['2017-1-31', '初四'], + ['2017-2-1', '初五'], + ['2017-2-2', '初六'], + ['2017-2-3', '初七', '立春'], + ['2017-2-4', '初八'], + ['2017-2-5', '初九'], + ['2017-2-6', '初十'], + ['2017-2-7', '十一'], + ['2017-2-8', '十二'], + ['2017-2-9', '十三'], + ['2017-2-10', '十四'], + ['2017-2-11', '十五'], + ['2017-2-12', '十六'], + ['2017-2-13', '十七'], + ['2017-2-14', '十八'], + ['2017-2-15', '十九'], + ['2017-2-16', '二十'], + ['2017-2-17', '廿一'], + ['2017-2-18', '廿二', '雨水'], + ['2017-2-19', '廿三'], + ['2017-2-20', '廿四'], + ['2017-2-21', '廿五'], + ['2017-2-22', '廿六'], + ['2017-2-23', '廿七'], + ['2017-2-24', '廿八'], + ['2017-2-25', '廿九'], + ['2017-2-26', '二月'], + ['2017-2-27', '初二'], + ['2017-2-28', '初三'], + ['2017-3-1', '初四'], + ['2017-3-2', '初五'], + ['2017-3-3', '初六'], + ['2017-3-4', '初七'], + ['2017-3-5', '初八', '驚蟄'], + ['2017-3-6', '初九'], + ['2017-3-7', '初十'], + ['2017-3-8', '十一'], + ['2017-3-9', '十二'], + ['2017-3-10', '十三'], + ['2017-3-11', '十四'], + ['2017-3-12', '十五'], + ['2017-3-13', '十六'], + ['2017-3-14', '十七'], + ['2017-3-15', '十八'], + ['2017-3-16', '十九'], + ['2017-3-17', '二十'], + ['2017-3-18', '廿一'], + ['2017-3-19', '廿二'], + ['2017-3-20', '廿三', '春分'], + ['2017-3-21', '廿四'], + ['2017-3-22', '廿五'], + ['2017-3-23', '廿六'], + ['2017-3-24', '廿七'], + ['2017-3-25', '廿八'], + ['2017-3-26', '廿九'], + ['2017-3-27', '三十'], + ['2017-3-28', '三月'], + ['2017-3-29', '初二'], + ['2017-3-30', '初三'], + ['2017-3-31', '初四'], + ['2017-4-1', '初五'], + ['2017-4-2', '初六'], + ['2017-4-3', '初七'], + ['2017-4-4', '初八', '清明'], + ['2017-4-5', '初九'], + ['2017-4-6', '初十'], + ['2017-4-7', '十一'], + ['2017-4-8', '十二'], + ['2017-4-9', '十三'], + ['2017-4-10', '十四'], + ['2017-4-11', '十五'], + ['2017-4-12', '十六'], + ['2017-4-13', '十七'], + ['2017-4-14', '十八'], + ['2017-4-15', '十九'], + ['2017-4-16', '二十'], + ['2017-4-17', '廿一'], + ['2017-4-18', '廿二'], + ['2017-4-19', '廿三'], + ['2017-4-20', '廿四', '穀雨'], + ['2017-4-21', '廿五'], + ['2017-4-22', '廿六'], + ['2017-4-23', '廿七'], + ['2017-4-24', '廿八'], + ['2017-4-25', '廿九'], + ['2017-4-26', '四月'], + ['2017-4-27', '初二'], + ['2017-4-28', '初三'], + ['2017-4-29', '初四'], + ['2017-4-30', '初五'], + ['2017-5-1', '初六'], + ['2017-5-2', '初七'], + ['2017-5-3', '初八'], + ['2017-5-4', '初九'], + ['2017-5-5', '初十', '立夏'], + ['2017-5-6', '十一'], + ['2017-5-7', '十二'], + ['2017-5-8', '十三'], + ['2017-5-9', '十四'], + ['2017-5-10', '十五'], + ['2017-5-11', '十六'], + ['2017-5-12', '十七'], + ['2017-5-13', '十八'], + ['2017-5-14', '十九'], + ['2017-5-15', '二十'], + ['2017-5-16', '廿一'], + ['2017-5-17', '廿二'], + ['2017-5-18', '廿三'], + ['2017-5-19', '廿四'], + ['2017-5-20', '廿五'], + ['2017-5-21', '廿六', '小滿'], + ['2017-5-22', '廿七'], + ['2017-5-23', '廿八'], + ['2017-5-24', '廿九'], + ['2017-5-25', '三十'], + ['2017-5-26', '五月'], + ['2017-5-27', '初二'], + ['2017-5-28', '初三'], + ['2017-5-29', '初四'], + ['2017-5-30', '初五'], + ['2017-5-31', '初六'], + ['2017-6-1', '初七'], + ['2017-6-2', '初八'], + ['2017-6-3', '初九'], + ['2017-6-4', '初十'], + ['2017-6-5', '十一', '芒種'], + ['2017-6-6', '十二'], + ['2017-6-7', '十三'], + ['2017-6-8', '十四'], + ['2017-6-9', '十五'], + ['2017-6-10', '十六'], + ['2017-6-11', '十七'], + ['2017-6-12', '十八'], + ['2017-6-13', '十九'], + ['2017-6-14', '二十'], + ['2017-6-15', '廿一'], + ['2017-6-16', '廿二'], + ['2017-6-17', '廿三'], + ['2017-6-18', '廿四'], + ['2017-6-19', '廿五'], + ['2017-6-20', '廿六'], + ['2017-6-21', '廿七', '夏至'], + ['2017-6-22', '廿八'], + ['2017-6-23', '廿九'], + ['2017-6-24', '六月'], + ['2017-6-25', '初二'], + ['2017-6-26', '初三'], + ['2017-6-27', '初四'], + ['2017-6-28', '初五'], + ['2017-6-29', '初六'], + ['2017-6-30', '初七'], + ['2017-7-1', '初八'], + ['2017-7-2', '初九'], + ['2017-7-3', '初十'], + ['2017-7-4', '十一'], + ['2017-7-5', '十二'], + ['2017-7-6', '十三'], + ['2017-7-7', '十四', '小暑'], + ['2017-7-8', '十五'], + ['2017-7-9', '十六'], + ['2017-7-10', '十七'], + ['2017-7-11', '十八'], + ['2017-7-12', '十九'], + ['2017-7-13', '二十'], + ['2017-7-14', '廿一'], + ['2017-7-15', '廿二'], + ['2017-7-16', '廿三'], + ['2017-7-17', '廿四'], + ['2017-7-18', '廿五'], + ['2017-7-19', '廿六'], + ['2017-7-20', '廿七'], + ['2017-7-21', '廿八'], + ['2017-7-22', '廿九', '大暑'], + ['2017-7-23', '閏六'], + ['2017-7-24', '初二'], + ['2017-7-25', '初三'], + ['2017-7-26', '初四'], + ['2017-7-27', '初五'], + ['2017-7-28', '初六'], + ['2017-7-29', '初七'], + ['2017-7-30', '初八'], + ['2017-7-31', '初九'], + ['2017-8-1', '初十'], + ['2017-8-2', '十一'], + ['2017-8-3', '十二'], + ['2017-8-4', '十三'], + ['2017-8-5', '十四'], + ['2017-8-6', '十五'], + ['2017-8-7', '十六', '立秋'], + ['2017-8-8', '十七'], + ['2017-8-9', '十八'], + ['2017-8-10', '十九'], + ['2017-8-11', '二十'], + ['2017-8-12', '廿一'], + ['2017-8-13', '廿二'], + ['2017-8-14', '廿三'], + ['2017-8-15', '廿四'], + ['2017-8-16', '廿五'], + ['2017-8-17', '廿六'], + ['2017-8-18', '廿七'], + ['2017-8-19', '廿八'], + ['2017-8-20', '廿九'], + ['2017-8-21', '三十'], + ['2017-8-22', '七月'], + ['2017-8-23', '初二', '處暑'], + ['2017-8-24', '初三'], + ['2017-8-25', '初四'], + ['2017-8-26', '初五'], + ['2017-8-27', '初六'], + ['2017-8-28', '初七'], + ['2017-8-29', '初八'], + ['2017-8-30', '初九'], + ['2017-8-31', '初十'], + ['2017-9-1', '十一'], + ['2017-9-2', '十二'], + ['2017-9-3', '十三'], + ['2017-9-4', '十四'], + ['2017-9-5', '十五'], + ['2017-9-6', '十六'], + ['2017-9-7', '十七', '白露'], + ['2017-9-8', '十八'], + ['2017-9-9', '十九'], + ['2017-9-10', '二十'], + ['2017-9-11', '廿一'], + ['2017-9-12', '廿二'], + ['2017-9-13', '廿三'], + ['2017-9-14', '廿四'], + ['2017-9-15', '廿五'], + ['2017-9-16', '廿六'], + ['2017-9-17', '廿七'], + ['2017-9-18', '廿八'], + ['2017-9-19', '廿九'], + ['2017-9-20', '八月'], + ['2017-9-21', '初二'], + ['2017-9-22', '初三'], + ['2017-9-23', '初四', '秋分'], + ['2017-9-24', '初五'], + ['2017-9-25', '初六'], + ['2017-9-26', '初七'], + ['2017-9-27', '初八'], + ['2017-9-28', '初九'], + ['2017-9-29', '初十'], + ['2017-9-30', '十一'], + ['2017-10-1', '十二'], + ['2017-10-2', '十三'], + ['2017-10-3', '十四'], + ['2017-10-4', '十五'], + ['2017-10-5', '十六'], + ['2017-10-6', '十七'], + ['2017-10-7', '十八'], + ['2017-10-8', '十九', '寒露'], + ['2017-10-9', '二十'], + ['2017-10-10', '廿一'], + ['2017-10-11', '廿二'], + ['2017-10-12', '廿三'], + ['2017-10-13', '廿四'], + ['2017-10-14', '廿五'], + ['2017-10-15', '廿六'], + ['2017-10-16', '廿七'], + ['2017-10-17', '廿八'], + ['2017-10-18', '廿九'], + ['2017-10-19', '三十'], + ['2017-10-20', '九月'], + ['2017-10-21', '初二'], + ['2017-10-22', '初三'], + ['2017-10-23', '初四', '霜降'], + ['2017-10-24', '初五'], + ['2017-10-25', '初六'], + ['2017-10-26', '初七'], + ['2017-10-27', '初八'], + ['2017-10-28', '初九'], + ['2017-10-29', '初十'], + ['2017-10-30', '十一'], + ['2017-10-31', '十二'], + ['2017-11-1', '十三'], + ['2017-11-2', '十四'], + ['2017-11-3', '十五'], + ['2017-11-4', '十六'], + ['2017-11-5', '十七'], + ['2017-11-6', '十八'], + ['2017-11-7', '十九', '立冬'], + ['2017-11-8', '二十'], + ['2017-11-9', '廿一'], + ['2017-11-10', '廿二'], + ['2017-11-11', '廿三'], + ['2017-11-12', '廿四'], + ['2017-11-13', '廿五'], + ['2017-11-14', '廿六'], + ['2017-11-15', '廿七'], + ['2017-11-16', '廿八'], + ['2017-11-17', '廿九'], + ['2017-11-18', '十月'], + ['2017-11-19', '初二'], + ['2017-11-20', '初三'], + ['2017-11-21', '初四'], + ['2017-11-22', '初五', '小雪'], + ['2017-11-23', '初六'], + ['2017-11-24', '初七'], + ['2017-11-25', '初八'], + ['2017-11-26', '初九'], + ['2017-11-27', '初十'], + ['2017-11-28', '十一'], + ['2017-11-29', '十二'], + ['2017-11-30', '十三'], + ['2017-12-1', '十四'], + ['2017-12-2', '十五'], + ['2017-12-3', '十六'], + ['2017-12-4', '十七'], + ['2017-12-5', '十八'], + ['2017-12-6', '十九'], + ['2017-12-7', '二十', '大雪'], + ['2017-12-8', '廿一'], + ['2017-12-9', '廿二'], + ['2017-12-10', '廿三'], + ['2017-12-11', '廿四'], + ['2017-12-12', '廿五'], + ['2017-12-13', '廿六'], + ['2017-12-14', '廿七'], + ['2017-12-15', '廿八'], + ['2017-12-16', '廿九'], + ['2017-12-17', '三十'], + ['2017-12-18', '十一月'], + ['2017-12-19', '初二'], + ['2017-12-20', '初三'], + ['2017-12-21', '初四'], + ['2017-12-22', '初五', '冬至'], + ['2017-12-23', '初六'], + ['2017-12-24', '初七'], + ['2017-12-25', '初八'], + ['2017-12-26', '初九'], + ['2017-12-27', '初十'], + ['2017-12-28', '十一'], + ['2017-12-29', '十二'], + ['2017-12-30', '十三'], + ['2017-12-31', '十四'], + ] + + let heatmapData = [] + let lunarData = [] + for (let i = 0; i < dateList.length; i++) { + heatmapData.push([dateList[i][0], Math.random() * 300]) + lunarData.push([dateList[i][0], 1, dateList[i][1], dateList[i][2]]) + } + + const option = { + tooltip: { + formatter(params) { + return `降雨量: ${params.value[1].toFixed(2)}` + }, + }, + + visualMap: { + show: false, + min: 0, + max: 300, + calculable: true, + seriesIndex: [2], + orient: 'horizontal', + left: 'center', + bottom: 20, + inRange: { + color: ['#e0ffff', '#006edd'], + opacity: 0.3, + }, + controller: { + inRange: { + opacity: 0.5, + }, + }, + }, + + calendar: [ + { + left: 'center', + top: 'middle', + cellSize: [70, 70], + yearLabel: { show: false }, + orient: 'vertical', + dayLabel: { + firstDay: 1, + nameMap: 'cn', + }, + monthLabel: { + show: false, + }, + range: '2017-03', + }, + ], + + series: [ + { + type: 'scatter', + coordinateSystem: 'calendar', + symbolSize: 1, + label: { + normal: { + show: true, + formatter(params) { + let d = echarts.number.parseDate(params.value[0]) + return `${d.getDate()}\n\n${params.value[2]}\n\n` + }, + textStyle: { + color: '#000', + }, + }, + }, + data: lunarData, + }, + { + type: 'scatter', + coordinateSystem: 'calendar', + symbolSize: 1, + label: { + normal: { + show: true, + formatter(params) { + return `\n\n\n${params.value[3] || ''}` + }, + textStyle: { + fontSize: 14, + fontWeight: 700, + color: '#a00', + }, + }, + }, + data: lunarData, + }, + { + name: '降雨量', + type: 'heatmap', + coordinateSystem: 'calendar', + data: heatmapData, + }, + ], + } + return option + } + + return ( +
+
+ + +
+
+ ) +} + +export default LunarCalendarComponent diff --git a/src/pages/chart/ECharts/MainPageComponent.js b/src/pages/chart/ECharts/MainPageComponent.js new file mode 100644 index 0000000..ed0a5cd --- /dev/null +++ b/src/pages/chart/ECharts/MainPageComponent.js @@ -0,0 +1,53 @@ +import React from 'react' +import AdSense from 'react-adsense' +import { Link } from 'umi' +import DynamicChartComponent from './DynamicChartComponent.js' + +const MainPageComponent = () => { + return ( +
+

echarts-for-react {this.props.params.type}

+

+ {' '} + A very simple echarts(v3.0) wrapper for React.{' '} + + hustcc/echarts-for-react + +

+ + + +

+ Simple demo | + Echarts loading | + Echarts API | + Echarts events | + Echarts theme | + Dynamic chart | + Map chart +

+

+ New + :   + Airport | + Graph | + Calendar | + Treemap | + Gauge | + GCalendar | + Lunar | + Liquidfill +

+ {this.props.children || } + +

+ Get it on GitHub!{' '} + + hustcc/echarts-for-react + +

+
+ ) +} + +export default MainPageComponent diff --git a/src/pages/chart/ECharts/MapChartComponent.js b/src/pages/chart/ECharts/MapChartComponent.js new file mode 100644 index 0000000..d272e90 --- /dev/null +++ b/src/pages/chart/ECharts/MapChartComponent.js @@ -0,0 +1,209 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +require('./map/js/china.js') + +class MapChartComponent extends React.Component { + constructor() { + super() + this.timeTicket = null + const randomData = () => { + return Math.round(Math.random() * 1000) + } + const option = { + title: { + text: 'iphone销量', + subtext: '纯属虚构', + left: 'center', + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'left', + data: ['iphone3', 'iphone4', 'iphone5'], + }, + visualMap: { + min: 0, + max: 2500, + left: 'left', + top: 'bottom', + text: ['高', '低'], // 文本,默认为数值文本 + calculable: true, + }, + toolbox: { + show: true, + orient: 'vertical', + left: 'right', + top: 'center', + feature: { + dataView: { readOnly: false }, + restore: {}, + saveAsImage: {}, + }, + }, + series: [ + { + name: 'iphone3', + type: 'map', + mapType: 'china', + roam: false, + label: { + normal: { + show: true, + }, + emphasis: { + show: true, + }, + }, + data: [ + { name: '北京', value: randomData() }, + { name: '天津', value: randomData() }, + { name: '上海', value: randomData() }, + { name: '重庆', value: randomData() }, + { name: '河北', value: randomData() }, + { name: '河南', value: randomData() }, + { name: '云南', value: randomData() }, + { name: '辽宁', value: randomData() }, + { name: '黑龙江', value: randomData() }, + { name: '湖南', value: randomData() }, + { name: '安徽', value: randomData() }, + { name: '山东', value: randomData() }, + { name: '新疆', value: randomData() }, + { name: '江苏', value: randomData() }, + { name: '浙江', value: randomData() }, + { name: '江西', value: randomData() }, + { name: '湖北', value: randomData() }, + { name: '广西', value: randomData() }, + { name: '甘肃', value: randomData() }, + { name: '山西', value: randomData() }, + { name: '内蒙古', value: randomData() }, + { name: '陕西', value: randomData() }, + { name: '吉林', value: randomData() }, + { name: '福建', value: randomData() }, + { name: '贵州', value: randomData() }, + { name: '广东', value: randomData() }, + { name: '青海', value: randomData() }, + { name: '西藏', value: randomData() }, + { name: '四川', value: randomData() }, + { name: '宁夏', value: randomData() }, + { name: '海南', value: randomData() }, + { name: '台湾', value: randomData() }, + { name: '香港', value: randomData() }, + { name: '澳门', value: randomData() }, + ], + }, + { + name: 'iphone4', + type: 'map', + mapType: 'china', + label: { + normal: { + show: true, + }, + emphasis: { + show: true, + }, + }, + data: [ + { name: '北京', value: randomData() }, + { name: '天津', value: randomData() }, + { name: '上海', value: randomData() }, + { name: '重庆', value: randomData() }, + { name: '河北', value: randomData() }, + { name: '安徽', value: randomData() }, + { name: '新疆', value: randomData() }, + { name: '浙江', value: randomData() }, + { name: '江西', value: randomData() }, + { name: '山西', value: randomData() }, + { name: '内蒙古', value: randomData() }, + { name: '吉林', value: randomData() }, + { name: '福建', value: randomData() }, + { name: '广东', value: randomData() }, + { name: '西藏', value: randomData() }, + { name: '四川', value: randomData() }, + { name: '宁夏', value: randomData() }, + { name: '香港', value: randomData() }, + { name: '澳门', value: randomData() }, + ], + }, + { + name: 'iphone5', + type: 'map', + mapType: 'china', + label: { + normal: { + show: true, + }, + emphasis: { + show: true, + }, + }, + data: [ + { name: '北京', value: randomData() }, + { name: '天津', value: randomData() }, + { name: '上海', value: randomData() }, + { name: '广东', value: randomData() }, + { name: '台湾', value: randomData() }, + { name: '香港', value: randomData() }, + { name: '澳门', value: randomData() }, + ], + }, + ], + } + this.state = { + option, + } + } + + componentDidMount() { + if (this.timeTicket) { + clearInterval(this.timeTicket) + } + this.timeTicket = setInterval(() => { + const { option } = this.state + const r = new Date().getSeconds() + option.title.text = `iphone销量${r}` + option.series[0].name = `iphone销量${r}` + option.legend.data[0] = `iphone销量${r}` + this.setState({ option }) + }, 1000) + } + + componentWillUnmount() { + if (this.timeTicket) { + clearInterval(this.timeTicket) + } + } + + render() { + let code = + "require('echarts/map/js/china.js'); \n" + + '" + return ( +
+
+ + + +
+            {code}
+          
+
+
+ ) + } +} + +export default MapChartComponent diff --git a/src/pages/chart/ECharts/ModuleLoadChartComponent.js b/src/pages/chart/ECharts/ModuleLoadChartComponent.js new file mode 100644 index 0000000..852fcdb --- /dev/null +++ b/src/pages/chart/ECharts/ModuleLoadChartComponent.js @@ -0,0 +1,55 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +const ModuleLoadChartComponent = () => { + const option = { + title: { text: 'ECharts 入门示例' }, + tooltip: {}, + xAxis: { + data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'], + }, + yAxis: {}, + series: [ + { + name: '销量', + type: 'bar', + data: [5, 20, 36, 10, 10, 20], + }, + ], + } + + let code = + '" + return ( +
+
+ + + +
+          {code}
+        
+
+
+ ) +} + +export default ModuleLoadChartComponent diff --git a/src/pages/chart/ECharts/SimpleChartComponent.js b/src/pages/chart/ECharts/SimpleChartComponent.js new file mode 100644 index 0000000..4028029 --- /dev/null +++ b/src/pages/chart/ECharts/SimpleChartComponent.js @@ -0,0 +1,90 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import './theme/macarons.js' + +const SimpleChartComponent = () => { + const option = { + title: { + text: '堆叠区域图', + }, + tooltip: { + trigger: 'axis', + }, + legend: { + data: ['邮件营销', '联盟广告', '视频广告'], + }, + toolbox: { + feature: { + saveAsImage: {}, + }, + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], + }, + ], + yAxis: [ + { + type: 'value', + }, + ], + series: [ + { + name: '邮件营销', + type: 'line', + stack: '总量', + areaStyle: { normal: {} }, + data: [120, 132, 101, 134, 90, 230, 210], + }, + { + name: '联盟广告', + type: 'line', + stack: '总量', + areaStyle: { normal: {} }, + data: [220, 182, 191, 234, 290, 330, 310], + }, + { + name: '视频广告', + type: 'line', + stack: '总量', + areaStyle: { normal: {} }, + data: [150, 232, 201, 154, 190, 330, 410], + }, + ], + } + let code = + '" + return ( +
+
+ + + +
+          {code}
+        
+
+
+ ) +} + +export default SimpleChartComponent diff --git a/src/pages/chart/ECharts/ThemeChartComponent.js b/src/pages/chart/ECharts/ThemeChartComponent.js new file mode 100644 index 0000000..7b81688 --- /dev/null +++ b/src/pages/chart/ECharts/ThemeChartComponent.js @@ -0,0 +1,127 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' + +import * as echarts from 'echarts' + +const ThemeChartComponent = () => { + const option = { + title: { + text: '阶梯瀑布图', + subtext: 'From ExcelHome', + sublink: 'http://e.weibo.com/1341556070/Aj1J2x5a5', + }, + tooltip: { + trigger: 'axis', + axisPointer: { + // 坐标轴指示器,坐标轴触发有效 + type: 'shadow', // 默认为直线,可选为:'line' | 'shadow' + }, + }, + legend: { + data: ['支出', '收入'], + }, + grid: { + left: '3%', + right: '4%', + bottom: '3%', + containLabel: true, + }, + xAxis: { + type: 'category', + splitLine: { show: false }, + data: [ + '11月1日', + '11月2日', + '11月3日', + '11月4日', + '11月5日', + '11月6日', + '11月7日', + '11月8日', + '11月9日', + '11月10日', + '11月11日', + ], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: '辅助', + type: 'bar', + stack: '总量', + itemStyle: { + normal: { + barBorderColor: 'rgba(0,0,0,0)', + color: 'rgba(0,0,0,0)', + }, + emphasis: { + barBorderColor: 'rgba(0,0,0,0)', + color: 'rgba(0,0,0,0)', + }, + }, + data: [0, 900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292], + }, + { + name: '收入', + type: 'bar', + stack: '总量', + label: { + normal: { + show: true, + position: 'top', + }, + }, + data: [900, 345, 393, '-', '-', 135, 178, 286, '-', '-', '-'], + }, + { + name: '支出', + type: 'bar', + stack: '总量', + label: { + normal: { + show: true, + position: 'bottom', + }, + }, + data: ['-', '-', '-', 108, 154, '-', '-', '-', 119, 361, 203], + }, + ], + } + + echarts.registerTheme('my_theme', { + backgroundColor: '#f4cccc', + }) + + let code = + "echarts.registerTheme('my_theme', {\n" + + " backgroundColor: '#f4cccc'\n" + + '});\n\n' + + '" + return ( +
+
+ + + +
+          {code}
+        
+
+
+ ) +} + +export default ThemeChartComponent diff --git a/src/pages/chart/ECharts/TransparentBar3DComPonent.js b/src/pages/chart/ECharts/TransparentBar3DComPonent.js new file mode 100644 index 0000000..63d0740 --- /dev/null +++ b/src/pages/chart/ECharts/TransparentBar3DComPonent.js @@ -0,0 +1,302 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import 'echarts-gl' + +const hours = [ + '12a', + '1a', + '2a', + '3a', + '4a', + '5a', + '6a', + '7a', + '8a', + '9a', + '10a', + '11a', + '12p', + '1p', + '2p', + '3p', + '4p', + '5p', + '6p', + '7p', + '8p', + '9p', + '10p', + '11p', +] +const days = [ + 'Saturday', + 'Friday', + 'Thursday', + 'Wednesday', + 'Tuesday', + 'Monday', + 'Sunday', +] + +const data = [ + [0, 0, 5], + [0, 1, 1], + [0, 2, 0], + [0, 3, 0], + [0, 4, 0], + [0, 5, 0], + [0, 6, 0], + [0, 7, 0], + [0, 8, 0], + [0, 9, 0], + [0, 10, 0], + [0, 11, 2], + [0, 12, 4], + [0, 13, 1], + [0, 14, 1], + [0, 15, 3], + [0, 16, 4], + [0, 17, 6], + [0, 18, 4], + [0, 19, 4], + [0, 20, 3], + [0, 21, 3], + [0, 22, 2], + [0, 23, 5], + [1, 0, 7], + [1, 1, 0], + [1, 2, 0], + [1, 3, 0], + [1, 4, 0], + [1, 5, 0], + [1, 6, 0], + [1, 7, 0], + [1, 8, 0], + [1, 9, 0], + [1, 10, 5], + [1, 11, 2], + [1, 12, 2], + [1, 13, 6], + [1, 14, 9], + [1, 15, 11], + [1, 16, 6], + [1, 17, 7], + [1, 18, 8], + [1, 19, 12], + [1, 20, 5], + [1, 21, 5], + [1, 22, 7], + [1, 23, 2], + [2, 0, 1], + [2, 1, 1], + [2, 2, 0], + [2, 3, 0], + [2, 4, 0], + [2, 5, 0], + [2, 6, 0], + [2, 7, 0], + [2, 8, 0], + [2, 9, 0], + [2, 10, 3], + [2, 11, 2], + [2, 12, 1], + [2, 13, 9], + [2, 14, 8], + [2, 15, 10], + [2, 16, 6], + [2, 17, 5], + [2, 18, 5], + [2, 19, 5], + [2, 20, 7], + [2, 21, 4], + [2, 22, 2], + [2, 23, 4], + [3, 0, 7], + [3, 1, 3], + [3, 2, 0], + [3, 3, 0], + [3, 4, 0], + [3, 5, 0], + [3, 6, 0], + [3, 7, 0], + [3, 8, 1], + [3, 9, 0], + [3, 10, 5], + [3, 11, 4], + [3, 12, 7], + [3, 13, 14], + [3, 14, 13], + [3, 15, 12], + [3, 16, 9], + [3, 17, 5], + [3, 18, 5], + [3, 19, 10], + [3, 20, 6], + [3, 21, 4], + [3, 22, 4], + [3, 23, 1], + [4, 0, 1], + [4, 1, 3], + [4, 2, 0], + [4, 3, 0], + [4, 4, 0], + [4, 5, 1], + [4, 6, 0], + [4, 7, 0], + [4, 8, 0], + [4, 9, 2], + [4, 10, 4], + [4, 11, 4], + [4, 12, 2], + [4, 13, 4], + [4, 14, 4], + [4, 15, 14], + [4, 16, 12], + [4, 17, 1], + [4, 18, 8], + [4, 19, 5], + [4, 20, 3], + [4, 21, 7], + [4, 22, 3], + [4, 23, 0], + [5, 0, 2], + [5, 1, 1], + [5, 2, 0], + [5, 3, 3], + [5, 4, 0], + [5, 5, 0], + [5, 6, 0], + [5, 7, 0], + [5, 8, 2], + [5, 9, 0], + [5, 10, 4], + [5, 11, 1], + [5, 12, 5], + [5, 13, 10], + [5, 14, 5], + [5, 15, 7], + [5, 16, 11], + [5, 17, 6], + [5, 18, 0], + [5, 19, 5], + [5, 20, 3], + [5, 21, 4], + [5, 22, 2], + [5, 23, 0], + [6, 0, 1], + [6, 1, 0], + [6, 2, 0], + [6, 3, 0], + [6, 4, 0], + [6, 5, 0], + [6, 6, 0], + [6, 7, 0], + [6, 8, 0], + [6, 9, 0], + [6, 10, 1], + [6, 11, 0], + [6, 12, 2], + [6, 13, 1], + [6, 14, 3], + [6, 15, 4], + [6, 16, 0], + [6, 17, 0], + [6, 18, 0], + [6, 19, 0], + [6, 20, 1], + [6, 21, 2], + [6, 22, 2], + [6, 23, 6], +] + +const option = { + tooltip: {}, + visualMap: { + max: 20, + inRange: { + color: [ + '#313695', + '#4575b4', + '#74add1', + '#abd9e9', + '#e0f3f8', + '#ffffbf', + '#fee090', + '#fdae61', + '#f46d43', + '#d73027', + '#a50026', + ], + }, + }, + xAxis3D: { + type: 'category', + data: hours, + }, + yAxis3D: { + type: 'category', + data: days, + }, + zAxis3D: { + type: 'value', + }, + grid3D: { + boxWidth: 200, + boxDepth: 80, + light: { + main: { + intensity: 1.2, + }, + ambient: { + intensity: 0.3, + }, + }, + }, + series: [ + { + type: 'bar3D', + data: data.map(item => { + return { + value: [item[1], item[0], item[2]], + } + }), + shading: 'color', + + label: { + show: false, + textStyle: { + fontSize: 16, + borderWidth: 1, + }, + }, + + itemStyle: { + opacity: 0.4, + }, + + emphasis: { + label: { + textStyle: { + fontSize: 20, + color: '#900', + }, + }, + itemStyle: { + color: '#900', + }, + }, + }, + ], +} + +const TransparentBar3DComPonent = () => { + return ( + + ) +} + +export default TransparentBar3DComPonent diff --git a/src/pages/chart/ECharts/TreemapComponent.js b/src/pages/chart/ECharts/TreemapComponent.js new file mode 100644 index 0000000..aec590d --- /dev/null +++ b/src/pages/chart/ECharts/TreemapComponent.js @@ -0,0 +1,275 @@ +import React from 'react' +import ReactEcharts from 'echarts-for-react' +import * as echarts from 'echarts' + +const TreemapComponent = () => { + let diskData = [ + { + value: 180, + name: 'Accounts', + path: 'Accounts', + children: [ + { + value: 76, + name: 'Access', + path: 'Accounts/Access', + children: [ + { + value: 12, + name: 'DefaultAccessPlugin.bundle', + path: 'Accounts/Access/DefaultAccessPlugin.bundle', + }, + { + value: 28, + name: 'FacebookAccessPlugin.bundle', + path: 'Accounts/Access/FacebookAccessPlugin.bundle', + }, + { + value: 20, + name: 'LinkedInAccessPlugin.bundle', + path: 'Accounts/Access/LinkedInAccessPlugin.bundle', + }, + { + value: 16, + name: 'TencentWeiboAccessPlugin.bundle', + path: 'Accounts/Access/TencentWeiboAccessPlugin.bundle', + }, + ], + }, + { + value: 92, + name: 'Authentication', + path: 'Accounts/Authentication', + children: [ + { + value: 24, + name: 'FacebookAuthenticationPlugin.bundle', + path: + 'Accounts/Authentication/FacebookAuthenticationPlugin.bundle', + }, + { + value: 16, + name: 'LinkedInAuthenticationPlugin.bundle', + path: + 'Accounts/Authentication/LinkedInAuthenticationPlugin.bundle', + }, + { + value: 20, + name: 'TencentWeiboAuthenticationPlugin.bundle', + path: + 'Accounts/Authentication/TencentWeiboAuthenticationPlugin.bundle', + }, + { + value: 16, + name: 'TwitterAuthenticationPlugin.bundle', + path: + 'Accounts/Authentication/TwitterAuthenticationPlugin.bundle', + }, + { + value: 16, + name: 'WeiboAuthenticationPlugin.bundle', + path: 'Accounts/Authentication/WeiboAuthenticationPlugin.bundle', + }, + ], + }, + { + value: 12, + name: 'Notification', + path: 'Accounts/Notification', + children: [ + { + value: 12, + name: 'SPAAccountsNotificationPlugin.bundle', + path: + 'Accounts/Notification/SPAAccountsNotificationPlugin.bundle', + }, + ], + }, + ], + }, + { + value: 1904, + name: 'AddressBook Plug-Ins', + path: 'AddressBook Plug-Ins', + children: [ + { + value: 744, + name: 'CardDAVPlugin.sourcebundle', + path: 'AddressBook Plug-Ins/CardDAVPlugin.sourcebundle', + children: [ + { + value: 744, + name: 'Contents', + path: 'AddressBook Plug-Ins/CardDAVPlugin.sourcebundle/Contents', + }, + ], + }, + { + value: 28, + name: 'DirectoryServices.sourcebundle', + path: 'AddressBook Plug-Ins/DirectoryServices.sourcebundle', + children: [ + { + value: 28, + name: 'Contents', + path: + 'AddressBook Plug-Ins/DirectoryServices.sourcebundle/Contents', + }, + ], + }, + { + value: 680, + name: 'Exchange.sourcebundle', + path: 'AddressBook Plug-Ins/Exchange.sourcebundle', + children: [ + { + value: 680, + name: 'Contents', + path: 'AddressBook Plug-Ins/Exchange.sourcebundle/Contents', + }, + ], + }, + { + value: 432, + name: 'LDAP.sourcebundle', + path: 'AddressBook Plug-Ins/LDAP.sourcebundle', + children: [ + { + value: 432, + name: 'Contents', + path: 'AddressBook Plug-Ins/LDAP.sourcebundle/Contents', + }, + ], + }, + { + value: 20, + name: 'LocalSource.sourcebundle', + path: 'AddressBook Plug-Ins/LocalSource.sourcebundle', + children: [ + { + value: 20, + name: 'Contents', + path: 'AddressBook Plug-Ins/LocalSource.sourcebundle/Contents', + }, + ], + }, + ], + }, + { + value: 36, + name: 'Assistant', + path: 'Assistant', + children: [ + { + value: 36, + name: 'Plugins', + path: 'Assistant/Plugins', + children: [ + { + value: 36, + name: 'AddressBook.assistantBundle', + path: 'Assistant/Plugins/AddressBook.assistantBundle', + }, + { + value: 8, + name: 'GenericAddressHandler.addresshandler', + path: 'Recents/Plugins/GenericAddressHandler.addresshandler', + }, + { + value: 12, + name: 'MapsRecents.addresshandler', + path: 'Recents/Plugins/MapsRecents.addresshandler', + }, + ], + }, + ], + }, + ] + let formatUtil = echarts.format + function getLevelOption() { + return [ + { + itemStyle: { + normal: { + borderWidth: 0, + gapWidth: 5, + }, + }, + }, + { + itemStyle: { + normal: { + gapWidth: 1, + }, + }, + }, + { + colorSaturation: [0.35, 0.5], + itemStyle: { + normal: { + gapWidth: 1, + borderColorSaturation: 0.6, + }, + }, + }, + ] + } + const option = { + title: { + text: 'Disk Usage', + left: 'center', + }, + + tooltip: { + formatter(info) { + let { value, treePathInfo } = info + let treePath = [] + + for (let i = 1; i < treePathInfo.length; i++) { + treePath.push(treePathInfo[i].name) + } + + return [ + `
${formatUtil.encodeHTML( + treePath.join('/') + )}
`, + `Disk Usage: ${formatUtil.addCommas(value)} KB`, + ].join('') + }, + }, + + series: [ + { + name: 'Disk Usage', + type: 'treemap', + visibleMin: 300, + label: { + show: true, + formatter: '{b}', + }, + itemStyle: { + normal: { + borderColor: '#fff', + }, + }, + levels: getLevelOption(), + data: diskData, + }, + ], + } + + return ( +
+
+ + +
+
+ ) +} + +export default TreemapComponent diff --git a/src/pages/chart/ECharts/index.js b/src/pages/chart/ECharts/index.js new file mode 100644 index 0000000..0e0a2e1 --- /dev/null +++ b/src/pages/chart/ECharts/index.js @@ -0,0 +1,115 @@ +import React from 'react' +import { Radio } from 'antd' +import { Page } from 'components' +import EchartsComponent from './EchartsComponent' +import styles from './index.less' + +const RadioGroup = Radio.Group + +const chartList = [ + { + label: 'SimpleChart', + value: 'simple', + }, + { + label: 'ChartShowLoading', + value: 'loading', + }, + { + label: 'ChartAPI', + value: 'api', + }, + { + label: 'ChartWithEvent', + value: 'events', + }, + { + label: 'ThemeChart', + value: 'theme', + }, + { + label: 'DynamicChart', + value: 'dynamic', + }, + { + label: 'MapChart', + value: 'map', + }, + { + label: 'AirportCoord', + value: 'airport', + }, + { + label: 'Graph', + value: 'graph', + }, + { + label: 'Calendar', + value: 'calendar', + }, + { + label: 'Treemap', + value: 'treemap', + }, + { + label: 'Gauge', + value: 'gauge', + }, + { + label: 'GCalendar', + value: 'gcalendar', + }, + { + label: 'LunarCalendar', + value: 'lunar', + }, + { + label: 'Liquidfill', + value: 'liquid', + }, + { + label: 'BubbleGradient', + value: 'BubbleGradientComponent', + }, + { + label: 'TransparentBar3D', + value: 'TransparentBar3DComPonent', + }, +] + +class Chart extends React.Component { + constructor() { + super() + this.state = { + type: '', + } + this.handleRadioGroupChange = this.handleRadioGroupChange.bind(this) + } + handleRadioGroupChange(e) { + this.setState({ + type: e.target.value, + }) + } + render() { + return ( + + +
+ +
+ +
+ ) + } +} + +export default Chart diff --git a/src/pages/chart/ECharts/index.less b/src/pages/chart/ECharts/index.less new file mode 100644 index 0000000..7a42d68 --- /dev/null +++ b/src/pages/chart/ECharts/index.less @@ -0,0 +1,34 @@ +.chart { + label { + margin: 24px 0; + display: block; + font-size: 14px; + } + + pre { + padding: 16px; + overflow: auto; + font-size: 12px; + line-height: 2; + background-color: #f6f8fa; + border-radius: 3px; + + code { + display: inline; + max-width: auto; + padding: 0; + margin: 0; + overflow: visible; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; + } + } +} + +:global { + .ant-radio-wrapper { + margin-bottom: 16px; + } +} diff --git a/src/pages/chart/ECharts/map/js/china.js b/src/pages/chart/ECharts/map/js/china.js new file mode 100644 index 0000000..12dabff --- /dev/null +++ b/src/pages/chart/ECharts/map/js/china.js @@ -0,0 +1,46 @@ +/* +* 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. +*/ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['exports', 'echarts'], factory); + } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') { + // CommonJS + factory(exports, require('echarts')); + } else { + // Browser globals + factory({}, root.echarts); + } +}(this, function (exports, echarts) { + var log = function (msg) { + if (typeof console !== 'undefined') { + console && console.error && console.error(msg); + } + } + if (!echarts) { + log('ECharts is not Loaded'); + return; + } + if (!echarts.registerMap) { + log('ECharts Map is not loaded') + return; + } + echarts.registerMap('china', {"type":"FeatureCollection","features":[{"type":"Feature","id":"710000","properties":{"id":"710000","cp":[121.509062,24.044332],"name":"台湾","childNum":6},"geometry":{"type":"MultiPolygon","coordinates":[["@@°Ü¯Û"],["@@ƛĴÕƊÉɼģºðʀ\\ƎsÆNŌÔĚäœnÜƤɊĂǀĆĴžĤNJŨxĚĮǂƺòƌ‚–âÔ®ĮXŦţƸZûЋƕƑGđ¨ĭMó·ęcëƝɉlÝƯֹÅŃ^Ó·śŃNjƏďíåɛGɉ™¿@ăƑŽ¥ĘWǬÏĶŁâ"],["@@\\p|WoYG¿¥I†j@¢"],["@@…¡‰@ˆV^RqˆBbAŒnTXeRz¤Lž«³I"],["@@ÆEE—„kWqë @œ"],["@@fced"],["@@„¯ɜÄèaì¯ØǓIġĽ"],["@@çûĖ롖hòř "]],"encodeOffsets":[[[122886,24033]],[[123335,22980]],[[122375,24193]],[[122518,24117]],[[124427,22618]],[[124862,26043]],[[126259,26318]],[[127671,26683]]]}},{"type":"Feature","id":"130000","properties":{"id":"130000","cp":[114.502461,38.045474],"name":"河北","childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@o~†Z]‚ªr‰ºc_ħ²G¼s`jΟnüsœłNX_“M`ǽÓnUK…Ĝēs¤­©yrý§uģŒc†JŠ›e"],["@@U`Ts¿m‚"],["@@oºƋÄd–eVŽDJj£€J|Ådz•Ft~žKŨ¸IÆv|”‡¢r}膎onb˜}`RÎÄn°ÒdÞ²„^®’lnÐèĄlðӜ×]ªÆ}LiĂ±Ö`^°Ç¶p®đDcœŋ`–ZÔ’¶êqvFƚ†N®ĆTH®¦O’¾ŠIbÐã´BĐɢŴÆíȦp–ĐÞXR€·nndOž¤’OÀĈƒ­Qg˜µFo|gȒęSWb©osx|hYh•gŃfmÖĩnº€T̒Sp›¢dYĤ¶UĈjl’ǐpäìë|³kÛfw²Xjz~ÂqbTŠÑ„ěŨ@|oM‡’zv¢ZrÃVw¬ŧˏfŒ°ÐT€ªqŽs{Sž¯r æÝlNd®²Ğ džiGʂJ™¼lr}~K¨ŸƐÌWö€™ÆŠzRš¤lêmĞL΄’@¡|q]SvK€ÑcwpÏρ†ĿćènĪWlĄkT}ˆJ”¤~ƒÈT„d„™pddʾĬŠ”ŽBVt„EÀ¢ôPĎƗè@~‚k–ü\\rÊĔÖæW_§¼F˜†´©òDòj’ˆYÈrbĞāøŀG{ƀ|¦ðrb|ÀH`pʞkv‚GpuARhÞÆǶgƊTǼƹS£¨¡ù³ŘÍ]¿Ây™ôEP xX¶¹܇O¡“gÚ¡IwÃ鑦ÅB‡Ï|ǰ…N«úmH¯‹âŸDùŽyŜžŲIÄuШDž•¸dɂ‡‚FŸƒ•›Oh‡đ©OŸ›iÃ`ww^ƒÌkŸ‘ÑH«ƇǤŗĺtFu…{Z}Ö@U‡´…ʚLg®¯Oı°ÃwŸ ^˜—€VbÉs‡ˆmA…ê]]w„§›RRl£‡ȭµu¯b{ÍDěïÿȧŽuT£ġƒěŗƃĝ“Q¨fV†Ƌ•ƅn­a@‘³@šď„yýIĹÊKšŭfċŰóŒxV@tˆƯŒJ”]eƒR¾fe|rHA˜|h~Ėƍl§ÏŠlTíb ØoˆÅbbx³^zÃ͚¶Sj®A”yÂhðk`š«P€”ˈµEF†Û¬Y¨Ļrõqi¼‰Wi°§’б´°^[ˆÀ|ĠO@ÆxO\\tŽa\\tĕtû{ġŒȧXýĪÓjùÎRb›š^ΛfK[ݏděYfíÙTyŽuUSyŌŏů@Oi½’éŅ­aVcř§ax¹XŻác‡žWU£ôãºQ¨÷Ñws¥qEH‰Ù|‰›šYQoŕÇyáĂ£MðoťÊ‰P¡mšWO¡€v†{ôvîēÜISpÌhp¨ ‘j†deŔQÖj˜X³à™Ĉ[n`Yp@Už–cM`’RKhŒEbœ”pŞlNut®Etq‚nsÁŠgA‹iú‹oH‡qCX‡”hfgu“~ϋWP½¢G^}¯ÅīGCŸÑ^ãziMáļMTÃƘrMc|O_ž¯Ŏ´|‡morDkO\\mĆJfl@c̬¢aĦtRıҙ¾ùƀ^juųœK­ƒUFy™—Ɲ…›īÛ÷ąV×qƥV¿aȉd³B›qPBm›aËđŻģm“Å®Vйd^K‡KoŸnYg“¯Xhqa”Ldu¥•ÍpDž¡KąÅƒkĝęěhq‡}HyÓ]¹ǧ£…Í÷¿qáµ§š™g‘¤o^á¾ZE‡¤i`ij{n•ƒOl»ŸWÝĔįhg›F[¿¡—ßkOüš_‰€ū‹i„DZàUtėGylƒ}ŒÓM}€jpEC~¡FtoQi‘šHkk{Ãmï‚"]],"encodeOffsets":[[[119712,40641]],[[121616,39981]],[[116462,37237]]]}},{"type":"Feature","id":"140000","properties":{"id":"140000","cp":[111.849248,36.857014],"name":"山西","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@Þĩ҃S‰ra}Á€yWix±Üe´lè“ßÓǏok‘ćiµVZģ¡coœ‘TS˹ĪmnÕńe–hZg{gtwªpXaĚThȑp{¶Eh—®RćƑP¿£‘Pmc¸mQÝW•ďȥoÅîɡųAďä³aωJ‘½¥PG­ąSM­™…EÅruµé€‘Yӎ•Ō_d›ĒCo­Èµ]¯_²ÕjāŽK~©ÅØ^ԛkïçămϑk]­±ƒcݯÑÃmQÍ~_a—pm…~ç¡q“ˆu{JÅŧ·Ls}–EyÁÆcI{¤IiCfUc•ƌÃp§]웫vD@¡SÀ‘µM‚ÅwuŽYY‡¡DbÑc¡hƒ×]nkoQdaMç~eD•ÛtT‰©±@¥ù@É¡‰ZcW|WqOJmĩl«ħşvOÓ«IqăV—¥ŸD[mI~Ó¢cehiÍ]Ɠ~ĥqXŠ·eƷœn±“}v•[ěďŽŕ]_‘œ•`‰¹ƒ§ÕōI™o©b­s^}Ét±ū«³p£ÿ·Wµ|¡¥ăFÏs׌¥ŅxŸÊdÒ{ºvĴÎêÌɊ²¶€ü¨|ÞƸµȲ‘LLúÉƎ¤ϊęĔV`„_bª‹S^|ŸdŠzY|dz¥p†ZbÆ£¶ÒK}tĦÔņƠ‚PYzn€ÍvX¶Ěn ĠÔ„zý¦ª˜÷žÑĸَUȌ¸‚dòÜJð´’ìúNM¬ŒXZ´‘¤ŊǸ_tldIš{¦ƀðĠȤ¥NehXnYG‚‡R° ƬDj¬¸|CĞ„Kq‚ºfƐiĺ©ª~ĆOQª ¤@ìǦɌ²æBŒÊ”TœŸ˜ʂōĖ’šĴŞ–ȀœÆÿȄlŤĒö„t”νî¼ĨXhŒ‘˜|ªM¤Ðz"],"encodeOffsets":[[116874,41716]]}},{"type":"Feature","id":"150000","properties":{"id":"150000","cp":[111.670801,41.818311],"name":"内蒙古","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@¯PqƒFB…‰|S•³C|kñ•H‹d‘iÄ¥sˆʼnő…PóÑÑE^‘ÅPpy_YtS™hQ·aHwsOnʼnÚs©iqj›‰€USiº]ïWš‰«gW¡A–Rë¥_ŽsgÁnUI«m‰…„‹]j‡vV¼euhwqA„aW˜ƒ_µj…»çjioQR¹ēÃßt@r³[ÛlćË^ÍÉáG“›OUۗOB±•XŸkŇ¹£k|e]ol™ŸkVͼÕqtaÏõjgÁ£§U^Œ”RLˆËnX°Ç’Bz†^~wfvˆypV ¯„ƫĉ˭ȫƗŷɿÿĿƑ˃ĝÿÃǃßËőó©ǐȍŒĖM×ÍEyx‹þp]Évïè‘vƀnÂĴÖ@‚‰†V~Ĉv¦wĖt—ējyÄDXÄxGQuv_›i¦aBçw‘˛wD™©{ŸtāmQ€{EJ§KPśƘƿ¥@‰sCT•É}ɃwˆƇy±ŸgÑ“}T[÷kÐ禫…SÒ¥¸ëBX½‰HáŵÀğtSÝÂa[ƣ°¯¦P]£ġ“–“Òk®G²„èQ°óMq}EŠóƐÇ\\ƒ‡@áügQ͋u¥Fƒ“T՛¿Jû‡]|mvāÎYua^WoÀa·­ząÒot×¶CLƗi¯¤mƎHNJ¤îìɾŊìTdåwsRÖgĒųúÍġäÕ}Q¶—ˆ¿A•†‹[¡Œ{d×uQAƒ›M•xV‹vMOmăl«ct[wº_šÇʊŽŸjb£ĦS_é“QZ“_lwgOiýe`YYLq§IÁˆdz£ÙË[ÕªuƏ³ÍT—s·bÁĽäė[›b[ˆŗfãcn¥îC¿÷µ[ŏÀQ­ōšĉm¿Á^£mJVm‡—L[{Ï_£›F¥Ö{ŹA}…×Wu©ÅaųijƳhB{·TQqÙIķˑZđ©Yc|M¡…L•eVUóK_QWk’_ĥ‘¿ãZ•»X\\ĴuUƒè‡lG®ěłTĠğDєOrÍd‚ÆÍz]‹±…ŭ©ŸÅ’]ŒÅÐ}UË¥©Tċ™ïxgckfWgi\\ÏĒ¥HkµE˜ë{»ÏetcG±ahUiñiWsɁˆ·c–C‚Õk]wȑ|ća}w…VaĚ᠞ŒG°ùnM¬¯†{ÈˆÐÆA’¥ÄêJxÙ¢”hP¢Ûˆº€µwWOŸóFŽšÁz^ÀŗÎú´§¢T¤ǻƺSė‰ǵhÝÅQgvBHouʝl_o¿Ga{ïq{¥|ſĿHĂ÷aĝÇq‡Z‘ñiñC³ª—…»E`¨åXēÕqÉû[l•}ç@čƘóO¿¡ƒFUsA‰“ʽīccšocƒ‚ƒÇS}„“£‡IS~ălkĩXçmĈ…ŀЂoÐdxÒuL^T{r@¢‘žÍƒĝKén£kQ™‰yšÅõËXŷƏL§~}kqš»IHėDžjĝŸ»ÑÞoŸå°qTt|r©ÏS‹¯·eŨĕx«È[eMˆ¿yuˆ‘pN~¹ÏyN£{©’—g‹ħWí»Í¾s“əšDž_ÃĀɗ±ą™ijĉʍŌŷ—S›É“A‹±åǥɋ@럣R©ąP©}ĹªƏj¹erƒLDĝ·{i«ƫC£µsKCš…GS|úþX”gp›{ÁX¿Ÿć{ƱȏñZáĔyoÁhA™}ŅĆfdʼn„_¹„Y°ėǩÑ¡H¯¶oMQqð¡Ë™|‘Ñ`ƭŁX½·óۓxğįÅcQ‡ˆ“ƒs«tȋDžF“Ÿù^i‘t«Č¯[›hAi©á¥ÇĚ×l|¹y¯YȵƓ‹ñǙµï‚ċ™Ļ|Dœ™üȭ¶¡˜›oŽäÕG\\ďT¿Òõr¯œŸLguÏYęRƩšɷŌO\\İТæ^Ŋ IJȶȆbÜGŽĝ¬¿ĚVĎgª^íu½jÿĕęjık@Ľƒ]ėl¥Ë‡ĭûÁ„ƒėéV©±ćn©­ȇžÍq¯½•YÃÔʼn“ÉNѝÅÝy¹NqáʅDǡËñ­ƁYÅy̱os§ȋµʽǘǏƬɱà‘ưN¢ƔÊuľýľώȪƺɂļžxœZĈ}ÌʼnŪ˜ĺœŽĭFЛĽ̅ȣͽÒŵìƩÇϋÿȮǡŏçƑůĕ~Ǎ›¼ȳÐUf†dIxÿ\\G ˆzâɏÙOº·pqy£†@ŒŠqþ@Ǟ˽IBäƣzsÂZ†ÁàĻdñ°ŕzéØűzșCìDȐĴĺf®ŽÀľưø@ɜÖÞKĊŇƄ§‚͑těï͡VAġÑÑ»d³öǍÝXĉĕÖ{þĉu¸ËʅğU̎éhɹƆ̗̮ȘNJ֥ड़ࡰţાíϲäʮW¬®ҌeרūȠkɬɻ̼ãüfƠSצɩςåȈHϚÎKdzͲOðÏȆƘ¼CϚǚ࢚˼ФԂ¤ƌžĞ̪Qʤ´¼mȠJˀŸƲÀɠmǐnǔĎȆÞǠN~€ʢĜ‚¶ƌĆĘźʆȬ˪ĚǏĞGȖƴƀj`ĢçĶāàŃºē̃ĖćšYŒÀŎüôQÐÂŎŞdžŞêƖš˜oˆDĤÕºÑǘÛˤ³̀gńƘĔÀ^žªƂ`ªt¾äƚêĦĀ¼Ð€Ĕǎ¨Ȕ»͠^ˮÊȦƤøxRrŜH¤¸ÂxDĝŒ|ø˂˜ƮÐ¬ɚwɲFjĔ²Äw°dždÀɞ_ĸdîàŎjʜêTĞªŌ‡ŜWÈ|tqĢUB~´°ÎFC•ŽU¼pĀēƄN¦¾O¶ŠłKĊOj“Ě”j´ĜYp˜{¦„ˆSĚÍ\\Tš×ªV–÷Ší¨ÅDK°ßtŇĔKš¨ǵÂcḷ̌ĚǣȄĽF‡lġUĵœŇ‹ȣFʉɁƒMğįʏƶɷØŭOǽ«ƽū¹Ʊő̝Ȩ§ȞʘĖiɜɶʦ}¨֪ࠜ̀ƇǬ¹ǨE˦ĥªÔêFŽxúQ„Er´W„rh¤Ɛ \\talĈDJ˜Ü|[Pll̚¸ƎGú´Pž¬W¦†^¦–H]prR“n|or¾wLVnÇIujkmon£cX^Bh`¥V”„¦U¤¸}€xRj–[^xN[~ªŠxQ„‚[`ªHÆÂExx^wšN¶Ê˜|¨ì†˜€MrœdYp‚oRzNy˜ÀDs~€bcfÌ`L–¾n‹|¾T‚°c¨È¢a‚r¤–`[|òDŞĔöxElÖdH„ÀI`„Ď\\Àì~ƎR¼tf•¦^¢ķ¶e”ÐÚMŒptgj–„ɡČÅyġLû™ŇV®ŠÄÈƀ†Ď°P|ªVV†ªj–¬ĚÒêp¬–E|ŬÂc|ÀtƐK fˆ{ĘFǜƌXƲąo½Ę‘\\¥–o}›Ûu£ç­kX‘{uĩ«āíÓUŅßŢq€Ť¥lyň[€oi{¦‹L‡ń‡ðFȪȖ”ĒL„¿Ì‹ˆfŒ£K£ʺ™oqNŸƒwğc`ue—tOj×°KJ±qƒÆġm‰Ěŗos¬…qehqsuœƒH{¸kH¡Š…ÊRǪÇƌbȆ¢´ä܍¢NìÉʖ¦â©Ġu¦öČ^â£Ăh–šĖMÈÄw‚\\fŦ°W ¢¾luŸD„wŠ\\̀ʉÌÛM…Ā[bӞEn}¶Vc…ê“sƒ"]],"encodeOffsets":[[[129102,52189]]]}},{"type":"Feature","id":"210000","properties":{"id":"210000","cp":[123.429096,41.796767],"name":"辽宁","childNum":16},"geometry":{"type":"MultiPolygon","coordinates":[["@@L–Ž@@s™a"],["@@MnNm"],["@@d‚c"],["@@eÀ‚C@b‚“‰"],["@@f‡…Xwkbr–Ä`qg"],["@@^jtW‘Q"],["@@~ Y]c"],["@@G`ĔN^_¿Z‚ÃM"],["@@iX¶B‹Y"],["@@„YƒZ"],["@@L_{Epf"],["@@^WqCT\\"],["@@\\[“‹§t|”¤_"],["@@m`n_"],["@@Ïxnj{q_×^Giip"],["@@@œé^B†‡ntˆaÊU—˜Ÿ]x ¯ÄPIJ­°h€ʙK³†VˆÕ@Y~†|EvĹsDŽ¦­L^p²ŸÒG ’Ël]„xxÄ_˜fT¤Ď¤cŽœP„–C¨¸TVjbgH²sdÎdHt`Bˆ—²¬GJję¶[ÐhjeXdlwhšðSȦªVÊπ‹Æ‘Z˜ÆŶ®²†^ŒÎyÅÎcPqń“ĚDMħĜŁH­ˆk„çvV[ij¼W–‚YÀäĦ’‘`XlžR`žôLUVžfK–¢†{NZdĒª’YĸÌÚJRr¸SA|ƴgŴĴÆbvªØX~†źBŽ|¦ÕœEž¤Ð`\\|Kˆ˜UnnI]¤ÀÂĊnŎ™R®Ő¿¶\\ÀøíDm¦ÎbŨab‰œaĘ\\ľã‚¸a˜tÎSƐ´©v\\ÖÚÌǴ¤Â‡¨JKr€Z_Z€fjþhPkx€`Y”’RIŒjJcVf~sCN¤ ˆE‚œhæm‰–sHy¨SðÑÌ\\\\ŸĐRZk°IS§fqŒßýáЍÙÉÖ[^¯ǤŲ„ê´\\¦¬ĆPM¯£Ÿˆ»uïpùzEx€žanµyoluqe¦W^£ÊL}ñrkqWňûP™‰UP¡ôJŠoo·ŒU}£Œ„[·¨@XŒĸŸ“‹‹DXm­Ûݏº‡›GU‹CÁª½{íĂ^cj‡k“¶Ã[q¤“LÉö³cux«zZfƒ²BWÇ®Yß½ve±ÃC•ý£W{Ú^’q^sÑ·¨‹ÍOt“¹·C¥‡GD›rí@wÕKţ݋˜Ÿ«V·i}xËÍ÷‘i©ĝ‡ɝǡ]ƒˆ{c™±OW‹³Ya±Ÿ‰_穂Hžĕoƫ€Ňqƒr³‰Lys[„ñ³¯OS–ďOMisZ†±ÅFC¥Pq{‚Ã[Pg}\\—¿ghćO…•k^ģÁFıĉĥM­oEqqZûěʼn³F‘¦oĵ—hŸÕP{¯~TÍlª‰N‰ßY“Ð{Ps{ÃVU™™eĎwk±ʼnVÓ½ŽJãÇÇ»Jm°dhcÀff‘dF~ˆ€ĀeĖ€d`sx² šƒ®EżĀdQ‹Âd^~ăÔHˆ¦\\›LKpĄVez¤NP ǹӗR™ÆąJSh­a[¦´Âghwm€BÐ¨źhI|žVVŽ—Ž|p] Â¼èNä¶ÜBÖ¼“L`‚¼bØæŒKV”ŸpoœúNZÞÒKxpw|ÊEMnzEQšŽIZ”ŽZ‡NBˆčÚFÜçmĩ‚WĪñt‘ÞĵÇñZ«uD‚±|Əlij¥ãn·±PmÍa‰–da‡ CL‡Ǒkùó¡³Ï«QaċϑOÃ¥ÕđQȥċƭy‹³ÃA"]],"encodeOffsets":[[[123686,41445]],[[126019,40435]],[[124393,40128]],[[126117,39963]],[[125322,40140]],[[126686,40700]],[[126041,40374]],[[125584,40168]],[[125453,40165]],[[125362,40214]],[[125280,40291]],[[125774,39997]],[[125976,40496]],[[125822,39993]],[[125509,40217]],[[122731,40949]]]}},{"type":"Feature","id":"220000","properties":{"id":"220000","cp":[125.3245,43.886841],"name":"吉林","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@‘p䔳PClƒFbbÍzš€wBG’ĭ€Z„Åi“»ƒlY­ċ²SgŽkÇ£—^S‰“qd¯•‹R…©éŽ£¯S†\\cZ¹iűƏCuƍÓX‡oR}“M^o•£…R}oªU­F…uuXHlEŕ‡€Ï©¤ÛmTŽþ¤D–²ÄufàÀ­XXȱAe„yYw¬dvõ´KÊ£”\\rµÄl”iˆdā]|DÂVŒœH¹ˆÞ®ÜWnŒC”Œķ W‹§@\\¸‹ƒ~¤‹Vp¸‰póIO¢ŠVOšŇürXql~òÉK]¤¥Xrfkvzpm¶bwyFoúvð‡¼¤ N°ąO¥«³[ƒéǡű_°Õ\\ÚÊĝŽþâőàerR¨­JYlďQ[ ÏYëЧTGz•tnŠß¡gFkMŸāGÁ¤ia É‰™È¹`\\xs€¬dĆkNnuNUŠ–užP@‚vRY¾•–\\¢…ŒGªóĄ~RãÖÎĢù‚đŴÕhQŽxtcæëSɽʼníëlj£ƍG£nj°KƘµDsØÑpyƸ®¿bXp‚]vbÍZuĂ{nˆ^IüœÀSք”¦EŒvRÎûh@℈[‚Əȉô~FNr¯ôçR±ƒ­HÑl•’Ģ–^¤¢‚OðŸŒævxsŒ]ÞÁTĠs¶¿âƊGW¾ìA¦·TѬ†è¥€ÏÐJ¨¼ÒÖ¼ƒƦɄxÊ~S–tD@ŠĂ¼Ŵ¡jlºWžvЉˆzƦZЎ²CH— „Axiukd‹ŒGgetqmcžÛ£Ozy¥cE}|…¾cZ…k‚‰¿uŐã[oxGikfeäT@…šSUwpiÚFM©’£è^ڟ‚`@v¶eň†f h˜eP¶žt“äOlÔUgƒÞzŸU`lœ}ÔÆUvØ_Ō¬Öi^ĉi§²ÃŠB~¡Ĉ™ÚEgc|DC_Ȧm²rBx¼MÔ¦ŮdĨÃâYx‘ƘDVÇĺĿg¿cwÅ\\¹˜¥Yĭlœ¤žOv†šLjM_a W`zļMž·\\swqÝSA‡š—q‰Śij¯Š‘°kŠRē°wx^Đkǂғ„œž“œŽ„‹\\]˜nrĂ}²ĊŲÒøãh·M{yMzysěnĒġV·°“G³¼XÀ““™¤¹i´o¤ŃšŸÈ`̃DzÄUĞd\\i֚ŒˆmÈBĤÜɲDEh LG¾ƀľ{WaŒYÍȏĢĘÔRîĐj‹}Ǟ“ccj‡oUb½š{“h§Ǿ{K‹ƖµÎ÷žGĀÖŠåưÎs­l›•yiē«‹`姝H¥Ae^§„GK}iã\\c]v©ģZ“mÃ|“[M}ģTɟĵ‘Â`À–çm‰‘FK¥ÚíÁbXš³ÌQґHof{‰]e€pt·GŋĜYünĎųVY^’˜ydõkÅZW„«WUa~U·Sb•wGçǑ‚“iW^q‹F‚“›uNĝ—·Ew„‹UtW·Ýďæ©PuqEzwAV•—XR‰ãQ`­©GŒM‡ehc›c”ďϝd‡©ÑW_ϗYƅŒ»…é\\ƒɹ~ǙG³mØ©BšuT§Ĥ½¢Ã_ý‘L¡‘ýŸqT^rme™\\Pp•ZZbƒyŸ’uybQ—efµ]UhĿDCmûvašÙNSkCwn‰cćfv~…Y‹„ÇG"],"encodeOffsets":[[130196,42528]]}},{"type":"Feature","id":"230000","properties":{"id":"230000","cp":[128.642464,46.756967],"name":"黑龙江","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@UƒµNÿ¥īè灋•HÍøƕ¶LŒǽ|g¨|”™Ža¾pViˆdd”~ÈiŒíďÓQġėǐZ΋ŽXb½|ſÃH½ŸKFgɱCģÛÇA‡n™‹jÕc[VĝDZÃ˄Ç_™ £ń³pŽj£º”š¿”»WH´¯”U¸đĢmžtĜyzzNN|g¸÷äűѱĉā~mq^—Œ[ƒ”››”ƒǁÑďlw]¯xQĔ‰¯l‰’€°řĴrŠ™˜BˆÞTxr[tޏĻN_yŸX`biN™Ku…P›£k‚ZĮ—¦[ºxÆÀdhŽĹŀUÈƗCw’áZħÄŭcÓ¥»NAw±qȥnD`{ChdÙFćš}¢‰A±Äj¨]ĊÕjŋ«×`VuÓś~_kŷVÝyh„“VkÄãPs”Oµ—fŸge‚Ň…µf@u_Ù ÙcŸªNªÙEojVx™T@†ãSefjlwH\\pŏäÀvŠŽlY†½d{†F~¦dyz¤PÜndsrhf‹HcŒvlwjFœ£G˜±DύƥY‡yϊu¹XikĿ¦ÏqƗǀOŜ¨LI|FRĂn sª|Cš˜zxAè¥bœfudTrFWÁ¹Am|˜ĔĕsķÆF‡´Nš‰}ć…UŠÕ@Áijſmužç’uð^ÊýowŒFzØÎĕNőžǏȎôªÌŒDŽàĀÄ˄ĞŀƒʀĀƘŸˮȬƬĊ°ƒUŸzou‡xe]}Ž…AyȑW¯ÌmK‡“Q]‹Īºif¸ÄX|sZt|½ÚUΠlkš^p{f¤lˆºlÆW –€A²˜PVܜPH”Êâ]ÎĈÌÜk´\\@qàsĔÄQºpRij¼èi†`¶—„bXƒrBgxfv»ŽuUiˆŒ^v~”J¬mVp´£Œ´VWrnP½ì¢BX‚¬h™ŠðX¹^TjVœŠriªj™tŊÄm€tPGx¸bgRšŽsT`ZozÆO]’ÒFô҆Oƒ‡ŊŒvŞ”p’cGŒêŠsx´DR–Œ{A†„EOr°Œ•žx|íœbˆ³Wm~DVjºéNN†Ëܲɶ­GƒxŷCStŸ}]ûō•SmtuÇÃĕN•™āg»šíT«u}ç½BĵÞʣ¥ëÊ¡Mێ³ãȅ¡ƋaǩÈÉQ‰†G¢·lG|›„tvgrrf«†ptęŘnŠÅĢr„I²¯LiØsPf˜_vĠd„xM prʹšL¤‹¤‡eˌƒÀđK“žïÙVY§]I‡óáĥ]ķ†Kˆ¥Œj|pŇ\\kzţ¦šnņäÔVĂîά|vW’®l¤èØr‚˜•xm¶ă~lÄƯĄ̈́öȄEÔ¤ØQĄ–Ą»ƢjȦOǺ¨ìSŖÆƬy”Qœv`–cwƒZSÌ®ü±DŽ]ŀç¬B¬©ńzƺŷɄeeOĨS’Œfm Ċ‚ƀP̎ēz©Ċ‚ÄÕÊmgŸÇsJ¥ƔˆŊśæ’΁Ñqv¿íUOµª‰ÂnĦÁ_½ä@ê텣P}Ġ[@gġ}g“ɊדûÏWXá¢užƻÌsNͽƎÁ§č՛AēeL³àydl›¦ĘVçŁpśdžĽĺſʃQíÜçÛġԏsĕ¬—Ǹ¯YßċġHµ ¡eå`ļƒrĉŘóƢFì“ĎWøxÊk†”ƈdƬv|–I|·©NqńRŀƒ¤é”eŊœŀ›ˆàŀU²ŕƀB‚Q£Ď}L¹Îk@©ĈuǰųǨ”Ú§ƈnTËÇéƟÊcfčŤ^Xm‡—HĊĕË«W·ċëx³ǔķÐċJā‚wİ_ĸ˜Ȁ^ôWr­°oú¬Ħ…ŨK~”ȰCĐ´Ƕ£’fNÎèâw¢XnŮeÂÆĶŽ¾¾xäLĴĘlļO¤ÒĨA¢Êɚ¨®‚ØCÔ ŬGƠ”ƦYĜ‡ĘÜƬDJ—g_ͥœ@čŅĻA“¶¯@wÎqC½Ĉ»NŸăëK™ďÍQ“Ùƫ[«Ãí•gßÔÇOÝáW‘ñuZ“¯ĥ€Ÿŕā¡ÑķJu¤E Ÿå¯°WKɱ_d_}}vyŸõu¬ï¹ÓU±½@gÏ¿rýD‰†g…Cd‰µ—°MFYxw¿CG£‹Rƛ½Õ{]L§{qqąš¿BÇƻğëšܭNJË|c²}Fµ}›ÙRsÓpg±ŠQNqǫŋRwŕnéÑÉKŸ†«SeYR…ŋ‹@{¤SJ}šD Ûǖ֍Ÿ]gr¡µŷjqWÛham³~S«“„›Þ]"]],"encodeOffsets":[[[134456,44547]]]}},{"type":"Feature","id":"320000","properties":{"id":"320000","cp":[119.767413,33.041544],"name":"江苏","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@cþÅPiŠ`ZŸRu¥É\\]~°ŽY`µ†Óƒ^phÁbnÀşúŽòa–ĬºTÖŒb‚˜e¦¦€{¸ZâćNpŒ©žHr|^ˆmjhŠSEb\\afv`sz^lkŽlj‹Ätg‹¤D˜­¾Xš¿À’|ДiZ„ȀåB·î}GL¢õcßjaŸyBFµÏC^ĭ•cÙt¿sğH]j{s©HM¢ƒQnDÀ©DaÜތ·jgàiDbPufjDk`dPOîƒhw¡ĥ‡¥šG˜ŸP²ĐobºrY†„î¶aHŢ´ ]´‚rılw³r_{£DB_Ûdåuk|ˆŨ¯F Cºyr{XFy™e³Þċ‡¿Â™kĭB¿„MvÛpm`rÚã”@ƹhågËÖƿxnlč¶Åì½Ot¾dJlŠVJʜǀœŞqvnOŠ^ŸJ”Z‘ż·Q}ê͎ÅmµÒ]Žƍ¦Dq}¬R^èĂ´ŀĻĊIԒtžIJyQŐĠMNtœR®òLh‰›Ěs©»œ}OӌGZz¶A\\jĨFˆäOĤ˜HYš†JvÞHNiÜaϚɖnFQlšNM¤ˆB´ĄNöɂtp–Ŭdf先‹qm¿QûŠùއÚb¤uŃJŴu»¹Ą•lȖħŴw̌ŵ²ǹǠ͛hĭłƕrçü±Y™xci‡tğ®jű¢KOķ•Coy`å®VTa­_Ā]ŐÝɞï²ʯÊ^]afYǸÃĆēĪȣJđ͍ôƋĝÄ͎ī‰çÛɈǥ£­ÛmY`ó£Z«§°Ó³QafusNıDž_k}¢m[ÝóDµ—¡RLčiXy‡ÅNïă¡¸iĔϑNÌŕoēdōîåŤûHcs}~Ûwbù¹£¦ÓCt‹OPrƒE^ÒoŠg™ĉIµžÛÅʹK…¤½phMŠü`o怆ŀ"],"encodeOffsets":[[121740,32276]]}},{"type":"Feature","id":"330000","properties":{"id":"330000","cp":[120.153576,29.287459],"name":"浙江","childNum":45},"geometry":{"type":"MultiPolygon","coordinates":[["@@E^dQ]K"],["@@jX^j‡"],["@@sfŠbU‡"],["@@qP\\xz[ck"],["@@‘Rƒ¢‚FX}°[s_"],["@@Cbœ\\—}"],["@@e|v\\la{u"],["@@v~u}"],["@@QxÂF¯}"],["@@¹nŒvÞs¯o"],["@@rSkUEj"],["@@bi­ZŒP"],["@@p[}INf"],["@@À¿€"],["@@¹dnbŒ…"],["@@rSŸBnR"],["@@g~h}"],["@@FlEk"],["@@OdPc"],["@@v[u\\"],["@@FjâL~wyoo~›sµL–\\"],["@@¬e¹aNˆ"],["@@\\nÔ¡q]L³ë\\ÿ®ŒQ֎"],["@@ÊA­©[¬"],["@@KxŒv­"],["@@@hlIk]"],["@@pW{o||j"],["@@Md|_mC"],["@@¢…X£ÏylD¼XˆtH"],["@@hlÜ[LykAvyfw^Ež›¤"],["@@fp¤Mus“R"],["@@®_ma~•LÁ¬šZ"],["@@iM„xZ"],["@@ZcYd"],["@@Z~dOSo|A¿qZv"],["@@@`”EN¡v"],["@@|–TY{"],["@@@n@m"],["@@XWkCT\\"],["@@ºwšZRkĕWO¢"],["@@™X®±Grƪ\\ÔáXq{‹"],["@@ůTG°ĄLHm°UC‹"],["@@¤Ž€aÜx~}dtüGæţŎíĔcŖpMËВj碷ðĄÆMzˆjWKĎ¢Q¶˜À_꒔_Bı€i«pZ€gf€¤Nrq]§ĂN®«H±‡yƳí¾×ŸīàLłčŴǝĂíÀBŖÕªˆŠÁŖHŗʼnåqûõi¨hÜ·ƒñt»¹ýv_[«¸m‰YL¯‰Qª…mĉÅdMˆ•gÇjcº«•ęœ¬­K­´ƒB«Âącoċ\\xKd¡gěŧ«®á’[~ıxu·Å”KsËɏc¢Ù\\ĭƛëbf¹­ģSƒĜkáƉÔ­ĈZB{ŠaM‘µ‰fzʼnfåÂŧįƋǝÊĕġć£g³ne­ą»@­¦S®‚\\ßðCšh™iqªĭiAu‡A­µ”_W¥ƣO\\lċĢttC¨£t`ˆ™PZäuXßBs‡Ļyek€OđġĵHuXBšµ]׌‡­­\\›°®¬F¢¾pµ¼kŘó¬Wät’¸|@ž•L¨¸µr“ºù³Ù~§WI‹ŸZWŽ®’±Ð¨ÒÉx€`‰²pĜ•rOògtÁZ}þÙ]„’¡ŒŸFK‚wsPlU[}¦Rvn`hq¬\\”nQ´ĘRWb”‚_ rtČFI֊kŠŠĦPJ¶ÖÀÖJĈĄTĚòžC ²@Pú…Øzœ©PœCÈÚœĒ±„hŖ‡l¬â~nm¨f©–iļ«m‡nt–u†ÖZÜÄj“ŠLŽ®E̜Fª²iÊxبžIÈhhst"],["@@o\\V’zRZ}y"],["@@†@°¡mۛGĕ¨§Ianá[ýƤjfæ‡ØL–•äGr™"]],"encodeOffsets":[[[125592,31553]],[[125785,31436]],[[125729,31431]],[[125513,31380]],[[125223,30438]],[[125115,30114]],[[124815,29155]],[[124419,28746]],[[124095,28635]],[[124005,28609]],[[125000,30713]],[[125111,30698]],[[125078,30682]],[[125150,30684]],[[124014,28103]],[[125008,31331]],[[125411,31468]],[[125329,31479]],[[125626,30916]],[[125417,30956]],[[125254,30976]],[[125199,30997]],[[125095,31058]],[[125083,30915]],[[124885,31015]],[[125218,30798]],[[124867,30838]],[[124755,30788]],[[124802,30809]],[[125267,30657]],[[125218,30578]],[[125200,30562]],[[124968,30474]],[[125167,30396]],[[124955,29879]],[[124714,29781]],[[124762,29462]],[[124325,28754]],[[123990,28459]],[[125366,31477]],[[125115,30363]],[[125369,31139]],[[122495,31878]],[[125329,30690]],[[125192,30787]]]}},{"type":"Feature","id":"340000","properties":{"id":"340000","cp":[117.283042,31.26119],"name":"安徽","childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@^iuLX^"],["@@‚e©Ehl"],["@@°ZÆëϵmkǀwÌÕæhºgBĝâqÙĊz›ÖgņtÀÁÊÆá’hEz|WzqD¹€Ÿ°E‡ŧl{ævÜcA`¤C`|´qžxIJkq^³³ŸGšµbƒíZ…¹qpa±ď OH—¦™Ħˆx¢„gPícOl_iCveaOjCh߸i݋bÛªCC¿€m„RV§¢A|t^iĠGÀtÚs–d]ĮÐDE¶zAb àiödK¡~H¸íæAžǿYƒ“j{ď¿‘™À½W—®£ChŒÃsiŒkkly]_teu[bFa‰Tig‡n{]Gqªo‹ĈMYá|·¥f¥—őaSÕė™NµñĞ«ImŒ_m¿Âa]uĜp …Z_§{Cƒäg¤°r[_Yj‰ÆOdý“[ŽI[á·¥“Q_n‡ùgL¾mv™ˊBÜÆ¶ĊJhšp“c¹˜O]iŠ]œ¥ jtsggJǧw×jÉ©±›EFˍ­‰Ki”ÛÃÕYv…s•ˆm¬njĻª•§emná}k«ŕˆƒgđ²Ù›DǤ›í¡ªOy›†×Où±@DŸñSęćăÕIÕ¿IµĥO‰‰jNÕËT¡¿tNæŇàåyķrĕq§ÄĩsWÆßŽF¶žX®¿‰mŒ™w…RIޓfßoG‘³¾©uyH‘į{Ɓħ¯AFnuP…ÍÔzšŒV—dàôº^Ðæd´€‡oG¤{S‰¬ćxã}›ŧ×Kǥĩ«žÕOEзÖdÖsƘѨ[’Û^Xr¢¼˜§xvěƵ`K”§ tÒ´Cvlo¸fzŨð¾NY´ı~ÉĔē…ßúLÃϖ_ÈÏ|]ÂÏFl”g`bšežž€n¾¢pU‚h~ƴ˶_‚r sĄ~cž”ƈ]|r c~`¼{À{ȒiJjz`îÀT¥Û³…]’u}›f…ïQl{skl“oNdŸjŸäËzDvčoQŠďHI¦rb“tHĔ~BmlRš—V_„ħTLnñH±’DžœL‘¼L˜ªl§Ťa¸ŒĚlK²€\\RòvDcÎJbt[¤€D@®hh~kt°ǾzÖ@¾ªdb„YhüóZ ň¶vHrľ\\ʗJuxAT|dmÀO„‹[ÃԋG·ĚąĐlŪÚpSJ¨ĸˆLvÞcPæķŨŽ®mАˆálŸwKhïgA¢ųƩޖ¤OȜm’°ŒK´"]],"encodeOffsets":[[[121722,32278]],[[119475,30423]],[[119168,35472]]]}},{"type":"Feature","id":"350000","properties":{"id":"350000","cp":[118.306239,26.075302],"name":"福建","childNum":18},"geometry":{"type":"MultiPolygon","coordinates":[["@@“zht´‡]"],["@@aj^~ĆG—©O"],["@@ed¨„C}}i"],["@@@vˆPGsQ"],["@@‰sBz‚ddW]Q"],["@@SލQ“{"],["@@NŽVucW"],["@@qptBAq"],["@@‰’¸[mu"],["@@Q\\pD]_"],["@@jSwUadpF"],["@@eXª~ƒ•"],["@@AjvFso"],["@@fT–›_Çí\\Ÿ™—v|ba¦jZÆy€°"],["@@IjJi"],["@@wJI€ˆxš«¼AoNe{M­"],["@@K‰±¡Óˆ”ČäeZ"],["@@k¡¹Eh~c®wBk‹UplÀ¡I•~Māe£bN¨gZý¡a±Öcp©PhžI”Ÿ¢Qq…ÇGj‹|¥U™ g[Ky¬ŏ–v@OpˆtÉEŸF„\\@ åA¬ˆV{Xģ‰ĐBy…cpě…¼³Ăp·¤ƒ¥o“hqqÚ¡ŅLsƒ^ᗞ§qlŸÀhH¨MCe»åÇGD¥zPO£čÙkJA¼ß–ėu›ĕeûҍiÁŧSW¥˜QŠûŗ½ùěcݧSùĩąSWó«íęACµ›eR—åǃRCÒÇZÍ¢‹ź±^dlsŒtjD¸•‚ZpužÔâÒH¾oLUêÃÔjjēò´ĄW‚ƛ…^Ñ¥‹ĦŸ@Çò–ŠmŒƒOw¡õyJ†yD}¢ďÑÈġfŠZd–a©º²z£šN–ƒjD°Ötj¶¬ZSÎ~¾c°¶Ðm˜x‚O¸¢Pl´žSL|¥žA†ȪĖM’ņIJg®áIJČĒü` ŽQF‡¬h|ÓJ@zµ |ê³È ¸UÖŬŬÀEttĸr‚]€˜ðŽM¤ĶIJHtÏ A’†žĬkvsq‡^aÎbvŒd–™fÊòSD€´Z^’xPsÞrv‹ƞŀ˜jJd×ŘÉ ®A–ΦĤd€xĆqAŒ†ZR”ÀMźŒnĊ»ŒİÐZ— YX–æJŠyĊ²ˆ·¶q§·–K@·{s‘Xãô«lŗ¶»o½E¡­«¢±¨Yˆ®Ø‹¶^A™vWĶGĒĢžPlzfˆļŽtàAvWYãšO_‡¤sD§ssČġ[kƤPX¦Ž`¶“ž®ˆBBvĪjv©šjx[L¥àï[F…¼ÍË»ğV`«•Ip™}ccÅĥZE‹ãoP…´B@ŠD—¸m±“z«Ƴ—¿å³BRضˆœWlâþäą`“]Z£Tc— ĹGµ¶H™m@_©—kŒ‰¾xĨ‡ôȉðX«½đCIbćqK³Á‹Äš¬OAwã»aLʼn‡ËĥW[“ÂGI—ÂNxij¤D¢ŽîĎÎB§°_JœGsƒ¥E@…¤uć…P‘å†cuMuw¢BI¿‡]zG¹guĮck\\_"]],"encodeOffsets":[[[123250,27563]],[[122541,27268]],[[123020,27189]],[[122916,27125]],[[122887,26845]],[[122808,26762]],[[122568,25912]],[[122778,26197]],[[122515,26757]],[[122816,26587]],[[123388,27005]],[[122450,26243]],[[122578,25962]],[[121255,25103]],[[120987,24903]],[[122339,25802]],[[121042,25093]],[[122439,26024]]]}},{"type":"Feature","id":"360000","properties":{"id":"360000","cp":[115.592151,27.676493],"name":"江西","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ĢĨƐgÂMD~ņªe^\\^§„ý©j׍cZ†Ø¨zdÒa¶ˆlҍJŒìõ`oz÷@¤u޸´†ôęöY¼‰HČƶajlÞƩ¥éZ[”|h}^U Œ ¥p„ĄžƦO lt¸Æ €Q\\€ŠaÆ|CnÂOjt­ĚĤd’ÈŒF`’¶„@Ð딠¦ōҞ¨Sêv†HĢûXD®…QgėWiØPÞìºr¤dž€NĠ¢l–•ĄtZoœCƞÔºCxrpĠV®Ê{f_Y`_ƒeq’’®Aot`@o‚DXfkp¨|Šs¬\\D‘ÄSfè©Hn¬…^DhÆyøJh“ØxĢĀLʈ„ƠPżċĄwȠ̦G®ǒĤäTŠÆ~ĦwŠ«|TF¡Šn€c³Ïå¹]ĉđxe{ÎӐ†vOEm°BƂĨİ|G’vz½ª´€H’àp”eJ݆Qšxn‹ÀŠW­žEµàXÅĪt¨ÃĖrÄwÀFÎ|ňÓMå¼ibµ¯»åDT±m[“r«_gŽmQu~¥V\\OkxtL E¢‹ƒ‘Ú^~ýê‹Pó–qo슱_Êw§ÑªåƗ⼋mĉŹ‹¿NQ“…YB‹ąrwģcÍ¥B•Ÿ­ŗÊcØiI—žƝĿuŒqtāwO]‘³YCñTeɕš‹caub͈]trlu€ī…B‘ПGsĵıN£ï—^ķqss¿FūūV՟·´Ç{éĈý‰ÿ›OEˆR_ŸđûIċâJh­ŅıN‘ȩĕB…¦K{Tk³¡OP·wn—µÏd¯}½TÍ«YiµÕsC¯„iM•¤™­•¦¯P|ÿUHv“he¥oFTu‰õ\\ŽOSs‹MòđƇiaºćXŸĊĵà·çhƃ÷ǜ{‘ígu^›đg’m[×zkKN‘¶Õ»lčÓ{XSƉv©_ÈëJbVk„ĔVÀ¤P¾ºÈMÖxlò~ªÚàGĂ¢B„±’ÌŒK˜y’áV‡¼Ã~­…`g›ŸsÙfI›Ƌlę¹e|–~udjˆuTlXµf`¿JdŠ[\\˜„L‚‘²"],"encodeOffsets":[[116689,26234]]}},{"type":"Feature","id":"370000","properties":{"id":"370000","cp":[118.000923,36.275807],"name":"山东","childNum":13},"geometry":{"type":"MultiPolygon","coordinates":[["@@Xjd]{K"],["@@itbFHy"],["@@HlGk"],["@@T‚ŒGŸy"],["@@K¬˜•‹U"],["@@WdXc"],["@@PtOs"],["@@•LnXhc"],["@@ppVƒu]Or"],["@@cdzAUa"],["@@udRhnCI‡"],["@@ˆoIƒpR„"],["@@Ľč{fzƤî’Kš–ÎMĮ]†—ZFˆ½Y]â£ph’™š¶¨râøÀ†ÎǨ¤^ºÄ”Gzˆ~grĚĜlĞÆ„LĆdž¢Îo¦–cv“Kb€gr°Wh”mZp ˆL]LºcU‰Æ­n”żĤÌǜbAnrOAœ´žȊcÀbƦUØrĆUÜøœĬƞ†š˜Ez„VL®öØBkŖÝĐ˹ŧ̄±ÀbÎɜnb²ĦhņBĖ›žįĦåXćì@L¯´ywƕCéõė ƿ¸‘lµ¾Z|†ZWyFYŸ¨Mf~C¿`€à_RÇzwƌfQnny´INoƬˆèôº|sT„JUš›‚L„îVj„ǎ¾Ē؍‚Dz²XPn±ŴPè¸ŔLƔÜƺ_T‘üÃĤBBċȉöA´fa„˜M¨{«M`‡¶d¡ô‰Ö°šmȰBÔjjŒ´PM|”c^d¤u•ƒ¤Û´Œä«ƢfPk¶Môlˆ]Lb„}su^ke{lC‘…M•rDŠÇ­]NÑFsmoõľH‰yGă{{çrnÓE‰‹ƕZGª¹Fj¢ïW…uøCǷ돡ąuhÛ¡^Kx•C`C\\bÅxì²ĝÝ¿_N‰īCȽĿåB¥¢·IŖÕy\\‡¹kx‡Ã£Č×GDyÕ¤ÁçFQ¡„KtŵƋ]CgÏAùSed‡cÚź—ŠuYfƒyMmhUWpSyGwMPqŀ—›Á¼zK›¶†G•­Y§Ëƒ@–´śÇµƕBmœ@Io‚g——Z¯u‹TMx}C‘‰VK‚ï{éƵP—™_K«™pÛÙqċtkkù]gŽ‹Tğwo•ɁsMõ³ă‡AN£™MRkmEʕč™ÛbMjÝGu…IZ™—GPģ‡ãħE[iµBEuŸDPԛ~ª¼ętŠœ]ŒûG§€¡QMsğNPŏįzs£Ug{đJĿļā³]ç«Qr~¥CƎÑ^n¶ÆéÎR~ݏY’I“] P‰umŝrƿ›‰›Iā‹[x‰edz‹L‘¯v¯s¬ÁY…~}…ťuٌg›ƋpÝĄ_ņī¶ÏSR´ÁP~ž¿Cyžċßdwk´Ss•X|t‰`Ä Èð€AªìÎT°¦Dd–€a^lĎDĶÚY°Ž`ĪŴǒˆ”àŠv\\ebŒZH„ŖR¬ŢƱùęO•ÑM­³FۃWp[ƒ"]],"encodeOffsets":[[[123806,39303]],[[123821,39266]],[[123742,39256]],[[123702,39203]],[[123649,39066]],[[123847,38933]],[[123580,38839]],[[123894,37288]],[[123043,36624]],[[123344,38676]],[[123522,38857]],[[123628,38858]],[[118260,36742]]]}},{"type":"Feature","id":"410000","properties":{"id":"410000","cp":[113.665412,33.757975],"name":"河南","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@•ýL™ùµP³swIÓxcŢĞð†´E®žÚPt†ĴXØx¶˜@«ŕŕQGƒ‹Yfa[şu“ßǩ™đš_X³ijÕčC]kbc•¥CS¯ëÍB©÷‹–³­Siˆ_}m˜YTtž³xlàcȂzÀD}ÂOQ³ÐTĨ¯†ƗòËŖ[hœł‹Ŧv~††}ÂZž«¤lPǕ£ªÝŴÅR§ØnhcŒtâk‡nύ­ľŹUÓÝdKuķ‡I§oTũÙďkęĆH¸ÓŒ\\ăŒ¿PcnS{wBIvɘĽ[GqµuŸŇôYgûƒZcaŽ©@½Õǽys¯}lgg@­C\\£as€IdÍuCQñ[L±ęk·‹ţb¨©kK—’»›KC²‘òGKmĨS`ƒ˜UQ™nk}AGē”sqaJ¥ĐGR‰ĎpCuÌy ã iMc”plk|tRk†ðœev~^‘´†¦ÜŽSí¿_iyjI|ȑ|¿_»d}qŸ^{“Ƈdă}Ÿtqµ`Ƴĕg}V¡om½fa™Ço³TTj¥„tĠ—Ry”K{ùÓjuµ{t}uËR‘iŸvGŠçJFjµŠÍyqΘàQÂFewixGw½Yŷpµú³XU›½ġy™łå‰kÚwZXˆ·l„¢Á¢K”zO„Λ΀jc¼htoDHr…|­J“½}JZ_¯iPq{tę½ĕ¦Zpĵø«kQ…Ťƒ]MÛfaQpě±ǽ¾]u­Fu‹÷nƒ™čįADp}AjmcEǒaª³o³ÆÍSƇĈÙDIzˑ赟^ˆKLœ—i—Þñ€[œƒaA²zz‰Ì÷Dœ|[šíijgf‚ÕÞd®|`ƒĆ~„oĠƑô³Ŋ‘D×°¯CsŠøÀ«ì‰UMhTº¨¸ǡîS–Ô„DruÂÇZ•ÖEŽ’vPZ„žW”~؋ÐtĄE¢¦Ðy¸bŠô´oŬ¬Ž²Ês~€€]®tªašpŎJ¨Öº„_ŠŔ–`’Ŗ^Ѝ\\Ĝu–”~m²Ƹ›¸fW‰ĦrƔ}Î^gjdfÔ¡J}\\n C˜¦þWxªJRÔŠu¬ĨĨmF†dM{\\d\\ŠYÊ¢ú@@¦ª²SŠÜsC–}fNècbpRmlØ^g„d¢aÒ¢CZˆZxvÆ¶N¿’¢T@€uCœ¬^ĊðÄn|žlGl’™Rjsp¢ED}€Fio~ÔNŽ‹„~zkĘHVsDzßjƒŬŒŠŢ`Pûàl¢˜\\ÀœEhŽİgÞē X¼Pk–„|m"],"encodeOffsets":[[118256,37017]]}},{"type":"Feature","id":"420000","properties":{"id":"420000","cp":[113.298572,30.684355],"name":"湖北","childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@AB‚"],["@@lskt"],["@@¾«}{ra®pîÃ\\™›{øCŠËyyB±„b\\›ò˜Ý˜jK›‡L ]ĎĽÌ’JyÚCƈćÎT´Å´pb©È‘dFin~BCo°BĎĚømvŒ®E^vǾ½Ĝ²Ro‚bÜeNŽ„^ĺ£R†¬lĶ÷YoĖ¥Ě¾|sOr°jY`~I”¾®I†{GqpCgyl{‡£œÍƒÍyPL“¡ƒ¡¸kW‡xYlÙæŠšŁĢzœ¾žV´W¶ùŸo¾ZHxjwfx„GNÁ•³Xéæl¶‰EièIH‰ u’jÌQ~v|sv¶Ôi|ú¢Fh˜Qsğ¦ƒSiŠBg™ÐE^ÁÐ{–čnOÂȞUÎóĔ†ÊēIJ}Z³½Mŧïeyp·uk³DsѨŸL“¶_œÅuèw»—€¡WqÜ]\\‘Ò§tƗcÕ¸ÕFÏǝĉăxŻČƟO‡ƒKÉġÿ×wg”÷IÅzCg†]m«ªGeçÃTC’«[‰t§{loWeC@ps_Bp‘­r‘„f_``Z|ei¡—oċMqow€¹DƝӛDYpûs•–‹Ykıǃ}s¥ç³[§ŸcYЧHK„«Qy‰]¢“wwö€¸ïx¼ņ¾Xv®ÇÀµRĠЋžHMž±cÏd„ƒǍũȅȷ±DSyúĝ£ŤĀàtÖÿï[îb\\}pĭÉI±Ñy…¿³x¯N‰o‰|¹H™ÏÛm‹júË~Tš•u˜ęjCöAwě¬R’đl¯ Ñb­‰ŇT†Ŀ_[Œ‘IčĄʿnM¦ğ\\É[T·™k¹œ©oĕ@A¾w•ya¥Y\\¥Âaz¯ãÁ¡k¥ne£Ûw†E©Êō¶˓uoj_Uƒ¡cF¹­[Wv“P©w—huÕyBF“ƒ`R‹qJUw\\i¡{jŸŸEPïÿ½fć…QÑÀQ{ž‚°‡fLԁ~wXg—ītêݾ–ĺ‘Hdˆ³fJd]‹HJ²…E€ƒoU¥†HhwQsƐ»Xmg±çve›]Dm͂PˆoCc¾‹_h”–høYrŊU¶eD°Č_N~øĹĚ·`z’]Äþp¼…äÌQŒv\\rCŒé¾TnkžŐڀÜa‡“¼ÝƆ̶Ûo…d…ĔňТJq’Pb ¾|JŒ¾fXŠƐîĨ_Z¯À}úƲ‹N_ĒĊ^„‘ĈaŐyp»CÇĕKŠšñL³ŠġMŒ²wrIÒŭxjb[œžn«øœ˜—æˆàƒ ^²­h¯Ú€ŐªÞ¸€Y²ĒVø}Ā^İ™´‚LŠÚm„¥ÀJÞ{JVŒųÞŃx×sxxƈē ģMř–ÚðòIf–Ċ“Œ\\Ʈ±ŒdʧĘD†vČ_Àæ~DŒċ´A®µ†¨ØLV¦êHÒ¤"]],"encodeOffsets":[[[113712,34000]],[[115612,30507]],[[113649,34054]]]}},{"type":"Feature","id":"430000","properties":{"id":"430000","cp":[111.782279,28.09409],"name":"湖南","childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@—n„FTs"],["@@ßÅÆá‰½ÔXr—†CO™“…ËR‘ïÿĩ­TooQyšÓ[‹ŅBE¬–ÎÓXa„į§Ã¸G °ITxp‰úxÚij¥Ïš–̾ŠedžÄ©ĸG…œàGh‚€M¤–Â_U}Ċ}¢pczfŠþg¤€”ÇòAV‘‹M"],["@@©K—ƒA·³CQ±Á«³BUŠƑ¹AŠtćOw™D]ŒJiØSm¯b£‘ylƒ›X…HËѱH•«–‘C^õľA–Å§¤É¥„ïyuǙuA¢^{ÌC´­¦ŷJ£^[†“ª¿‡ĕ~•Ƈ…•N… skóā‡¹¿€ï]ă~÷O§­@—Vm¡‹Qđ¦¢Ĥ{ºjԏŽŒª¥nf´•~ÕoŸž×Ûą‹MąıuZœmZcÒ IJβSÊDŽŶ¨ƚƒ’CÖŎªQؼrŭŽ­«}NÏürʬŒmjr€@ĘrTW ­SsdHzƓ^ÇÂyUi¯DÅYlŹu{hTœ}mĉ–¹¥ě‰Dÿë©ıÓ[Oº£ž“¥ót€ł¹MՄžƪƒ`Pš…Di–ÛUоÅ‌ìˆU’ñB“È£ýhe‰dy¡oċ€`pfmjP~‚kZa…ZsÐd°wj§ƒ@€Ĵ®w~^‚kÀÅKvNmX\\¨a“”сqvíó¿F„¤¡@ũÑVw}S@j}¾«pĂr–ªg àÀ²NJ¶¶Dô…K‚|^ª†Ž°LX¾ŴäPᜣEXd›”^¶›IJÞܓ~‘u¸ǔ˜Ž›MRhsR…e†`ÄofIÔ\\Ø  i”ćymnú¨cj ¢»–GČìƊÿШXeĈ¾Oð Fi ¢|[jVxrIQŒ„_E”zAN¦zLU`œcªx”OTu RLÄ¢dV„i`p˔vŎµªÉžF~ƒØ€d¢ºgİàw¸Áb[¦Zb¦–z½xBĖ@ªpº›šlS¸Ö\\Ĕ[N¥ˀmĎă’J\\‹ŀ`€…ňSڊĖÁĐiO“Ĝ«BxDõĚiv—ž–S™Ì}iùŒžÜnšÐºGŠ{Šp°M´w†ÀÒzJ²ò¨ oTçüöoÛÿñŽőФ‚ùTz²CȆȸǎۃƑÐc°dPÎŸğ˶[Ƚu¯½WM¡­Éž“’B·rížnZŸÒ `‡¨GA¾\\pē˜XhÆRC­üWGġu…T靧Ŏѝ©ò³I±³}_‘‹EÃħg®ęisÁPDmÅ{‰b[Rşs·€kPŸŽƥƒóRo”O‹ŸVŸ~]{g\\“êYƪ¦kÝbiċƵŠGZ»Ěõ…ó·³vŝž£ø@pyö_‹ëŽIkѵ‡bcѧy…×dY؎ªiþž¨ƒ[]f]Ņ©C}ÁN‡»hĻħƏ’ĩ"]],"encodeOffsets":[[[115640,30489]],[[112543,27312]],[[116690,26230]]]}},{"type":"Feature","id":"440000","properties":{"id":"440000","cp":[113.280637,23.125178],"name":"广东","childNum":24},"geometry":{"type":"MultiPolygon","coordinates":[["@@QdˆAua"],["@@ƒlxDLo"],["@@sbhNLo"],["@@Ă āŸ"],["@@WltO[["],["@@Krœ]S"],["@@e„„I]y"],["@@I|„Mym"],["@@ƒÛ³LSŒž¼Y"],["@@nvºB–ëui©`¾"],["@@zdšÛ›Jw®"],["@@†°…¯"],["@@a yAª¸ËJIx،@€ĀHAmßV¡o•fu•o"],["@@šs‰ŗÃÔėAƁ›ZšÄ ~°ČP‚‹äh"],["@@‹¶Ý’Ì‚vmĞh­ı‡Q"],["@@HœŠdSjĒ¢D}war…“u«ZqadYM"],["@@elŒ\\LqqU"],["@@~rMo\\"],["@@f„^ƒC"],["@@øPªoj÷ÍÝħXČx”°Q¨ıXNv"],["@@gÇƳˆŽˆ”oˆŠˆ[~tly"],["@@E–ÆC¿‘"],["@@OŽP"],["@@w‹†đóg‰™ĝ—[³‹¡VÙæÅöM̳¹pÁaËýý©D©Ü“JŹƕģGą¤{Ùū…ǘO²«BƱéA—Ò‰ĥ‡¡«BhlmtÃPµyU¯uc“d·w_bŝcīímGOŽ|KP’ȏ‡ŹãŝIŕŭŕ@Óoo¿ē‹±ß}Ž…ŭ‚ŸIJWÈCőâUâǙI›ğʼn©I›ijEׅÁ”³Aó›wXJþ±ÌŒÜӔĨ£L]ĈÙƺZǾĆĖMĸĤfŒÎĵl•ŨnȈ‘ĐtF”Š–FĤ–‚êk¶œ^k°f¶gŠŽœ}®Fa˜f`vXŲxl˜„¦–ÔÁ²¬ÐŸ¦pqÊ̲ˆi€XŸØRDÎ}†Ä@ZĠ’s„x®AR~®ETtĄZ†–ƈfŠŠHâÒÐA†µ\\S¸„^wĖkRzŠalŽŜ|E¨ÈNĀňZTŒ’pBh£\\ŒĎƀuXĖtKL–¶G|Ž»ĺEļĞ~ÜĢÛĊrˆO˜Ùîvd]nˆ¬VœÊĜ°R֟pM††–‚ƂªFbwžEÀˆ˜©Œž\\…¤]ŸI®¥D³|ˎ]CöAŤ¦…æ’´¥¸Lv¼€•¢ĽBaô–F~—š®²GÌҐEY„„œzk¤’°ahlV՞I^‹šCxĈPŽsB‰ƒºV‰¸@¾ªR²ĨN]´_eavSi‡vc•}p}Đ¼ƌkJœÚe thœ†_¸ ºx±ò_xN›Ë‹²‘@ƒă¡ßH©Ùñ}wkNÕ¹ÇO½¿£ĕ]ly_WìIžÇª`ŠuTÅxYĒÖ¼k֞’µ‚MžjJÚwn\\h‘œĒv]îh|’È›Ƅøègž¸Ķß ĉĈWb¹ƀdéƌNTtP[ŠöSvrCZžžaGuœbo´ŖÒÇА~¡zCI…özx¢„Pn‹•‰Èñ @ŒĥÒ¦†]ƞŠV}³ăĔñiiÄÓVépKG½Ä‘ÓávYo–C·sit‹iaÀy„ŧΡÈYDÑům}‰ý|m[węõĉZÅxUO}÷N¹³ĉo_qtă“qwµŁYلǝŕ¹tïÛUïmRCº…ˆĭ|µ›ÕÊK™½R‘ē ó]‘–GªęAx–»HO£|ām‡¡diď×YïYWªʼnOeÚtĐ«zđ¹T…ā‡úE™á²\\‹ķÍ}jYàÙÆſ¿Çdğ·ùTßÇţʄ¡XgWÀLJğ·¿ÃˆOj YÇ÷Qě‹i"]],"encodeOffsets":[[[117381,22988]],[[116552,22934]],[[116790,22617]],[[116973,22545]],[[116444,22536]],[[116931,22515]],[[116496,22490]],[[116453,22449]],[[113301,21439]],[[118726,21604]],[[118709,21486]],[[113210,20816]],[[115482,22082]],[[113171,21585]],[[113199,21590]],[[115232,22102]],[[115739,22373]],[[115134,22184]],[[113056,21175]],[[119573,21271]],[[119957,24020]],[[115859,22356]],[[116561,22649]],[[116285,22746]]]}},{"type":"Feature","id":"450000","properties":{"id":"450000","cp":[108.320004,22.82402],"name":"广西","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@H– TQ§•A"],["@@ĨʪƒLƒƊDÎĹĐCǦė¸zÚGn£¾›rªŀÜt¬@֛ڈSx~øOŒ˜ŶÐÂæȠ\\„ÈÜObĖw^oބLf¬°bI lTØB̈F£Ć¹gñĤaY“t¿¤VSñœK¸¤nM†¼‚JE±„½¸šŠño‹ÜCƆæĪ^ŠĚQÖ¦^‡ˆˆf´Q†üÜʝz¯šlzUĺš@쇀p¶n]sxtx¶@„~ÒĂJb©gk‚{°‚~c°`ԙ¬rV\\“la¼¤ôá`¯¹LC†ÆbŒxEræO‚v[H­˜„[~|aB£ÖsºdAĐzNÂðsŽÞƔ…Ĥªbƒ–ab`ho¡³F«èVloޤ™ÔRzpp®SŽĪº¨ÖƒºN…ij„d`’a”¦¤F³ºDÎńĀìŠCžĜº¦Ċ•~nS›|gźvZkCÆj°zVÈÁƔ]LÊFZg…čP­kini«‹qǀcz͔Y®¬Ů»qR×ō©DՄ‘§ƙǃŵTÉĩ±ŸıdÑnYY›IJvNĆÌØÜ Öp–}e³¦m‹©iÓ|¹Ÿħņ›|ª¦QF¢Â¬ʖovg¿em‡^ucà÷gՎuŒíÙćĝ}FϼĹ{µHK•sLSđƃr‹č¤[Ag‘oS‹ŇYMÿ§Ç{Fśbky‰lQxĕƒ]T·¶[B…ÑÏGáşşƇe€…•ăYSs­FQ}­Bƒw‘tYğÃ@~…C̀Q ×W‡j˱rÉ¥oÏ ±«ÓÂ¥•ƒ€k—ŽwWűŒmcih³K›~‰µh¯e]lµ›él•E쉕E“ďs‡’mǖŧē`ãògK_ÛsUʝ“ćğ¶hŒöŒO¤Ǜn³Žc‘`¡y‹¦C‘ez€YŠwa™–‘[ďĵűMę§]X˜Î_‚훘Û]é’ÛUćİÕBƣ±…dƒy¹T^džûÅÑŦ·‡PĻþÙ`K€¦˜…¢ÍeœĥR¿Œ³£[~Œäu¼dl‰t‚†W¸oRM¢ď\\zœ}Æzdvň–{ÎXF¶°Â_„ÒÂÏL©Ö•TmuŸ¼ãl‰›īkiqéfA„·Êµ\\őDc¥ÝF“y›Ôć˜c€űH_hL܋êĺШc}rn`½„Ì@¸¶ªVLŒŠhŒ‹\\•Ţĺk~ŽĠið°|gŒtTĭĸ^x‘vK˜VGréAé‘bUu›MJ‰VÃO¡…qĂXËS‰ģãlýàŸ_ju‡YÛÒB†œG^˜é֊¶§ŽƒEG”ÅzěƒƯ¤Ek‡N[kdåucé¬dnYpAyČ{`]þ¯T’bÜÈk‚¡Ġ•vŒàh„ÂƄ¢Jî¶²"]],"encodeOffsets":[[[111707,21520]],[[107619,25527]]]}},{"type":"Feature","id":"460000","properties":{"id":"460000","cp":[109.83119,19.031971],"name":"海南","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@š¦Ŝil¢”XƦ‘ƞò–ïè§ŞCêɕrŧůÇąĻõ™·ĉ³œ̅kÇm@ċȧƒŧĥ‰Ľʉ­ƅſ“ȓÒ˦ŝE}ºƑ[ÍĜȋ gÎfǐÏĤ¨êƺ\\Ɔ¸ĠĎvʄȀœÐ¾jNðĀÒRŒšZdž™zÐŘΰH¨Ƣb²_Ġ "],"encodeOffsets":[[112750,20508]]}},{"type":"Feature","id":"510000","properties":{"id":"510000","cp":[104.065735,30.659462],"name":"四川","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@LqKr"],["@@Š[ĻéV£ž_ţġñpG •réÏ·~ąSfy×͂·ºſƽiÍıƣıĻmHH}siaX@iǰÁÃ×t«ƒ­Tƒ¤J–JJŒyJ•ÈŠ`Ohߦ¡uËhIyCjmÿw…ZG……Ti‹SˆsO‰žB²ŸfNmsPaˆ{M{ŠõE‘^Hj}gYpaeuž¯‘oáwHjÁ½M¡pM“–uå‡mni{fk”\\oƒÎqCw†EZ¼K›ĝŠƒAy{m÷L‡wO×SimRI¯rK™õBS«sFe‡]fµ¢óY_ÆPRcue°Cbo׌bd£ŌIHgtrnyPt¦foaXďx›lBowz‹_{ÊéWiêE„GhܸºuFĈIxf®Ž•Y½ĀǙ]¤EyŸF²ċ’w¸¿@g¢§RGv»–áŸW`ÃĵJwi]t¥wO­½a[׈]`Ãi­üL€¦LabbTÀå’c}Íh™Æhˆ‹®BH€î|Ék­¤S†y£„ia©taį·Ɖ`ō¥Uh“O…ƒĝLk}©Fos‰´›Jm„µlŁu—…ø–nÑJWΪ–YÀïAetTžŅ‚ӍG™Ë«bo‰{ıwodƟ½ƒžOġܑµxàNÖ¾P²§HKv¾–]|•B‡ÆåoZ`¡Ø`ÀmºĠ~ÌЧnDž¿¤]wğ@sƒ‰rğu‰~‘Io”[é±¹ ¿žſđӉ@q‹gˆ¹zƱřaí°KtǤV»Ã[ĩǭƑ^ÇÓ@ỗs›Zϕ‹œÅĭ€Ƌ•ěpwDóÖሯneQˌq·•GCœýS]xŸ·ý‹q³•O՜Œ¶Qzßti{ř‰áÍÇWŝŭñzÇW‹pç¿JŒ™‚Xœĩè½cŒF–ÂLiVjx}\\N†ŇĖ¥Ge–“JA¼ÄHfÈu~¸Æ«dE³ÉMA|b˜Ò…˜ćhG¬CM‚õŠ„ƤąAvƒüV€éŀ‰_V̳ĐwQj´·ZeÈÁ¨X´Æ¡Qu·»Ÿ“˜ÕZ³ġqDo‰y`L¬gdp°şŠp¦ėìÅĮZްIä”h‚‘ˆzŠĵœf²å ›ĚрKp‹IN|‹„Ñz]ń……·FU×é»R³™MƒÉ»GM«€ki€™ér™}Ã`¹ăÞmȝnÁîRǀ³ĜoİzŔwǶVÚ£À]ɜ»ĆlƂ²Ġ…þTº·àUȞÏʦ¶†I’«dĽĢdĬ¿–»Ĕ׊h\\c¬†ä²GêëĤł¥ÀǿżÃÆMº}BÕĢyFVvw–ˆxBèĻĒ©Ĉ“tCĢɽŠȣ¦āæ·HĽî“ôNԓ~^¤Ɗœu„œ^s¼{TA¼ø°¢İªDè¾Ň¶ÝJ‘®Z´ğ~Sn|ªWÚ©òzPOȸ‚bð¢|‹øĞŠŒœŒQìÛÐ@Ğ™ǎRS¤Á§d…i“´ezÝúØã]Hq„kIŸþËQǦÃsǤ[E¬ÉŪÍxXƒ·ÖƁİlƞ¹ª¹|XÊwn‘ÆƄmÀêErĒtD®ċæcQƒ”E®³^ĭ¥©l}äQto˜ŖÜqƎkµ–„ªÔĻĴ¡@Ċ°B²Èw^^RsºT£ڿœQP‘JvÄz„^Đ¹Æ¯fLà´GC²‘dt˜­ĀRt¼¤ĦOðğfÔðDŨŁĞƘïžPȆ®âbMüÀXZ ¸£@Ś›»»QÉ­™]d“sÖ×_͖_ÌêŮPrĔĐÕGĂeZÜîĘqBhtO ¤tE[h|Y‹Ô‚ZśÎs´xº±UŒ’ñˆt|O’ĩĠºNbgþŠJy^dÂY Į„]Řz¦gC‚³€R`Šz’¢AjŒ¸CL„¤RÆ»@­Ŏk\\Ç´£YW}z@Z}‰Ã¶“oû¶]´^N‡Ò}èN‚ª–P˜Íy¹`S°´†ATe€VamdUĐwʄvĮÕ\\ƒu‹Æŗ¨Yp¹àZÂm™Wh{á„}WØǍ•Éüw™ga§áCNęÎ[ĀÕĪgÖɪX˜øx¬½Ů¦¦[€—„NΆL€ÜUÖ´òrÙŠxR^–†J˜k„ijnDX{Uƒ~ET{ļº¦PZc”jF²Ė@Žp˜g€ˆ¨“B{ƒu¨ŦyhoÚD®¯¢˜ WòàFΤ¨GDäz¦kŮPœġq˚¥À]€Ÿ˜eŽâÚ´ªKxī„Pˆ—Ö|æ[xäJÞĥ‚s’NÖ½ž€I†¬nĨY´®Ð—ƐŠ€mD™ŝuäđđEb…e’e_™v¡}ìęNJē}q”É埁T¯µRs¡M@}ůa†a­¯wvƉåZwž\\Z{åû^›"]],"encodeOffsets":[[[108815,30935]],[[110617,31811]]]}},{"type":"Feature","id":"520000","properties":{"id":"520000","cp":[106.713478,26.578343],"name":"贵州","childNum":3},"geometry":{"type":"MultiPolygon","coordinates":[["@@†G\\†lY£‘in"],["@@q‚|ˆ‚mc¯tχVSÎ"],["@@hÑ£Is‡NgßH†›HªķÃh_¹ƒ¡ĝħń¦uيùŽgS¯JHŸ|sÝÅtÁïyMDč»eÕtA¤{b\\}—ƒG®u\\åPFq‹wÅaD…žK°ºâ_£ùbµ”mÁ‹ÛœĹM[q|hlaªāI}тƒµ@swtwm^oµˆD鼊yV™ky°ÉžûÛR…³‚‡eˆ‡¥]RՋěħ[ƅåÛDpŒ”J„iV™™‰ÂF²I…»mN·£›LbÒYb—WsÀbŽ™pki™TZĄă¶HŒq`……ĥ_JŸ¯ae«ƒKpÝx]aĕÛPƒÇȟ[ÁåŵÏő—÷Pw}‡TœÙ@Õs«ĿÛq©½œm¤ÙH·yǥĘĉBµĨÕnđ]K„©„œá‹ŸG纍§Õßg‡ǗĦTèƤƺ{¶ÉHÎd¾ŚÊ·OÐjXWrãLyzÉAL¾ę¢bĶėy_qMĔąro¼hĊžw¶øV¤w”²Ĉ]ʚKx|`ź¦ÂÈdr„cȁbe¸›`I¼čTF´¼Óýȃr¹ÍJ©k_șl³´_pН`oÒh޶pa‚^ÓĔ}D»^Xyœ`d˜[Kv…JPhèhCrĂĚÂ^Êƌ wˆZL­Ġ£šÁbrzOIl’MM”ĪŐžËr×ÎeŦŽtw|Œ¢mKjSǘňĂStÎŦEtqFT†¾†E쬬ôxÌO¢Ÿ KгŀºäY†„”PVgŎ¦Ŋm޼VZwVlŒ„z¤…ž£Tl®ctĽÚó{G­A‡ŒÇgeš~Αd¿æaSba¥KKûj®_ć^\\ؾbP®¦x^sxjĶI_Ä X‚⼕Hu¨Qh¡À@Ëô}ޱžGNìĎlT¸ˆ…`V~R°tbÕĊ`¸úÛtπFDu€[ƒMfqGH·¥yA‰ztMFe|R‚_Gk†ChZeÚ°to˜v`x‹b„ŒDnÐ{E}šZ˜è€x—†NEފREn˜[Pv@{~rĆAB§‚EO¿|UZ~ì„Uf¨J²ĂÝÆ€‚sª–B`„s¶œfvö¦ŠÕ~dÔq¨¸º»uù[[§´sb¤¢zþFœ¢Æ…Àhˆ™ÂˆW\\ıŽËI݊o±ĭŠ£þˆÊs}¡R]ŒěƒD‚g´VG¢‚j±®è†ºÃmpU[Á›‘Œëº°r›ÜbNu¸}Žº¼‡`ni”ºÔXĄ¤¼Ôdaµ€Á_À…†ftQQgœR—‘·Ǔ’v”}Ýלĵ]µœ“Wc¤F²›OĩųãW½¯K‚©…]€{†LóµCIµ±Mß¿hŸ•©āq¬o‚½ž~@i~TUxŪÒ¢@ƒ£ÀEîôruń‚”“‚b[§nWuMÆLl¿]x}ij­€½"]],"encodeOffsets":[[[112158,27383]],[[112105,27474]],[[112095,27476]]]}},{"type":"Feature","id":"530000","properties":{"id":"530000","cp":[101.512251,24.740609],"name":"云南","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@[„ùx½}ÑRH‘YīĺûsÍn‘iEoã½Ya²ė{c¬ĝg•ĂsA•ØÅwď‚õzFjw}—«Dx¿}UũlŸê™@•HÅ­F‰¨ÇoJ´Ónũuą¡Ã¢pÒŌ“Ø TF²‚xa²ËX€‚cʋlHîAßËŁkŻƑŷÉ©h™W­æßU‡“Ës¡¦}•teèÆ¶StǀÇ}Fd£j‹ĈZĆÆ‹¤T‚č\\Dƒ}O÷š£Uˆ§~ŃG™‚åŃDĝ¸œTsd¶¶Bªš¤u¢ŌĎo~t¾ÍŶÒtD¦Ú„iôö‰€z›ØX²ghįh½Û±¯€ÿm·zR¦Ɵ`ªŊÃh¢rOԍ´£Ym¼èêf¯ŪĽn„†cÚbŒw\\zlvWžªâˆ ¦g–mĿBş£¢ƹřbĥkǫßeeZkÙIKueT»sVesb‘aĕ  ¶®dNœĄÄpªyސ¼—„³BE˜®l‡ŽGœŭCœǶwêżĔÂe„pÍÀQƞpC„–¼ŲÈ­AÎô¶R„ä’Q^Øu¬°š_Èôc´¹ò¨P΢hlϦ´Ħ“Æ´sâDŽŲPnÊD^¯°’Upv†}®BP̪–jǬx–Söwlfòªv€qĸ|`H€­viļ€ndĜ­Ćhň•‚em·FyށqóžSᝑ³X_ĞçêtryvL¤§z„¦c¦¥jnŞk˜ˆlD¤øz½ĜàžĂŧMÅ|áƆàÊcðÂF܎‚áŢ¥\\\\º™İøÒÐJĴ‡„îD¦zK²ǏÎEh~’CD­hMn^ÌöÄ©ČZÀžaü„fɭyœpį´ěFűk]Ôě¢qlÅĆÙa¶~Äqššê€ljN¬¼H„ÊšNQ´ê¼VظE††^ŃÒyŒƒM{ŒJLoÒœęæŸe±Ķ›y‰’‡gã“¯JYÆĭĘëo¥Š‰o¯hcK«z_pŠrC´ĢÖY”—¼ v¸¢RŽÅW³Â§fǸYi³xR´ďUˊ`êĿU„û€uĆBƒƣö‰N€DH«Ĉg†——Ñ‚aB{ÊNF´¬c·Åv}eÇÃGB»”If•¦HňĕM…~[iwjUÁKE•Ž‹¾dĪçW›šI‹èÀŒoÈXòyŞŮÈXâÎŚŠj|àsRy‹µÖ›–Pr´þŒ ¸^wþTDŔ–Hr¸‹žRÌmf‡żÕâCôox–ĜƌÆĮŒ›Ð–œY˜tâŦÔ@]ÈǮƒ\\μģUsȯLbîƲŚºyh‡rŒŠ@ĒԝƀŸÀ²º\\êp“’JŠ}ĠvŠqt„Ġ@^xÀ£È†¨mËÏğ}n¹_¿¢×Y_æpˆÅ–A^{½•Lu¨GO±Õ½ßM¶w’ÁĢۂP‚›Ƣ¼pcIJxŠ|ap̬HšÐŒŊSfsðBZ¿©“XÏÒK•k†÷Eû¿‰S…rEFsÕūk”óVǥʼniTL‚¡n{‹uxţÏh™ôŝ¬ğōN“‘NJkyPaq™Âğ¤K®‡YŸxÉƋÁ]āęDqçgOg†ILu—\\_gz—]W¼ž~CÔē]bµogpў_oď`´³Țkl`IªºÎȄqÔþž»E³ĎSJ»œ_f·‚adÇqƒÇc¥Á_Źw{™L^ɱćx“U£µ÷xgĉp»ĆqNē`rĘzaĵĚ¡K½ÊBzyäKXqiWPÏɸ½řÍcÊG|µƕƣG˛÷Ÿk°_^ý|_zċBZocmø¯hhcæ\\lˆMFlư£Ĝ„ÆyH“„F¨‰µêÕ]—›HA…àӄ^it `þßäkŠĤÎT~Wlÿ¨„ÔPzUC–NVv [jâôDôď[}ž‰z¿–msSh‹¯{jïğl}šĹ[–őŒ‰gK‹©U·µË@¾ƒm_~q¡f¹…ÅË^»‘f³ø}Q•„¡Ö˳gͱ^ǁ…\\ëÃA_—¿bW›Ï[¶ƛ鏝£F{īZgm@|kHǭƁć¦UĔťƒ×ë}ǝƒeďºȡȘÏíBə£āĘPªij¶“ʼnÿ‡y©n‰ď£G¹¡I›Š±LÉĺÑdĉ܇W¥˜‰}g˜Á†{aqÃ¥aŠıęÏZ—ï`"],"encodeOffsets":[[104636,22969]]}},{"type":"Feature","id":"540000","properties":{"id":"540000","cp":[89.132212,30.860361],"name":"西藏","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@hžľxŽŖ‰xƒÒVކºÅâAĪÝȆµę¯Ňa±r_w~uSÕň‘qOj]ɄQ…£Z……UDûoY’»©M[‹L¼qãË{V͕çWViŽ]ë©Ä÷àyƛh›ÚU°ŒŒa”d„cQƒ~Mx¥™cc¡ÙaSyF—ցk­ŒuRýq¿Ôµ•QĽ³aG{¿FµëªéĜÿª@¬·–K‰·àariĕĀ«V»Ŷ™Ĵū˜gèLǴŇƶaf‹tŒèBŚ£^Šâ†ǐÝ®–šM¦ÁǞÿ¬LhŸŽJ¾óƾƺcxw‹f]Y…´ƒ¦|œQLn°aœdĊ…œ\\¨o’œǀÍŎœ´ĩĀd`tÊQŞŕ|‚¨C^©œĈ¦„¦ÎJĊ{ŽëĎjª²rЉšl`¼Ą[t|¦St辉PŒÜK¸€d˜Ƅı]s¤—î_v¹ÎVòŦj˜£Əsc—¬_Ğ´|٘¦Avަw`ăaÝaa­¢e¤ı²©ªSªšÈMĄwžÉØŔì@T‘¤—Ę™\\õª@”þo´­xA s”ÂtŎKzó´ÇĊµ¢rž^nĊ­Æ¬×üGž¢‚³ {âĊ]š™G‚~bÀgVjzlhǶf€žOšfdЉªB]pj„•TO–tĊ‚n¤}®¦ƒČ¥d¢¼»ddš”Y¼Žt—¢eȤJ¤}Ǿ¡°§¤AГlc@ĝ”sªćļđAç‡wx•UuzEÖġ~AN¹ÄÅȀݦ¿ģŁéì±H…ãd«g[؉¼ēÀ•cīľġ¬cJ‘µ…ÐʥVȝ¸ßS¹†ý±ğkƁ¼ą^ɛ¤Ûÿ‰b[}¬ōõÃ]ËNm®g@•Bg}ÍF±ǐyL¥íCˆƒIij€Ï÷њį[¹¦[⚍EÛïÁÉdƅß{âNÆāŨߝ¾ě÷yC£‡k­´ÓH@¹†TZ¥¢įƒ·ÌAЧ®—Zc…v½ŸZ­¹|ŕWZqgW“|ieZÅYVӁqdq•bc²R@†c‡¥Rã»Ge†ŸeƃīQ•}J[ғK…¬Ə|o’ėjġĠÑN¡ð¯EBčnwôɍėªƒ²•CλŹġǝʅįĭạ̃ūȹ]ΓͧgšsgȽóϧµǛ†ęgſ¶ҍć`ĘąŌJޚä¤rÅň¥ÖÁUětęuůÞiĊÄÀ\\Æs¦ÓRb|Â^řÌkÄŷ¶½÷‡f±iMݑ›‰@ĥ°G¬ÃM¥n£Øą‚ğ¯ß”§aëbéüÑOčœk£{\\‘eµª×M‘šÉfm«Ƒ{Å׃Gŏǩãy³©WÑăû‚··‘Q—òı}¯ã‰I•éÕÂZ¨īès¶ZÈsŽæĔTŘvŽgÌsN@îá¾ó@‰˜ÙwU±ÉT廣TđŸWxq¹Zo‘b‹s[׌¯cĩv‡Œėŧ³BM|¹k‰ªħ—¥TzNYnݍßpęrñĠĉRS~½ŠěVVе‚õ‡«ŒM££µB•ĉ¥áºae~³AuĐh`Ü³ç@BۘïĿa©|z²Ý¼D”£à貋ŸƒIƒû›I ā€óK¥}rÝ_Á´éMaň¨€~ªSĈ½Ž½KÙóĿeƃÆBŽ·¬ën×W|Uº}LJrƳ˜lŒµ`bÔ`QˆˆÐÓ@s¬ñIŒÍ@ûws¡åQÑßÁ`ŋĴ{Ī“T•ÚÅTSij‚‹Yo|Ç[ǾµMW¢ĭiÕØ¿@˜šMh…pÕ]j†éò¿OƇĆƇp€êĉâlØw–ěsˆǩ‚ĵ¸c…bU¹ř¨WavquSMzeo_^gsÏ·¥Ó@~¯¿RiīB™Š\\”qTGªÇĜçPoŠÿfñòą¦óQīÈáP•œābß{ƒZŗĸIæÅ„hnszÁCËìñšÏ·ąĚÝUm®ó­L·ăU›Èíoù´Êj°ŁŤ_uµ^‘°Œìǖ@tĶĒ¡Æ‡M³Ģ«˜İĨÅ®ğ†RŽāð“ggheÆ¢z‚Ê©Ô\\°ÝĎz~ź¤Pn–MĪÖB£Ÿk™n鄧żćŠ˜ĆK„ǰ¼L¶è‰âz¨u¦¥LDĘz¬ýÎmĘd¾ß”Fz“hg²™Fy¦ĝ¤ċņbΛ@y‚Ąæm°NĮZRÖíŽJ²öLĸÒ¨Y®ƌÐV‰à˜tt_ڀÂyĠzž]Ţh€zĎ{†ĢX”ˆc|šÐqŽšfO¢¤ög‚ÌHNŽ„PKŖœŽ˜Uú´xx[xˆvĐCûŠìÖT¬¸^}Ìsòd´_އKgžLĴ…ÀBon|H@–Êx˜—¦BpŰˆŌ¿fµƌA¾zLjRxжF”œkĄźRzŀˆ~¶[”´Hnª–VƞuĒ­È¨ƎcƽÌm¸ÁÈM¦x͊ëÀxdžB’šú^´W†£–d„kɾĬpœw‚˂ØɦļĬIŚœÊ•n›Ŕa¸™~J°î”lɌxĤÊÈðhÌ®‚g˜T´øŽàCˆŽÀ^ªerrƘdž¢İP|Ė ŸWœªĦ^¶´ÂL„aT±üWƜ˜ǀRšŶUńšĖ[QhlLüA†‹Ü\\†qR›Ą©"],"encodeOffsets":[[90849,37210]]}},{"type":"Feature","id":"610000","properties":{"id":"610000","cp":[108.948024,34.263161],"name":"陕西","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@˜p¢—ȮµšûG™Ħ}Ħšðǚ¶òƄ€jɂz°{ºØkÈęâ¦jª‚Bg‚\\œċ°s¬Ž’]jžú ‚E”Ȍdž¬s„t‡”RˆÆdĠݎwܔ¸ôW¾ƮłÒ_{’Ìšû¼„jº¹¢GǪÒ¯ĘƒZ`ºŊƒecņąš~BÂgzpâēòYǠȰÌTΨÂWœ|fcŸă§uF—Œ@NŸ¢XLƒŠRMº[ğȣſï|¥J™kc`sʼnǷ’Y¹‹W@µ÷K…ãï³ÛIcñ·VȋڍÒķø©—þ¥ƒy‚ÓŸğęmWµÎumZyOŅƟĥÓ~sÑL¤µaŅY¦ocyZ{‰y c]{ŒTa©ƒ`U_Ěē£ωÊƍKù’K¶ȱÝƷ§{û»ÅÁȹÍéuij|¹cÑd‘ŠìUYƒŽO‘uF–ÕÈYvÁCqӃT•Ǣí§·S¹NgŠV¬ë÷Át‡°Dد’C´ʼnƒópģ}„ċcE˅FŸŸéGU¥×K…§­¶³B‹Č}C¿åċ`wġB·¤őcƭ²ő[Å^axwQO…ÿEËߌ•ĤNĔŸwƇˆÄŠńwĪ­Šo[„_KÓª³“ÙnK‰Çƒěœÿ]ď€ă_d©·©Ýŏ°Ù®g]±„Ÿ‡ß˜å›—¬÷m\\›iaǑkěX{¢|ZKlçhLt€Ňîŵ€œè[€É@ƉĄEœ‡tƇÏ˜³­ħZ«mJ…›×¾‘MtÝĦ£IwÄå\\Õ{‡˜ƒOwĬ©LÙ³ÙgBƕŀr̛ĢŭO¥lãyC§HÍ£ßEñŸX¡—­°ÙCgpťz‘ˆb`wI„vA|§”‡—hoĕ@E±“iYd¥OϹS|}F@¾oAO²{tfžÜ—¢Fǂ҈W²°BĤh^Wx{@„¬‚­F¸¡„ķn£P|ŸªĴ@^ĠĈæb–Ôc¶l˜Yi…–^Mi˜cϰÂ[ä€vï¶gv@À“Ĭ·lJ¸sn|¼u~a]’ÆÈtŌºJp’ƒþ£KKf~ЦUbyäIšĺãn‡Ô¿^­žŵMT–hĠܤko¼Ŏìąǜh`[tŒRd²IJ_œXPrɲ‰l‘‚XžiL§àƒ–¹ŽH˜°Ȧqº®QC—bA†„ŌJ¸ĕÚ³ĺ§ `d¨YjžiZvRĺ±öVKkjGȊĐePОZmļKÀ€‚[ŠŽ`ösìh†ïÎoĬdtKÞ{¬èÒÒBŒÔpIJÇĬJŊ¦±J«ˆY§‹@·pH€µàåVKe›pW†ftsAÅqC·¬ko«pHÆuK@oŸHĆۄķhx“e‘n›S³àǍrqƶRbzy€¸ËАl›¼EºpĤ¼Œx¼½~Ğ’”à@†ÚüdK^ˆmÌSj"],"encodeOffsets":[[110234,38774]]}},{"type":"Feature","id":"620000","properties":{"id":"620000","cp":[103.823557,36.058039],"name":"甘肃","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@VuUv"],["@@ũ‹EĠtt~nkh`Q‰¦ÅÄÜdw˜Ab×ĠąJˆ¤DüègĺqBqœj°lI¡ĨÒ¤úSHbš‡ŠjΑBаaZˆ¢KJŽ’O[|A£žDx}Nì•HUnrk„ kp€¼Y kMJn[aG‚áÚÏ[½rc†}aQxOgsPMnUs‡nc‹Z…ž–sKúvA›t„Þġ’£®ĀYKdnFwš¢JE°”Latf`¼h¬we|€Æ‡šbj}GA€·~WŽ”—`†¢MC¤tL©IJ°qdf”O‚“bÞĬ¹ttu`^ZúE`Œ[@„Æsîz®¡’C„ƳƜG²“R‘¢R’m”fŽwĸg܃‚ą G@pzJM½mŠhVy¸uÈÔO±¨{LfæU¶ßGĂq\\ª¬‡²I‚¥IʼnÈīoı‹ÓÑAçÑ|«LÝcspīðÍg…të_õ‰\\ĉñLYnĝg’ŸRǡÁiHLlõUĹ²uQjYi§Z_c¨Ÿ´ĹĖÙ·ŋI…ƒaBD˜­R¹ȥr—¯G•ºß„K¨jWk’ɱŠOq›Wij\\a­‹Q\\sg_ĆǛōëp»£lğۀgS•ŶN®À]ˆÓäm™ĹãJaz¥V}‰Le¤L„ýo‘¹IsŋÅÇ^‘Žbz…³tmEÁ´aйcčecÇN•ĊãÁ\\蝗dNj•]j†—ZµkÓda•ćå]ğij@ ©O{¤ĸm¢ƒE·®ƒ«|@Xwg]A챝‡XǁÑdzªc›wQÚŝñsÕ³ÛV_ýƒ˜¥\\ů¥©¾÷w—Ž©WÕÊĩhÿÖÁRo¸V¬âDb¨šhûx–Ê×nj~Zâƒg|šXÁnßYoº§ZÅŘvŒ[„ĭÖʃuďxcVbnUSf…B¯³_Tzº—ΕO©çMÑ~Mˆ³]µ^püµ”ŠÄY~y@X~¤Z³€[Èōl@®Å¼£QKƒ·Di‹¡By‘ÿ‰Q_´D¥hŗyƒ^ŸĭÁZ]cIzý‰ah¹MĪğP‘s{ò‡‹‘²Vw¹t³Ŝˁ[ŽÑ}X\\gsFŸ£sPAgěp×ëfYHāďÖqēŭOÏë“dLü•\\iŒ”t^c®šRʺ¶—¢H°mˆ‘rYŸ£BŸ¹čIoľu¶uI]vģSQ{ƒUŻ”Å}QÂ|̋°ƅ¤ĩŪU ęĄžÌZҞ\\v˜²PĔ»ƢNHƒĂyAmƂwVmž`”]ȏb•”H`‰Ì¢²ILvĜ—H®¤Dlt_„¢JJÄämèÔDëþgºƫ™”aʎÌrêYi~ ÎݤNpÀA¾Ĕ¼b…ð÷’Žˆ‡®‚”üs”zMzÖĖQdȨý†v§Tè|ªH’þa¸|šÐ ƒwKĢx¦ivr^ÿ ¸l öæfƟĴ·PJv}n\\h¹¶v†·À|\\ƁĚN´Ĝ€çèÁz]ġ¤²¨QÒŨTIl‡ªťØ}¼˗ƦvÄùØE‹’«Fï˛Iq”ōŒTvāÜŏ‚íÛߜÛV—j³âwGăÂíNOŠˆŠPìyV³ʼnĖýZso§HіiYw[߆\\X¦¥c]ÔƩÜ·«j‡ÐqvÁ¦m^ċ±R™¦΋ƈťĚgÀ»IïĨʗƮްƝ˜ĻþÍAƉſ±tÍEÕÞāNU͗¡\\ſčåÒʻĘm ƭÌŹöʥ’ëQ¤µ­ÇcƕªoIýˆ‰Iɐ_mkl³ă‰Ɠ¦j—¡Yz•Ňi–}Msßõ–īʋ —}ƒÁVmŸ_[n}eı­Uĥ¼‘ª•I{ΧDӜƻėoj‘qYhĹT©oūĶ£]ďxĩ‹ǑMĝ‰q`B´ƃ˺Ч—ç~™²ņj@”¥@đ´ί}ĥtPńǾV¬ufӃÉC‹tÓ̻‰…¹£G³€]ƖƾŎĪŪĘ̖¨ʈĢƂlɘ۪üºňUðǜȢƢż̌ȦǼ‚ĤŊɲĖ­Kq´ï¦—ºĒDzņɾªǀÞĈĂD†½ĄĎÌŗĞrôñnŽœN¼â¾ʄľԆ|DŽŽ֦ज़ȗlj̘̭ɺƅêgV̍ʆĠ·ÌĊv|ýĖÕWĊǎÞ´õ¼cÒÒBĢ͢UĜð͒s¨ňƃLĉÕÝ@ɛƯ÷¿Ľ­ĹeȏijëCȚDŲyê×Ŗyò¯ļcÂßY…tÁƤyAã˾J@ǝrý‹‰@¤…rz¸oP¹ɐÚyᐇHŸĀ[Jw…cVeȴϜ»ÈŽĖ}ƒŰŐèȭǢόĀƪÈŶë;Ñ̆ȤМľĮEŔ—ĹŊũ~ËUă{ŸĻƹɁύȩþĽvĽƓÉ@ē„ĽɲßǐƫʾǗĒpäWÐxnsÀ^ƆwW©¦cÅ¡Ji§vúF¶Ž¨c~c¼īŒeXǚ‹\\đ¾JŽwÀďksãA‹fÕ¦L}wa‚o”Z’‹D½†Ml«]eÒÅaɲáo½FõÛ]ĻÒ¡wYR£¢rvÓ®y®LF‹LzĈ„ôe]gx}•|KK}xklL]c¦£fRtív¦†PĤoH{tK"]],"encodeOffsets":[[[108619,36299]],[[108589,36341]]]}},{"type":"Feature","id":"630000","properties":{"id":"630000","cp":[96.778916,35.623178],"name":"青海","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@InJm"],["@@CƒÆ½OŃĦsΰ~dz¦@@“Ņiš±è}ؘƄ˹A³r_ĞŠǒNΌĐw¤^ŬĵªpĺSZg’rpiƼĘԛ¨C|͖J’©Ħ»®VIJ~f\\m `Un„˜~ʌŸ•ĬàöNt•~ňjy–¢Zi˜Ɣ¥ĄŠk´nl`JʇŠJþ©pdƖ®È£¶ìRʦ‘źõƮËnŸʼėæÑƀĎ[‚˜¢VÎĂMÖÝÎF²sƊƀÎBļýƞ—¯ʘƭðħ¼Jh¿ŦęΌƇš¥²Q]Č¥nuÂÏriˆ¸¬ƪÛ^Ó¦d€¥[Wà…x\\ZŽjҕ¨GtpþYŊĕ´€zUO뇉P‰îMĄÁxH´á˜iÜUà›îÜՁĂÛSuŎ‹r“œJð̬EŒ‘FÁú×uÃÎkr“Ē{V}İ«O_ÌËĬ©ŽÓŧSRѱ§Ģ£^ÂyèçěM³Ƃę{[¸¿u…ºµ[gt£¸OƤĿéYŸõ·kŸq]juw¥Dĩƍ€õÇPéĽG‘ž©ã‡¤G…uȧþRcÕĕNy“yût“ˆ­‡ø‘†ï»a½ē¿BMoᣟÍj}éZËqbʍš“Ƭh¹ìÿÓAçãnIáI`ƒks£CG­ě˜Uy×Cy•…’Ÿ@¶ʡÊBnāzG„ơMē¼±O÷õJËĚăVŸĪũƆ£Œ¯{ËL½Ìzż“„VR|ĠTbuvJvµhĻĖH”Aëáa…­OÇðñęNw‡…œľ·L›mI±íĠĩPÉ×®ÿs—’cB³±JKßĊ«`…ađ»·QAmO’‘Vţéÿ¤¹SQt]]Çx€±¯A@ĉij¢Ó祖•ƒl¶ÅÛr—ŕspãRk~¦ª]Į­´“FR„åd­ČsCqđéFn¿Åƃm’Éx{W©ºƝºįkÕƂƑ¸wWūЩÈFž£\\tÈ¥ÄRÈýÌJ ƒlGr^×äùyÞ³fj”c†€¨£ÂZ|ǓMĝšÏ@ëÜőR‹›ĝ‰Œ÷¡{aïȷPu°ËXÙ{©TmĠ}Y³’­ÞIňµç½©C¡į÷¯B»|St»›]vƒųƒs»”}MÓ ÿʪƟǭA¡fs˜»PY¼c¡»¦c„ċ­¥£~msĉP•–Siƒ^o©A‰Šec‚™PeǵŽkg‚yUi¿h}aH™šĉ^|ᴟ¡HØûÅ«ĉ®]m€¡qĉ¶³ÈyôōLÁst“BŸ®wn±ă¥HSò뚣˜S’ë@לÊăxÇN©™©T±ª£IJ¡fb®ÞbŽb_Ą¥xu¥B—ž{łĝ³«`d˜Ɛt—¤ťiñžÍUuºí`£˜^tƃIJc—·ÛLO‹½Šsç¥Ts{ă\\_»™kϊ±q©čiìĉ|ÍIƒ¥ć¥›€]ª§D{ŝŖÉR_sÿc³Īō›ƿΑ›§p›[ĉ†›c¯bKm›R¥{³„Z†e^ŽŒwx¹dƽŽôIg §Mĕ ƹĴ¿—ǣÜ̓]‹Ý–]snåA{‹eŒƭ`ǻŊĿ\\ijŬű”YÂÿ¬jĖqŽßbЏ•L«¸©@ěĀ©ê¶ìÀEH|´bRľž–Ó¶rÀQþ‹vl®Õ‚E˜TzÜdb ˜hw¤{LR„ƒd“c‹b¯‹ÙVgœ‚ƜßzÃô쮍^jUèXΖ|UäÌ»rKŽ\\ŒªN‘¼pZCü†VY††¤ɃRi^rPҒTÖ}|br°qňb̰ªiƶGQ¾²„x¦PœmlŜ‘[Ĥ¡ΞsĦŸÔÏâ\\ªÚŒU\\f…¢N²§x|¤§„xĔsZPòʛ²SÐqF`ª„VƒÞŜĶƨVZŒÌL`ˆ¢dŐIqr\\oäõ–F礻Ŷ×h¹]Clـ\\¦ďÌį¬řtTӺƙgQÇÓHţĒ”´ÃbEÄlbʔC”|CˆŮˆk„Ʈ[ʼ¬ňœ´KŮÈΰÌζƶlð”ļA†TUvdTŠG†º̼ŠÔ€ŒsÊDԄveOg"]],"encodeOffsets":[[[105308,37219]],[[95370,40081]]]}},{"type":"Feature","id":"640000","properties":{"id":"640000","cp":[106.278179,37.26637],"name":"宁夏","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@KëÀęĞ«OęȿȕŸı]ʼn¡åįÕÔ«Ǵõƪ™ĚQÐZhv K°›öqÀѐS[ÃÖHƖčË‡nL]ûc…Ùß@‚“ĝ‘¾}w»»‹oģF¹œ»kÌÏ·{zPƒ§B­¢íyÅt@ƒ@áš]Yv_ssģ¼i߁”ĻL¾ġsKD£¡N_…“˜X¸}B~Haiˆ™Åf{«x»ge_bs“KF¯¡Ix™mELcÿZ¤­Ģ‘ƒÝœsuBLù•t†ŒYdˆmVtNmtOPhRw~bd…¾qÐ\\âÙH\\bImlNZŸ»loƒŸqlVm–Gā§~QCw¤™{A\\‘PKŸNY‡¯bF‡kC¥’sk‹Šs_Ã\\ă«¢ħkJi¯r›rAhĹûç£CU‡ĕĊ_ԗBixÅُĄnªÑaM~ħpOu¥sîeQ¥¤^dkKwlL~{L~–hw^‚ófćƒKyEŒ­K­zuÔ¡qQ¤xZÑ¢^ļöܾEpž±âbÊÑÆ^fk¬…NC¾‘Œ“YpxbK~¥Že֎ŒäBlt¿Đx½I[ĒǙŒWž‹f»Ĭ}d§dµùEuj¨‚IÆ¢¥dXªƅx¿]mtÏwßR͌X¢͎vÆzƂZò®ǢÌʆCrâºMÞzžÆMҔÊÓŊZľ–r°Î®Ȉmª²ĈUªĚøºˆĮ¦ÌĘk„^FłĬhĚiĀ˾iİbjÕ"],["@@mfwěwMrŢªv@G‰"]],"encodeOffsets":[[[109366,40242]],[[108600,36303]]]}},{"type":"Feature","id":"650000","properties":{"id":"650000","cp":[85.617733,40.792818],"name":"新疆","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@QØĔ²X¨”~ǘBºjʐߨvK”ƔX¨vĊOžÃƒ·¢i@~c—‡ĝe_«”Eš“}QxgɪëÏÃ@sÅyXoŖ{ô«ŸuX…ê•Îf`œC‚¹ÂÿÐGĮÕĞXŪōŸMźÈƺQèĽôe|¿ƸJR¤ĘEjcUóº¯Ĩ_ŘÁMª÷Ð¥Oéȇ¿ÖğǤǷÂF҇zÉx[]­Ĥĝ‰œ¦EP}ûƥé¿İƷTėƫœŕƅ™ƱB»Đ±’ēO…¦E–•}‘`cȺrĦáŖuҞª«IJ‡πdƺÏØZƴwʄ¤ĖGЙǂZ̓èH¶}ÚZצʥĪï|ÇĦMŔ»İĝLj‹ì¥Βœba­¯¥ǕǚkĆŵĦɑĺƯxūД̵nơʃĽá½M»›òmqóŘĝč˾ăC…ćāƿÝɽ©DZŅ¹đ¥˜³ðLrÁ®ɱĕģʼnǻ̋ȥơŻǛȡVï¹Ň۩ûkɗġƁ§ʇė̕ĩũƽō^ƕŠUv£ƁQï“Ƶkŏ½ΉÃŭdzLқʻ«ƭ\\lƒ‡ŭD‡“{ʓDkaFÃÄa“³ŤđÔGRÈƚhSӹŚsİ«ĐË[¥ÚDkº^Øg¼ŵ¸£EÍö•€ůʼnT¡c_‡ËKY‹ƧUśĵ„݃U_©rETÏʜ±OñtYw獃{£¨uM³x½şL©Ùá[ÓÐĥ Νtģ¢\\‚ś’nkO›w¥±ƒT»ƷFɯàĩÞáB¹Æ…ÑUw„੍žĽw[“mG½Èå~‡Æ÷QyŠěCFmĭZī—ŵVÁ™ƿQƛ—ûXS²‰b½KϽĉS›©ŷXĕŸ{ŽĕK·¥Ɨcqq©f¿]‡ßDõU³h—­gËÇïģÉɋw“k¯í}I·šœbmœÉ–ř›īJɥĻˁ×xo›ɹī‡l•c…¤³Xù]‘™DžA¿w͉ì¥wÇN·ÂËnƾƍdǧđ®Ɲv•Um©³G\\“}µĿ‡QyŹl㓛µEw‰LJQ½yƋBe¶ŋÀů‡ož¥A—˜Éw@•{Gpm¿Aij†ŽKLhˆ³`ñcËtW‚±»ÕS‰ëüÿďD‡u\\wwwù³—V›LŕƒOMËGh£õP¡™er™Ïd{“‡ġWÁ…č|yšg^ğyÁzÙs`—s|ÉåªÇ}m¢Ń¨`x¥’ù^•}ƒÌ¥H«‰Yªƅ”Aйn~Ꝛf¤áÀz„gŠÇDIԝ´AňĀ҄¶ûEYospõD[{ù°]u›Jq•U•|Soċxţ[õÔĥkŋÞŭZ˺óYËüċrw €ÞkrťË¿XGÉbřaDü·Ē÷Aê[Ää€I®BÕИÞ_¢āĠpŠÛÄȉĖġDKwbm‡ÄNô‡ŠfœƫVÉvi†dz—H‘‹QµâFšù­Âœ³¦{YGžƒd¢ĚÜO „€{Ö¦ÞÍÀPŒ^b–ƾŠlŽ[„vt×ĈÍE˨¡Đ~´î¸ùÎh€uè`¸ŸHÕŔVºwĠââWò‡@{œÙNÝ´ə²ȕn{¿¥{l—÷eé^e’ďˆXj©î\\ªÑò˜Üìc\\üqˆÕ[Č¡xoÂċªbØ­Œø|€¶ȴZdÆÂšońéŒGš\\”¼C°ÌƁn´nxšÊOĨ’ہƴĸ¢¸òTxÊǪMīИÖŲÃɎOvˆʦƢ~FއRěò—¿ġ~åŊœú‰Nšžš¸qŽ’Ę[Ĕ¶ÂćnÒPĒÜvúĀÊbÖ{Äî¸~Ŕünp¤ÂH¾œĄYÒ©ÊfºmԈĘcDoĬMŬ’˜S¤„s²‚”ʘچžȂVŦ –ŽèW°ªB|IJXŔþÈJĦÆæFĚêŠYĂªĂ]øªŖNÞüA€’fɨJ€˜¯ÎrDDšĤ€`€mz\\„§~D¬{vJÂ˜«lµĂb–¤p€ŌŰNĄ¨ĊXW|ų ¿¾ɄĦƐMT”‡òP˜÷fØĶK¢ȝ˔Sô¹òEð­”`Ɩ½ǒÂň×äı–§ĤƝ§C~¡‚hlå‚ǺŦŞkâ’~}ŽFøàIJaĞ‚fƠ¥Ž„Ŕdž˜®U¸ˆźXœv¢aƆúŪtŠųƠjd•ƺŠƺÅìnrh\\ĺ¯äɝĦ]èpĄ¦´LƞĬŠ´ƤǬ˼Ēɸ¤rºǼ²¨zÌPðŀbþ¹ļD¢¹œ\\ĜÑŚŸ¶ZƄ³àjĨoâŠȴLʉȮŒĐ­ĚăŽÀêZǚŐ¤qȂ\\L¢ŌİfÆs|zºeªÙæ§΢{Ā´ƐÚ¬¨Ĵà²łhʺKÞºÖTŠiƢ¾ªì°`öøu®Ê¾ãØ"],"encodeOffsets":[[88824,50096]]}},{"type":"Feature","id":"110000","properties":{"id":"110000","cp":[116.405285,39.904989],"name":"北京","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ĽOÁ›ûtŷmiÍt_H»Ĩ±d`й­{bw…Yr“³S]§§o¹€qGtm_Sŧ€“oa›‹FLg‘QN_•dV€@Zom_ć\\ߚc±x¯oœRcfe…£’o§ËgToÛJíĔóu…|wP¤™XnO¢ÉˆŦ¯rNÄā¤zâŖÈRpŢZŠœÚ{GŠrFt¦Òx§ø¹RóäV¤XdˆżâºWbwڍUd®bêņ¾‘jnŎGŃŶŠnzÚSeîĜZczî¾i]͜™QaúÍÔiþĩȨWĢ‹ü|Ėu[qb[swP@ÅğP¿{\\‡¥A¨Ï‘Ѩj¯ŠX\\¯œMK‘pA³[H…īu}}"],"encodeOffsets":[[120023,41045]]}},{"type":"Feature","id":"120000","properties":{"id":"120000","cp":[117.190182,39.125596],"name":"天津","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@ŬgX§Ü«E…¶Ḟ“¬O_™ïlÁg“z±AXe™µÄĵ{¶]gitgšIj·›¥îakS€‰¨ÐƎk}ĕ{gB—qGf{¿a†U^fI“ư‹³õ{YƒıëNĿžk©ïËZŏ‘R§òoY×Ógc…ĥs¡bġ«@dekąI[nlPqCnp{ˆō³°`{PNdƗqSÄĻNNâyj]äžÒD ĬH°Æ]~¡HO¾ŒX}ÐxŒgp“gWˆrDGˆŒpù‚Š^L‚ˆrzWxˆZ^¨´T\\|~@I‰zƒ–bĤ‹œjeĊªz£®Ĕvě€L†mV¾Ô_ȔNW~zbĬvG†²ZmDM~”~"],"encodeOffsets":[[120237,41215]]}},{"type":"Feature","id":"310000","properties":{"id":"310000","cp":[121.472644,31.231706],"name":"上海","childNum":6},"geometry":{"type":"MultiPolygon","coordinates":[["@@ɧư¬EpƸÁxc‡"],["@@©„ªƒ"],["@@”MA‹‘š"],["@@Qp݁E§ÉC¾"],["@@bŝՕÕEȣÚƥêImɇǦèÜĠŒÚžÃƌÃ͎ó"],["@@ǜûȬɋŠŭ™×^‰sYŒɍDŋ‘ŽąñCG²«ªč@h–_p¯A{‡oloY€¬j@IJ`•gQڛhr|ǀ^MIJvtbe´R¯Ô¬¨YŽô¤r]ì†Ƭį"]],"encodeOffsets":[[[124702,32062]],[[124547,32200]],[[124808,31991]],[[124726,32110]],[[124903,32376]],[[124438,32149]]]}},{"type":"Feature","id":"500000","properties":{"id":"500000","cp":[107.304962,29.533155],"name":"重庆","childNum":2},"geometry":{"type":"MultiPolygon","coordinates":[["@@vjG~nGŘŬĶȂƀƾ¹¸ØÎezĆT¸}êЖqHŸðqĖ䒊¥^CƒIj–²p…\\_ æüY|[YxƊæuž°xb®…Űb@~¢NQt°¶‚S栓Ê~rljĔëĚ¢~šuf`‘‚†fa‚ĔJåĊ„nÖ]„jƎćÊ@Š£¾a®£Ű{ŶĕF‹ègLk{Y|¡ĜWƔtƬJÑxq‹±ĢN´‰òK‰™–LÈüD|s`ŋ’ć]ƒÃ‰`đŒMûƱ½~Y°ħ`ƏíW‰½eI‹½{aŸ‘OIrÏ¡ĕŇa†p†µÜƅġ‘œ^ÖÛbÙŽŏml½S‹êqDu[R‹ãË»†ÿw`»y‘¸_ĺę}÷`M¯ċfCVµqʼn÷Z•gg“Œ`d½pDO‡ÎCnœ^uf²ènh¼WtƏxRGg¦…pV„†FI±ŽG^ŒIc´ec‡’G•ĹÞ½sëĬ„h˜xW‚}Kӈe­Xsbk”F¦›L‘ØgTkïƵNï¶}Gy“w\\oñ¡nmĈzjŸ•@™Óc£»Wă¹Ój“_m»ˆ¹·~MvÛaqœ»­‰êœ’\\ÂoVnŽÓØÍ™²«‹bq¿efE „€‹Ĝ^Qž~ Évý‡ş¤²Į‰pEİ}zcĺƒL‹½‡š¿gņ›¡ýE¡ya£³t\\¨\\vú»¼§·Ñr_oÒý¥u‚•_n»_ƒ•At©Þűā§IVeëƒY}{VPÀFA¨ąB}q@|Ou—\\Fm‰QF݅Mw˜å}]•€|FmϋCaƒwŒu_p—¯sfÙgY…DHl`{QEfNysBЦzG¸rHe‚„N\\CvEsÐùÜ_·ÖĉsaQ¯€}_U‡†xÃđŠq›NH¬•Äd^ÝŰR¬ã°wećJEž·vÝ·Hgƒ‚éFXjÉê`|yŒpxkAwœWĐpb¥eOsmzwqChóUQl¥F^laf‹anòsr›EvfQdÁUVf—ÎvÜ^efˆtET¬ôA\\œ¢sJŽnQTjP؈xøK|nBz‰„œĞ»LY‚…FDxӄvr“[ehľš•vN”¢o¾NiÂxGp⬐z›bfZo~hGi’]öF|‰|Nb‡tOMn eA±ŠtPT‡LjpYQ|†SH††YĀxinzDJ€Ìg¢và¥Pg‰_–ÇzII‹€II•„£®S¬„Øs쐣ŒN"],["@@ifjN@s"]],"encodeOffsets":[[[109628,30765]],[[111725,31320]]]}},{"type":"Feature","id":"810000","properties":{"id":"810000","cp":[114.173355,22.320048],"name":"香港","childNum":5},"geometry":{"type":"MultiPolygon","coordinates":[["@@AlBk"],["@@mŽn"],["@@EpFo"],["@@ea¢pl¸Eõ¹‡hj[ƒ]ÔCΖ@lj˜¡uBXŸ…•´‹AI¹…[‹yDUˆ]W`çwZkmc–…M›žp€Åv›}I‹oJlcaƒfёKްä¬XJmРđhI®æÔtSHn€Eˆ„ÒrÈc"],["@@rMUw‡AS®€e"]],"encodeOffsets":[[[117111,23002]],[[117072,22876]],[[117045,22887]],[[116975,23082]],[[116882,22747]]]}},{"type":"Feature","id":"820000","properties":{"id":"820000","cp":[113.54909,22.198951],"name":"澳门","childNum":1},"geometry":{"type":"Polygon","coordinates":["@@kÊd°å§s"],"encodeOffsets":[[116279,22639]]}}],"UTF8Encoding":true}); +})); diff --git a/src/pages/chart/ECharts/theme/macarons.js b/src/pages/chart/ECharts/theme/macarons.js new file mode 100644 index 0000000..3660c13 --- /dev/null +++ b/src/pages/chart/ECharts/theme/macarons.js @@ -0,0 +1,219 @@ +/* global define */ +;(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // eslint-disable-line + // AMD. Register as an anonymous module. + define(['exports', 'echarts'], factory) // eslint-disable-line + } else if ( + typeof exports === 'object' && + typeof exports.nodeName !== 'string' + ) { + // CommonJS + factory(exports, require('echarts')) + } else { + // Browser globals + factory({}, root.echarts) + } +})(this, (exports, echarts) => { + let log = function(msg) { + if (typeof console !== 'undefined') { + /* eslint-disable */ + console && console.error && console.error(msg) + } + } + if (!echarts) { + log('ECharts is not Loaded') + return + } + + let colorPalette = [ + '#2ec7c9', + '#b6a2de', + '#5ab1ef', + '#ffb980', + '#d87a80', + '#8d98b3', + '#e5cf0d', + '#97b552', + '#95706d', + '#dc69aa', + '#07a2a4', + '#9a7fd1', + '#588dd5', + '#f5994e', + '#c05050', + '#59678c', + '#c9ab00', + '#7eb00a', + '#6f5553', + '#c14089', + ] + + let theme = { + color: colorPalette, + + title: { + textStyle: { + fontWeight: 'normal', + color: '#008acd', + }, + }, + + visualMap: { + itemWidth: 15, + color: ['#5ab1ef', '#e0ffff'], + }, + + toolbox: { + iconStyle: { + normal: { + borderColor: colorPalette[0], + }, + }, + }, + + tooltip: { + backgroundColor: 'rgba(50,50,50,0.5)', + axisPointer: { + type: 'line', + lineStyle: { + color: '#008acd', + }, + crossStyle: { + color: '#008acd', + }, + shadowStyle: { + color: 'rgba(200,200,200,0.2)', + }, + }, + }, + + dataZoom: { + dataBackgroundColor: '#efefff', + fillerColor: 'rgba(182,162,222,0.2)', + handleColor: '#008acd', + }, + + grid: { + borderColor: '#eee', + }, + + categoryAxis: { + axisLine: { + lineStyle: { + color: '#008acd', + }, + }, + splitLine: { + lineStyle: { + color: ['#eee'], + }, + }, + }, + + valueAxis: { + axisLine: { + lineStyle: { + color: '#008acd', + }, + }, + splitArea: { + show: true, + areaStyle: { + color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'], + }, + }, + splitLine: { + lineStyle: { + color: ['#eee'], + }, + }, + }, + + timeline: { + lineStyle: { + color: '#008acd', + }, + controlStyle: { + normal: { color: '#008acd' }, + emphasis: { color: '#008acd' }, + }, + symbol: 'emptyCircle', + symbolSize: 3, + }, + + line: { + smooth: true, + symbol: 'emptyCircle', + symbolSize: 3, + }, + + candlestick: { + itemStyle: { + normal: { + color: '#d87a80', + color0: '#2ec7c9', + lineStyle: { + color: '#d87a80', + color0: '#2ec7c9', + }, + }, + }, + }, + + scatter: { + symbol: 'circle', + symbolSize: 4, + }, + + map: { + label: { + normal: { + textStyle: { + color: '#d87a80', + }, + }, + }, + itemStyle: { + normal: { + borderColor: '#eee', + areaColor: '#ddd', + }, + emphasis: { + areaColor: '#fe994e', + }, + }, + }, + + graph: { + color: colorPalette, + }, + + gauge: { + axisLine: { + lineStyle: { + color: [[0.2, '#2ec7c9'], [0.8, '#5ab1ef'], [1, '#d87a80']], + width: 10, + }, + }, + axisTick: { + splitNumber: 10, + length: 15, + lineStyle: { + color: 'auto', + }, + }, + splitLine: { + length: 22, + lineStyle: { + color: 'auto', + }, + }, + pointer: { + width: 5, + }, + }, + } + + echarts.registerTheme('macarons', theme) +}) diff --git a/src/pages/chart/ECharts/theme/shine.js b/src/pages/chart/ECharts/theme/shine.js new file mode 100644 index 0000000..bba7655 --- /dev/null +++ b/src/pages/chart/ECharts/theme/shine.js @@ -0,0 +1,169 @@ +/* global define */ +;(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // eslint-disable-line + // AMD. Register as an anonymous module. + define(['exports', 'echarts'], factory) // eslint-disable-line + } else if ( + typeof exports === 'object' && + typeof exports.nodeName !== 'string' + ) { + // CommonJS + factory(exports, require('echarts')) + } else { + // Browser globals + factory({}, root.echarts) + } +})(this, (exports, echarts) => { + let log = function(msg) { + if (typeof console !== 'undefined') { + /* eslint-disable */ + console && console.error && console.error(msg) + } + } + if (!echarts) { + log('ECharts is not Loaded') + return + } + + let colorPalette = [ + '#c12e34', + '#e6b600', + '#0098d9', + '#2b821d', + '#005eaa', + '#339ca8', + '#cda819', + '#32a487', + ] + + let theme = { + color: colorPalette, + + title: { + textStyle: { + fontWeight: 'normal', + }, + }, + + visualMap: { + color: ['#1790cf', '#a2d4e6'], + }, + + toolbox: { + iconStyle: { + normal: { + borderColor: '#06467c', + }, + }, + }, + + tooltip: { + backgroundColor: 'rgba(0,0,0,0.6)', + }, + + dataZoom: { + dataBackgroundColor: '#dedede', + fillerColor: 'rgba(154,217,247,0.2)', + handleColor: '#005eaa', + }, + + timeline: { + lineStyle: { + color: '#005eaa', + }, + controlStyle: { + normal: { + color: '#005eaa', + borderColor: '#005eaa', + }, + }, + }, + + candlestick: { + itemStyle: { + normal: { + color: '#c12e34', + color0: '#2b821d', + lineStyle: { + width: 1, + color: '#c12e34', + color0: '#2b821d', + }, + }, + }, + }, + + graph: { + color: colorPalette, + }, + + map: { + label: { + normal: { + textStyle: { + color: '#c12e34', + }, + }, + emphasis: { + textStyle: { + color: '#c12e34', + }, + }, + }, + itemStyle: { + normal: { + borderColor: '#eee', + areaColor: '#ddd', + }, + emphasis: { + areaColor: '#e6b600', + }, + }, + }, + + gauge: { + axisLine: { + show: true, + lineStyle: { + color: [[0.2, '#2b821d'], [0.8, '#005eaa'], [1, '#c12e34']], + width: 5, + }, + }, + axisTick: { + splitNumber: 10, + length: 8, + lineStyle: { + color: 'auto', + }, + }, + axisLabel: { + textStyle: { + color: 'auto', + }, + }, + splitLine: { + length: 12, + lineStyle: { + color: 'auto', + }, + }, + pointer: { + length: '90%', + width: 3, + color: 'auto', + }, + title: { + textStyle: { + color: '#333', + }, + }, + detail: { + textStyle: { + color: 'auto', + }, + }, + }, + } + echarts.registerTheme('shine', theme) +}) diff --git a/src/pages/chart/Recharts/AreaChartComponent.js b/src/pages/chart/Recharts/AreaChartComponent.js new file mode 100644 index 0000000..519a245 --- /dev/null +++ b/src/pages/chart/Recharts/AreaChartComponent.js @@ -0,0 +1,360 @@ +import React from 'react' +import { Row, Col, Card, Button } from 'antd' +import * as d3 from 'd3-shape' +import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts' +import Container from './Container' + +const data = [ + { + name: 'Page A', + uv: 4000, + pv: 2400, + amt: 2400, + }, + { + name: 'Page B', + uv: 3000, + pv: 1398, + amt: 2210, + }, + { + name: 'Page C', + uv: 2000, + pv: 9800, + amt: 2290, + }, + { + name: 'Page D', + uv: 2780, + pv: 3908, + amt: 2000, + }, + { + name: 'Page E', + uv: 1890, + pv: 4800, + amt: 2181, + }, + { + name: 'Page F', + uv: 2390, + pv: 3800, + amt: 2500, + }, + { + name: 'Page G', + uv: 3490, + pv: 4300, + amt: 2100, + }, +] + +const mixData = [ + { + name: 'Page A', + uv: 4000, + pv: 2400, + amt: 2400, + }, + { + name: 'Page B', + uv: 3000, + pv: 1398, + amt: 2210, + }, + { + name: 'Page C', + uv: 2000, + pv: 9800, + amt: 2290, + }, + { + name: 'Page D', + uv: 2780, + pv: 3908, + amt: 2000, + }, + { + name: 'Page E', + uv: 1890, + pv: 4800, + amt: 2181, + }, + { + name: 'Page F', + uv: 2390, + pv: 3800, + amt: 2500, + }, + { + name: 'Page G', + uv: 3490, + pv: 4300, + amt: 2100, + }, +] + +const percentData = [ + { + month: '2015.01', + a: 4000, + b: 2400, + c: 2400, + }, + { + month: '2015.02', + a: 3000, + b: 1398, + c: 2210, + }, + { + month: '2015.03', + a: 2000, + b: 9800, + c: 2290, + }, + { + month: '2015.04', + a: 2780, + b: 3908, + c: 2000, + }, + { + month: '2015.05', + a: 1890, + b: 4800, + c: 2181, + }, + { + month: '2015.06', + a: 2390, + b: 3800, + c: 2500, + }, + { + month: '2015.07', + a: 3490, + b: 4300, + c: 2100, + }, +] + +const colProps = { + lg: 12, + md: 24, +} + +const SimpleAreaChart = () => ( + + + + + + + + + +) + +const StackedAreaChart = () => ( + + + + + + + + + + + +) + +// StackedAreaChart + +const toPercent = (decimal, fixed = 0) => { + return `${(decimal * 100).toFixed(fixed)}%` +} + +const getPercent = (value, total) => { + const ratio = total > 0 ? value / total : 0 + + return toPercent(ratio, 2) +} + +const renderTooltipContent = o => { + const { payload, label } = o + const total = payload.reduce((result, entry) => result + entry.value, 0) + + return ( +
+

{`${label} (Total: ${total})`}

+
    + {payload.map((entry, index) => ( +
  • + {`${entry.name}: ${entry.value}(${getPercent(entry.value, total)})`} +
  • + ))} +
+
+ ) +} + +const PercentAreaChart = () => ( + + + + + + + + + + + +) + +// CardinalAreaChart +const cardinal = d3.curveCardinal.tension(0.2) +const CardinalAreaChart = () => ( + + + + + + + + + + +) + +const AreaChartPage = () => ( +
+ + + + + + + + + + + + + + + + + + + + + + + +
+) + +export default AreaChartPage diff --git a/src/pages/chart/Recharts/BarChartComponent.js b/src/pages/chart/Recharts/BarChartComponent.js new file mode 100644 index 0000000..e524ea7 --- /dev/null +++ b/src/pages/chart/Recharts/BarChartComponent.js @@ -0,0 +1,260 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Row, Col, Card, Button } from 'antd' +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, +} from 'recharts' +import Container from './Container' + +const data = [ + { + name: 'Page A', + uv: 4000, + pv: 2400, + amt: 2400, + }, + { + name: 'Page B', + uv: 3000, + pv: 1398, + amt: 2210, + }, + { + name: 'Page C', + uv: 2000, + pv: 9800, + amt: 2290, + }, + { + name: 'Page D', + uv: 2780, + pv: 3908, + amt: 2000, + }, + { + name: 'Page E', + uv: 1890, + pv: 4800, + amt: 2181, + }, + { + name: 'Page F', + uv: 2390, + pv: 3800, + amt: 2500, + }, + { + name: 'Page G', + uv: 3490, + pv: 4300, + amt: 2100, + }, +] + +const mixData = [ + { + name: 'Page A', + uv: 4000, + female: 2400, + male: 2400, + }, + { + name: 'Page B', + uv: 3000, + female: 1398, + male: 2210, + }, + { + name: 'Page C', + uv: 2000, + female: 9800, + male: 2290, + }, + { + name: 'Page D', + uv: 2780, + female: 3908, + male: 2000, + }, + { + name: 'Page E', + uv: 1890, + female: 4800, + male: 2181, + }, + { + name: 'Page F', + uv: 2390, + female: 3800, + male: 2500, + }, + { + name: 'Page G', + uv: 3490, + female: 4300, + male: 2100, + }, +] +const colProps = { + lg: 12, + md: 24, +} + +const SimpleBarChart = () => ( + + + + + + + + + + + +) + +const StackedBarChart = () => ( + + + + + + + + + + + +) + +const MixBarChart = () => ( + + + + + + + + + + + + +) + +// CustomShapeBarChart +const getPath = (x, y, width, height) => { + return `M${x},${y + height} + C${x + width / 3},${y + height} ${x + width / 2},${y + height / 3} ${x + + width / 2}, ${y} + C${x + width / 2},${y + height / 3} ${x + (2 * width) / 3},${y + + height} ${x + width}, ${y + height} + Z` +} + +const TriangleBar = props => { + const { fill, x, y, width, height } = props + return +} + +TriangleBar.propTypes = { + fill: PropTypes.string, + x: PropTypes.number, + y: PropTypes.number, + width: PropTypes.number, + height: PropTypes.number, +} + +const CustomShapeBarChart = () => ( + + + + + + } label /> + + +) + +const BarChartPage = () => ( +
+ + + + + + + + + + + + + + + + + + + + + + + +
+) + +export default BarChartPage diff --git a/src/pages/chart/Recharts/Container.js b/src/pages/chart/Recharts/Container.js new file mode 100644 index 0000000..5c19608 --- /dev/null +++ b/src/pages/chart/Recharts/Container.js @@ -0,0 +1,27 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { ResponsiveContainer } from 'recharts' +import styles from './Container.less' + +const Container = ({ + children, + ratio = 5 / 2, + minHeight = 250, + maxHeight = 350, +}) => ( +
+
+
+ {children} +
+
+) + +Container.propTypes = { + children: PropTypes.element.isRequired, + ratio: PropTypes.number, + minHeight: PropTypes.number, + maxHeight: PropTypes.number, +} + +export default Container diff --git a/src/pages/chart/Recharts/Container.less b/src/pages/chart/Recharts/Container.less new file mode 100644 index 0000000..daa5c27 --- /dev/null +++ b/src/pages/chart/Recharts/Container.less @@ -0,0 +1,20 @@ +.container { + width: 100%; + position: relative; + display: inline-block; + + :global { + .recharts-responsive-container { + width: e('calc(100% + 56px)') !important; + margin-left: -32px; + } + } +} + +.content { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; +} diff --git a/src/pages/chart/Recharts/LineChartComponent.js b/src/pages/chart/Recharts/LineChartComponent.js new file mode 100644 index 0000000..a249cdf --- /dev/null +++ b/src/pages/chart/Recharts/LineChartComponent.js @@ -0,0 +1,261 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Row, Col, Card, Button } from 'antd' +import { + LineChart, + Line, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, +} from 'recharts' +import Container from './Container' + +const data = [ + { + name: 'Page A', + uv: 4000, + pv: 2400, + amt: 2400, + }, + { + name: 'Page B', + uv: 3000, + pv: 1398, + amt: 2210, + }, + { + name: 'Page C', + uv: 2000, + pv: 9800, + amt: 2290, + }, + { + name: 'Page D', + uv: 2780, + pv: 3908, + amt: 2000, + }, + { + name: 'Page E', + uv: 1890, + pv: 4800, + amt: 2181, + }, + { + name: 'Page F', + uv: 2390, + pv: 3800, + amt: 2500, + }, + { + name: 'Page G', + uv: 3490, + pv: 4300, + amt: 2100, + }, +] + +const colProps = { + lg: 12, + md: 24, +} + +const SimpleLineChart = () => ( + + + + + + + + + + + +) + +const VerticalLineChart = () => ( + + + + + + + + + + + +) + +const DashedLineChart = () => ( + + + + + + + + + + + +) + +// CustomizedDotLineChart +const CustomizedDot = ({ cx, cy, payload }) => { + if (payload.value > 2500) { + return ( + + + + ) + } + + return ( + + + + ) +} + +CustomizedDot.propTypes = { + cx: PropTypes.number, + cy: PropTypes.number, + payload: PropTypes.object, +} + +const CustomizedDotLineChart = () => ( + + + + + + + + } + /> + + + +) + +const LineChartPage = () => ( +
+ + + + + + + + + + + + + + + + + + + + + + + +
+) + +export default LineChartPage diff --git a/src/pages/chart/Recharts/ReChartsComponent.js b/src/pages/chart/Recharts/ReChartsComponent.js new file mode 100644 index 0000000..9ed7acc --- /dev/null +++ b/src/pages/chart/Recharts/ReChartsComponent.js @@ -0,0 +1,18 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import AreaChartComponent from './AreaChartComponent' +import BarChartComponent from './BarChartComponent' +import LineChartComponent from './LineChartComponent' + +const ReChartsComponent = ({ type }) => { + if (type === 'areaChart') return + if (type === 'barChart') return + return +} + +ReChartsComponent.propTypes = { + type: PropTypes.string, +} + +export default ReChartsComponent diff --git a/src/pages/chart/Recharts/index.js b/src/pages/chart/Recharts/index.js new file mode 100644 index 0000000..fec6ce2 --- /dev/null +++ b/src/pages/chart/Recharts/index.js @@ -0,0 +1,53 @@ +import React from 'react' +import { Radio } from 'antd' +import { Page } from 'components' +import ReChartsComponent from './ReChartsComponent' +import styles from './index.less' + +const RadioGroup = Radio.Group + +const chartList = [ + { + label: 'lineChart', + value: 'lineChart', + }, + { + label: 'barChart', + value: 'barChart', + }, + { + label: 'areaChart', + value: 'areaChart', + }, +] + +class Chart extends React.Component { + constructor() { + super() + this.state = { + type: '', + } + this.handleRadioGroupChange = this.handleRadioGroupChange.bind(this) + } + handleRadioGroupChange(e) { + this.setState({ + type: e.target.value, + }) + } + render() { + return ( + + +
+ +
+
+ ) + } +} + +export default Chart diff --git a/src/pages/chart/Recharts/index.less b/src/pages/chart/Recharts/index.less new file mode 100644 index 0000000..169053a --- /dev/null +++ b/src/pages/chart/Recharts/index.less @@ -0,0 +1,8 @@ +.chart { + :global { + .ant-card { + overflow: hidden; + margin-bottom: 24px; + } + } +} diff --git a/src/pages/chart/highCharts/HighChartsComponent.js b/src/pages/chart/highCharts/HighChartsComponent.js new file mode 100644 index 0000000..520e08a --- /dev/null +++ b/src/pages/chart/highCharts/HighChartsComponent.js @@ -0,0 +1,18 @@ +import React from 'react' +import PropTypes from 'prop-types' + +import HighstockComponent from './HighstockComponent' +import HighmapsComponent from './HighmapsComponent' +import HighMoreComponent from './HighMoreComponent' + +const HighChartsComponent = ({ type }) => { + if (type === 'Highmaps') return + if (type === 'HighMore') return + return +} + +HighChartsComponent.propTypes = { + type: PropTypes.string, +} + +export default HighChartsComponent diff --git a/src/pages/chart/highCharts/HighMoreComponent.js b/src/pages/chart/highCharts/HighMoreComponent.js new file mode 100644 index 0000000..0c6273c --- /dev/null +++ b/src/pages/chart/highCharts/HighMoreComponent.js @@ -0,0 +1,53 @@ +import React from 'react' +import ReactHighcharts from 'react-highcharts' +import HighchartsExporting from 'highcharts-exporting' +import HighchartsMore from 'highcharts-more' + +HighchartsMore(ReactHighcharts.Highcharts) +HighchartsExporting(ReactHighcharts.Highcharts) + +const config = { + chart: { + polar: true, + }, + xAxis: { + categories: [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + ], + }, + series: [ + { + data: [ + 29.9, + 71.5, + 106.4, + 129.2, + 144.0, + 176.0, + 135.6, + 148.5, + 216.4, + 194.1, + 95.6, + 54.4, + ], + }, + ], +} + +const HighMoreComponent = () => { + return +} + +export default HighMoreComponent diff --git a/src/pages/chart/highCharts/HighmapsComponent.js b/src/pages/chart/highCharts/HighmapsComponent.js new file mode 100644 index 0000000..f74527b --- /dev/null +++ b/src/pages/chart/highCharts/HighmapsComponent.js @@ -0,0 +1,81 @@ +import React from 'react' +import ReactHighmaps from 'react-highcharts/ReactHighmaps.src' +import maps from './mapdata/europe' + +const config = { + chart: { + spacingBottom: 20, + }, + title: { + text: 'Europe time zones', + }, + + legend: { + enabled: true, + }, + + plotOptions: { + map: { + allAreas: false, + joinBy: ['iso-a2', 'code'], + dataLabels: { + enabled: true, + color: 'white', + style: { + fontWeight: 'bold', + }, + }, + mapData: maps, + tooltip: { + headerFormat: '', + pointFormat: '{point.name}: {series.name}', + }, + }, + }, + + series: [ + { + name: 'UTC', + data: ['IE', 'IS', 'GB', 'PT'].map(code => { + return { code } + }), + }, + { + name: 'UTC + 1', + data: [ + 'NO', + 'SE', + 'DK', + 'DE', + 'NL', + 'BE', + 'LU', + 'ES', + 'FR', + 'PL', + 'CZ', + 'AT', + 'CH', + 'LI', + 'SK', + 'HU', + 'SI', + 'IT', + 'SM', + 'HR', + 'BA', + 'YF', + 'ME', + 'AL', + 'MK', + ].map(code => { + return { code } + }), + }, + ], +} + +const HighmapsComponent = () => { + return +} +export default HighmapsComponent diff --git a/src/pages/chart/highCharts/HighstockComponent.js b/src/pages/chart/highCharts/HighstockComponent.js new file mode 100644 index 0000000..e2cd4e5 --- /dev/null +++ b/src/pages/chart/highCharts/HighstockComponent.js @@ -0,0 +1,99 @@ +import React from 'react' +import ReactHighstock from 'react-highcharts/ReactHighstock.src' + +const data = [ + [1220832000000, 22.56], + [1220918400000, 21.67], + [1221004800000, 21.66], + [1221091200000, 21.81], + [1221177600000, 21.28], + [1221436800000, 20.05], + [1221523200000, 19.98], + [1221609600000, 18.26], + [1221696000000, 19.16], + [1221782400000, 20.13], + [1222041600000, 18.72], + [1222128000000, 18.12], + [1222214400000, 18.39], + [1222300800000, 18.85], + [1222387200000, 18.32], + [1222646400000, 15.04], + [1222732800000, 16.24], + [1222819200000, 15.59], + [1222905600000, 14.3], + [1222992000000, 13.87], + [1223251200000, 14.02], + [1223337600000, 12.74], + [1223424000000, 12.83], + [1223510400000, 12.68], + [1223596800000, 13.8], + [1223856000000, 15.75], + [1223942400000, 14.87], + [1224028800000, 13.99], + [1224115200000, 14.56], + [1224201600000, 13.91], + [1224460800000, 14.06], + [1224547200000, 13.07], + [1224633600000, 13.84], + [1224720000000, 14.03], + [1224806400000, 13.77], + [1225065600000, 13.16], + [1225152000000, 14.27], + [1225238400000, 14.94], + [1225324800000, 15.86], + [1225411200000, 15.37], + [1225670400000, 15.28], + [1225756800000, 15.86], + [1225843200000, 14.76], + [1225929600000, 14.16], + [1226016000000, 14.03], + [1226275200000, 13.7], + [1226361600000, 13.54], + [1226448000000, 12.87], + [1226534400000, 13.78], + [1226620800000, 12.89], + [1226880000000, 12.59], + [1226966400000, 12.84], + [1227052800000, 12.33], + [1227139200000, 11.5], + [1227225600000, 11.8], + [1227484800000, 13.28], + [1227571200000, 12.97], + [1227657600000, 13.57], + [1227830400000, 13.24], + [1228089600000, 12.7], + [1228176000000, 13.21], + [1228262400000, 13.7], + [1228348800000, 13.06], + [1228435200000, 13.43], + [1228694400000, 14.25], + [1228780800000, 14.29], + [1228867200000, 14.03], + [1228953600000, 13.57], + [1229040000000, 14.04], + [1229299200000, 13.54], +] + +const config = { + rangeSelector: { + selected: 1, + }, + title: { + text: 'AAPL Stock Price', + }, + series: [ + { + name: 'AAPL', + data, + tooltip: { + valueDecimals: 2, + }, + }, + ], +} + +const HighstockComponent = () => { + return +} + +export default HighstockComponent diff --git a/src/pages/chart/highCharts/index.js b/src/pages/chart/highCharts/index.js new file mode 100644 index 0000000..44a80de --- /dev/null +++ b/src/pages/chart/highCharts/index.js @@ -0,0 +1,53 @@ +import React from 'react' +import { Radio } from 'antd' +import { Page } from 'components' +import HighChartsComponent from './HighChartsComponent' +import styles from './index.less' + +const RadioGroup = Radio.Group + +const chartList = [ + { + label: 'Highstock', + value: 'Highstock', + }, + { + label: 'Highmaps', + value: 'Highmaps', + }, + { + label: 'HighMore', + value: 'HighMore', + }, +] + +class Chart extends React.Component { + constructor() { + super() + this.state = { + type: '', + } + this.handleRadioGroupChange = this.handleRadioGroupChange.bind(this) + } + handleRadioGroupChange(e) { + this.setState({ + type: e.target.value, + }) + } + render() { + return ( + + +
+ +
+
+ ) + } +} + +export default Chart diff --git a/src/pages/chart/highCharts/index.less b/src/pages/chart/highCharts/index.less new file mode 100644 index 0000000..2926f77 --- /dev/null +++ b/src/pages/chart/highCharts/index.less @@ -0,0 +1,7 @@ +.chart { + :global { + .ant-radio-wrapper { + margin-bottom: 16px; + } + } +} diff --git a/src/pages/chart/highCharts/mapdata/europe.js b/src/pages/chart/highCharts/mapdata/europe.js new file mode 100644 index 0000000..95a13c9 --- /dev/null +++ b/src/pages/chart/highCharts/mapdata/europe.js @@ -0,0 +1,9162 @@ +module.exports = { + title: 'Europe', + version: '1.1.2', + type: 'FeatureCollection', + copyright: 'Copyright (c) 2015 Highsoft AS, Based on data from Natural Earth', + copyrightShort: 'Natural Earth', + copyrightUrl: 'http://www.naturalearthdata.com', + crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:EPSG:102014' } }, + 'hc-transform': { + default: { + crs: + '+proj=lcc +lat_1=43 +lat_2=62 +lat_0=30 +lon_0=10 +x_0=0 +y_0=0 +ellps=intl +units=m +no_defs', + scale: 0.000169255094964, + jsonres: 15.5, + jsonmarginX: -999, + jsonmarginY: 9851.0, + xoffset: -1706316.2597, + yoffset: 4824494.18154, + }, + }, + features: [ + { + type: 'Feature', + id: 'DK', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.19, + 'hc-middle-y': 0.44, + 'hc-key': 'dk', + 'hc-a2': 'DK', + name: 'Denmark', + labelrank: '4', + 'country-abbrev': 'Den.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'DNK', + 'iso-a2': 'DK', + 'woe-id': '23424796', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [3686, 4530], + [3743, 4490], + [3764, 4508], + [3787, 4471], + [3773, 4443], + [3724, 4436], + [3644, 4481], + [3658, 4526], + [3686, 4530], + ], + ], + [ + [ + [3536, 4512], + [3564, 4499], + [3541, 4493], + [3513, 4524], + [3536, 4512], + ], + ], + [ + [ + [3898, 4549], + [3847, 4516], + [3831, 4533], + [3864, 4557], + [3898, 4549], + ], + ], + [ + [ + [3443, 4565], + [3482, 4530], + [3472, 4501], + [3447, 4513], + [3443, 4565], + ], + ], + [ + [ + [3616, 4524], + [3599, 4467], + [3584, 4496], + [3635, 4587], + [3616, 4524], + ], + ], + [ + [ + [4282, 4636], + [4328, 4610], + [4317, 4568], + [4251, 4596], + [4260, 4656], + [4282, 4636], + ], + ], + [ + [ + [3217, 4671], + [3225, 4667], + [3223, 4642], + [3210, 4667], + [3217, 4671], + ], + ], + [ + [ + [3533, 4717], + [3608, 4645], + [3599, 4563], + [3567, 4550], + [3511, 4568], + [3458, 4614], + [3459, 4642], + [3424, 4684], + [3533, 4717], + ], + ], + [ + [ + [3899, 4708], + [3889, 4727], + [3902, 4751], + [3914, 4724], + [3899, 4708], + ], + ], + [ + [ + [3578, 4795], + [3579, 4771], + [3562, 4769], + [3572, 4800], + [3578, 4795], + ], + ], + [ + [ + [3306, 5107], + [3300, 5063], + [3263, 5028], + [3247, 5060], + [3264, 5089], + [3306, 5107], + ], + ], + [ + [ + [3664, 5214], + [3644, 5204], + [3639, 5178], + [3611, 5196], + [3664, 5214], + ], + ], + [ + [ + [3282, 4516], + [3255, 4513], + [3260, 4582], + [3227, 4563], + [3225, 4595], + [3261, 4584], + [3251, 4670], + [3201, 4707], + [3166, 4708], + [3184, 4779], + [3216, 4802], + [3200, 4855], + [3172, 4868], + [3178, 4993], + [3188, 5027], + [3208, 5000], + [3249, 4999], + [3274, 4971], + [3277, 5015], + [3312, 5063], + [3347, 5035], + [3326, 5010], + [3362, 5013], + [3345, 5088], + [3389, 5126], + [3417, 5111], + [3444, 5148], + [3362, 5120], + [3338, 5136], + [3269, 5107], + [3237, 5058], + [3245, 5003], + [3199, 5057], + [3260, 5156], + [3385, 5166], + [3411, 5189], + [3472, 5289], + [3508, 5292], + [3570, 5336], + [3544, 5283], + [3563, 5244], + [3562, 5187], + [3548, 5172], + [3519, 5092], + [3535, 4992], + [3603, 4985], + [3632, 4960], + [3598, 4893], + [3578, 4899], + [3563, 4859], + [3558, 4910], + [3542, 4916], + [3513, 4872], + [3517, 4805], + [3460, 4782], + [3487, 4757], + [3444, 4736], + [3454, 4722], + [3395, 4683], + [3430, 4613], + [3394, 4588], + [3434, 4536], + [3435, 4494], + [3409, 4521], + [3384, 4487], + [3384, 4487], + [3282, 4516], + ], + ], + [ + [ + [3717, 4815], + [3747, 4806], + [3772, 4741], + [3805, 4817], + [3779, 4826], + [3839, 4872], + [3901, 4850], + [3884, 4814], + [3901, 4753], + [3845, 4704], + [3842, 4672], + [3879, 4649], + [3871, 4621], + [3837, 4612], + [3834, 4545], + [3818, 4538], + [3838, 4500], + [3805, 4457], + [3768, 4508], + [3790, 4538], + [3750, 4596], + [3685, 4601], + [3656, 4648], + [3675, 4656], + [3665, 4703], + [3634, 4751], + [3681, 4753], + [3717, 4786], + [3717, 4815], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'FO', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.56, + 'hc-middle-y': 0.16, + 'hc-key': 'fo', + 'hc-a2': 'FO', + name: 'Faroe Islands', + labelrank: '6', + 'country-abbrev': 'Faeroe Is.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'FRO', + 'iso-a2': 'FO', + 'woe-id': '23424816', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [1151, 6735], + [1169, 6717], + [1165, 6663], + [1146, 6700], + [1151, 6735], + ], + ], + [ + [ + [1176, 6812], + [1202, 6782], + [1190, 6763], + [1169, 6796], + [1176, 6812], + ], + ], + [ + [ + [1150, 6888], + [1163, 6872], + [1139, 6859], + [1115, 6902], + [1150, 6888], + ], + ], + [ + [ + [1158, 6940], + [1202, 6846], + [1193, 6819], + [1166, 6880], + [1143, 6903], + [1158, 6940], + ], + ], + [ + [ + [1199, 6933], + [1230, 6870], + [1208, 6857], + [1181, 6898], + [1172, 6936], + [1199, 6933], + ], + ], + [ + [ + [1236, 6908], + [1230, 6914], + [1227, 6927], + [1232, 6941], + [1236, 6908], + ], + ], + [ + [ + [1226, 6902], + [1222, 6904], + [1215, 6942], + [1217, 6946], + [1226, 6902], + ], + ], + [ + [ + [1254, 6915], + [1248, 6943], + [1254, 6940], + [1257, 6921], + [1255, 6914], + [1263, 6903], + [1246, 6901], + [1239, 6895], + [1243, 6931], + [1254, 6915], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'HR', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.09, + 'hc-middle-y': 0.39, + 'hc-key': 'hr', + 'hc-a2': 'HR', + name: 'Croatia', + labelrank: '6', + 'country-abbrev': 'Cro.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'HRV', + 'iso-a2': 'HR', + 'woe-id': '23424843', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [4965, 1080], + [4964, 1071], + [4945, 1066], + [4938, 1078], + [4965, 1080], + ], + ], + [ + [ + [5060, 1097], + [5137, 1081], + [5142, 1075], + [5062, 1089], + [5060, 1097], + ], + ], + [ + [ + [4924, 1135], + [4980, 1143], + [5017, 1129], + [4944, 1116], + [4924, 1135], + ], + ], + [ + [ + [4799, 1153], + [4804, 1142], + [4785, 1134], + [4768, 1148], + [4799, 1153], + ], + ], + [ + [ + [4873, 1205], + [4915, 1189], + [5010, 1189], + [4904, 1178], + [4834, 1192], + [4873, 1205], + ], + ], + [ + [ + [4922, 1243], + [4925, 1221], + [4841, 1228], + [4840, 1250], + [4922, 1243], + ], + ], + [ + [ + [4813, 1251], + [4834, 1236], + [4825, 1233], + [4794, 1244], + [4813, 1251], + ], + ], + [ + [ + [4621, 1380], + [4603, 1384], + [4580, 1409], + [4607, 1399], + [4621, 1380], + ], + ], + [ + [ + [4572, 1425], + [4565, 1419], + [4550, 1431], + [4536, 1450], + [4572, 1425], + ], + ], + [ + [ + [4496, 1441], + [4573, 1380], + [4557, 1376], + [4526, 1418], + [4496, 1441], + ], + ], + [ + [ + [4482, 1574], + [4494, 1578], + [4572, 1505], + [4495, 1543], + [4482, 1574], + ], + ], + [ + [ + [4392, 1569], + [4391, 1562], + [4374, 1601], + [4388, 1593], + [4392, 1569], + ], + ], + [ + [ + [4458, 1644], + [4474, 1623], + [4481, 1604], + [4444, 1643], + [4458, 1644], + ], + ], + [ + [ + [4398, 1672], + [4394, 1585], + [4363, 1666], + [4381, 1672], + [4355, 1720], + [4372, 1729], + [4398, 1672], + ], + ], + [ + [ + [4412, 1758], + [4435, 1713], + [4468, 1683], + [4386, 1710], + [4412, 1758], + ], + ], + [ + [ + [5311, 1013], + [5150, 1111], + [5070, 1120], + [5023, 1159], + [5115, 1130], + [5161, 1114], + [5293, 1053], + [5298, 1030], + [5311, 1013], + ], + ], + [ + [ + [5272, 2037], + [5265, 2001], + [5308, 1936], + [5313, 1878], + [5390, 1853], + [5399, 1831], + [5332, 1816], + [5333, 1734], + [5308, 1729], + [5259, 1787], + [5229, 1777], + [5164, 1799], + [5120, 1791], + [5085, 1763], + [5051, 1788], + [5030, 1773], + [4966, 1787], + [4950, 1773], + [4893, 1807], + [4867, 1774], + [4805, 1774], + [4781, 1716], + [4754, 1721], + [4705, 1771], + [4662, 1750], + [4668, 1659], + [4747, 1571], + [4775, 1482], + [4881, 1385], + [4890, 1365], + [4976, 1298], + [5010, 1291], + [5019, 1256], + [5062, 1201], + [5095, 1184], + [5098, 1143], + [4981, 1218], + [4936, 1263], + [4860, 1282], + [4742, 1274], + [4729, 1323], + [4625, 1387], + [4544, 1481], + [4583, 1510], + [4492, 1601], + [4491, 1679], + [4468, 1723], + [4415, 1769], + [4362, 1786], + [4296, 1624], + [4219, 1709], + [4192, 1822], + [4209, 1816], + [4271, 1801], + [4286, 1828], + [4369, 1822], + [4403, 1876], + [4428, 1842], + [4525, 1818], + [4570, 1837], + [4542, 1900], + [4581, 1934], + [4624, 1943], + [4625, 2002], + [4602, 2023], + [4614, 2053], + [4734, 2110], + [4722, 2143], + [4777, 2150], + [4851, 2116], + [4877, 2075], + [4924, 2054], + [4959, 2009], + [5008, 2009], + [5070, 1968], + [5138, 1979], + [5180, 1971], + [5227, 2026], + [5272, 2037], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'NL', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.34, + 'hc-middle-y': 0.59, + 'hc-key': 'nl', + 'hc-a2': 'NL', + name: 'Netherlands', + labelrank: '5', + 'country-abbrev': 'Neth.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'NLD', + 'iso-a2': 'NL', + 'woe-id': '-90', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [2408, 3636], + [2399, 3614], + [2350, 3647], + [2395, 3648], + [2408, 3636], + ], + ], + [ + [ + [2593, 4028], + [2574, 3998], + [2561, 4015], + [2588, 4051], + [2593, 4028], + ], + ], + [ + [ + [2603, 4061], + [2593, 4060], + [2613, 4079], + [2625, 4085], + [2603, 4061], + ], + ], + [ + [ + [2691, 4107], + [2652, 4094], + [2648, 4104], + [2719, 4119], + [2691, 4107], + ], + ], + [ + [ + [2776, 4121], + [2783, 4117], + [2735, 4111], + [2734, 4122], + [2776, 4121], + ], + ], + [ + [ + [2817, 4118], + [2812, 4122], + [2827, 4129], + [2847, 4126], + [2817, 4118], + ], + ], + [ + [ + [2280, 3553], + [2316, 3561], + [2371, 3536], + [2395, 3553], + [2437, 3537], + [2380, 3495], + [2330, 3523], + [2285, 3515], + [2280, 3553], + ], + ], + [ + [ + [2444, 3537], + [2389, 3565], + [2367, 3550], + [2316, 3574], + [2305, 3602], + [2372, 3613], + [2422, 3559], + [2444, 3580], + [2400, 3604], + [2436, 3629], + [2402, 3678], + [2414, 3716], + [2438, 3721], + [2510, 3811], + [2565, 3989], + [2593, 3969], + [2677, 4019], + [2717, 4076], + [2786, 4101], + [2916, 4110], + [2993, 4045], + [2988, 3965], + [2969, 3933], + [2959, 3874], + [2912, 3874], + [2897, 3827], + [2945, 3818], + [2952, 3754], + [2887, 3701], + [2910, 3678], + [2832, 3644], + [2788, 3666], + [2751, 3642], + [2779, 3594], + [2794, 3519], + [2766, 3475], + [2780, 3452], + [2737, 3419], + [2761, 3382], + [2746, 3338], + [2690, 3344], + [2723, 3456], + [2660, 3498], + [2614, 3492], + [2581, 3557], + [2561, 3534], + [2537, 3566], + [2511, 3546], + [2486, 3564], + [2467, 3530], + [2444, 3537], + ], + [ + [2720, 3812], + [2735, 3822], + [2736, 3825], + [2736, 3825], + [2736, 3825], + [2750, 3836], + [2750, 3869], + [2717, 3876], + [2748, 3862], + [2736, 3825], + [2736, 3825], + [2736, 3825], + [2720, 3812], + [2720, 3812], + [2720, 3812], + [2720, 3812], + [2670, 3782], + [2621, 3817], + [2717, 3877], + [2712, 3924], + [2732, 3940], + [2678, 3949], + [2676, 4013], + [2616, 3976], + [2626, 3929], + [2657, 3907], + [2608, 3887], + [2614, 3833], + [2591, 3815], + [2674, 3776], + [2720, 3812], + [2720, 3812], + [2720, 3812], + [2720, 3812], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'EE', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.6, + 'hc-middle-y': 0.53, + 'hc-key': 'ee', + 'hc-a2': 'EE', + name: 'Estonia', + labelrank: '6', + 'country-abbrev': 'Est.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'EST', + 'iso-a2': 'EE', + 'woe-id': '23424805', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [5483, 5775], + [5469, 5746], + [5441, 5761], + [5452, 5784], + [5483, 5775], + ], + ], + [ + [ + [5440, 5891], + [5460, 5893], + [5468, 5876], + [5435, 5869], + [5440, 5891], + ], + ], + [ + [ + [5370, 5868], + [5403, 5866], + [5426, 5828], + [5383, 5810], + [5362, 5771], + [5337, 5813], + [5275, 5835], + [5334, 5850], + [5348, 5887], + [5370, 5868], + ], + ], + [ + [ + [6143, 6139], + [6134, 6134], + [6119, 6126], + [6130, 6125], + [6130, 6125], + [6131, 6125], + [6133, 6126], + [6124, 6119], + [6106, 6106], + [6108, 6072], + [6106, 6046], + [6102, 6021], + [6074, 6020], + [6012, 5988], + [6005, 5937], + [6044, 5907], + [6076, 5839], + [6106, 5812], + [6161, 5739], + [6194, 5705], + [6159, 5682], + [6151, 5595], + [6071, 5605], + [6022, 5561], + [5934, 5617], + [5926, 5637], + [5861, 5642], + [5801, 5677], + [5699, 5617], + [5669, 5588], + [5681, 5651], + [5674, 5732], + [5642, 5736], + [5618, 5688], + [5557, 5706], + [5535, 5759], + [5512, 5760], + [5504, 5815], + [5545, 5818], + [5543, 5838], + [5488, 5817], + [5479, 5858], + [5495, 5879], + [5471, 5891], + [5470, 5946], + [5555, 5992], + [5541, 6009], + [5694, 6088], + [5735, 6082], + [5770, 6142], + [5882, 6132], + [5912, 6141], + [5940, 6125], + [6095, 6143], + [6111, 6169], + [6126, 6160], + [6143, 6139], + ], + ], + [ + [ + [5280, 5633], + [5297, 5662], + [5272, 5700], + [5306, 5706], + [5369, 5757], + [5380, 5746], + [5417, 5762], + [5487, 5731], + [5463, 5728], + [5448, 5692], + [5403, 5642], + [5351, 5628], + [5342, 5561], + [5313, 5556], + [5336, 5608], + [5280, 5633], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'BG', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.54, + 'hc-middle-y': 0.49, + 'hc-key': 'bg', + 'hc-a2': 'BG', + name: 'Bulgaria', + labelrank: '4', + 'country-abbrev': 'Bulg.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'BGR', + 'iso-a2': 'BG', + 'woe-id': '23424771', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [7353, 1794], + [7373, 1738], + [7359, 1683], + [7291, 1678], + [7265, 1596], + [7264, 1551], + [7287, 1467], + [7255, 1461], + [7212, 1374], + [7250, 1382], + [7288, 1337], + [7352, 1291], + [7366, 1265], + [7320, 1259], + [7271, 1219], + [7200, 1259], + [7149, 1241], + [7136, 1215], + [7058, 1175], + [7060, 1145], + [7026, 1104], + [6967, 1083], + [7003, 1040], + [7004, 992], + [6956, 965], + [6884, 953], + [6831, 918], + [6735, 946], + [6714, 926], + [6671, 941], + [6645, 975], + [6547, 945], + [6462, 882], + [6390, 877], + [6357, 845], + [6313, 844], + [6303, 916], + [6313, 957], + [6262, 1037], + [6189, 1058], + [6140, 1104], + [6170, 1136], + [6144, 1181], + [6146, 1270], + [6192, 1283], + [6229, 1382], + [6118, 1443], + [6066, 1533], + [6067, 1588], + [6105, 1620], + [6108, 1660], + [6115, 1666], + [6116, 1666], + [6193, 1640], + [6168, 1606], + [6183, 1561], + [6264, 1592], + [6444, 1587], + [6512, 1615], + [6610, 1620], + [6698, 1611], + [6780, 1652], + [6838, 1749], + [7006, 1837], + [7055, 1833], + [7089, 1809], + [7144, 1825], + [7163, 1808], + [7199, 1830], + [7223, 1793], + [7278, 1781], + [7353, 1794], + ], + ], + }, + }, + { + type: 'Feature', + id: 'ES', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.38, + 'hc-middle-y': 0.53, + 'hc-key': 'es', + 'hc-a2': 'ES', + name: 'Spain', + labelrank: '2', + 'country-abbrev': 'Sp.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'ESP', + 'iso-a2': 'ES', + 'woe-id': '23424950', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [[[1502, -54], [1511, -71], [1486, -84], [1488, -64], [1502, -54]]], + [ + [ + [1546, 46], + [1554, 23], + [1497, -29], + [1456, -3], + [1495, 44], + [1546, 46], + ], + ], + [ + [ + [1936, 261], + [1927, 203], + [1997, 190], + [1929, 81], + [1890, 58], + [1826, 103], + [1806, 154], + [1767, 130], + [1740, 175], + [1879, 250], + [1936, 261], + ], + ], + [ + [ + [2150, 269], + [2183, 239], + [2186, 195], + [2124, 231], + [2082, 238], + [2083, 271], + [2150, 269], + ], + ], + [ + [ + [-240, -615], + [-227, -613], + [-212, -627], + [-226, -637], + [-240, -615], + ], + ], + [ + [ + [1743, 1010], + [1741, 1016], + [1746, 1022], + [1751, 1009], + [1743, 1010], + ], + ], + [ + [ + [-212, -550], + [-280, -577], + [-390, -461], + [-390, -378], + [-423, -351], + [-410, -302], + [-426, -252], + [-503, -171], + [-621, -134], + [-621, -20], + [-559, 40], + [-533, 84], + [-473, 83], + [-444, 129], + [-481, 131], + [-520, 224], + [-479, 302], + [-423, 324], + [-393, 365], + [-430, 404], + [-449, 478], + [-438, 511], + [-476, 588], + [-361, 562], + [-304, 645], + [-328, 703], + [-262, 740], + [-270, 768], + [-238, 881], + [-249, 936], + [-220, 941], + [-168, 993], + [-134, 993], + [-54, 1057], + [-122, 1124], + [-107, 1176], + [-226, 1223], + [-257, 1193], + [-338, 1204], + [-354, 1228], + [-457, 1228], + [-463, 1252], + [-423, 1288], + [-441, 1327], + [-534, 1320], + [-566, 1304], + [-596, 1288], + [-587, 1350], + [-515, 1391], + [-569, 1392], + [-513, 1429], + [-557, 1437], + [-523, 1496], + [-578, 1477], + [-586, 1499], + [-540, 1545], + [-582, 1564], + [-574, 1593], + [-606, 1604], + [-593, 1640], + [-553, 1673], + [-514, 1671], + [-482, 1695], + [-455, 1674], + [-372, 1686], + [-356, 1731], + [-254, 1763], + [-154, 1714], + [-134, 1675], + [75, 1634], + [238, 1587], + [284, 1556], + [443, 1491], + [623, 1495], + [629, 1468], + [712, 1434], + [786, 1445], + [860, 1392], + [909, 1376], + [984, 1392], + [989, 1363], + [1059, 1338], + [1034, 1294], + [1135, 1241], + [1182, 1231], + [1213, 1182], + [1270, 1188], + [1324, 1134], + [1370, 1139], + [1390, 1120], + [1470, 1114], + [1478, 1158], + [1615, 1104], + [1634, 1067], + [1645, 1016], + [1691, 1033], + [1760, 981], + [1811, 998], + [1848, 968], + [1953, 995], + [2005, 979], + [2032, 944], + [1994, 929], + [1984, 895], + [2004, 842], + [1931, 775], + [1785, 717], + [1727, 667], + [1609, 655], + [1483, 627], + [1414, 570], + [1439, 525], + [1381, 514], + [1313, 426], + [1239, 361], + [1131, 223], + [1138, 92], + [1175, 24], + [1224, -23], + [1143, -71], + [1081, -84], + [1038, -115], + [959, -245], + [961, -319], + [864, -330], + [834, -311], + [724, -358], + [683, -399], + [650, -471], + [586, -524], + [536, -485], + [484, -484], + [458, -514], + [327, -472], + [280, -482], + [239, -459], + [132, -437], + [41, -430], + [12, -464], + [-40, -480], + [-81, -467], + [-154, -480], + [-207, -551], + [-212, -550], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'IT', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.44, + 'hc-middle-y': 0.38, + 'hc-key': 'it', + 'hc-a2': 'IT', + name: 'Italy', + labelrank: '2', + 'country-abbrev': 'Italy', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'ITA', + 'iso-a2': 'IT', + 'woe-id': '23424853', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [3951, -735], + [3968, -746], + [3964, -760], + [3941, -747], + [3951, -735], + ], + ], + [ + [ + [4632, -225], + [4627, -220], + [4615, -212], + [4628, -199], + [4632, -225], + ], + ], + [[[3101, -59], [3124, -77], [3111, -105], [3098, -75], [3101, -59]]], + [[[3088, -62], [3076, -61], [3070, -47], [3089, -36], [3088, -62]]], + [[[4361, 430], [4336, 430], [4339, 444], [4362, 437], [4361, 430]]], + [[[3108, 525], [3108, 513], [3089, 508], [3096, 526], [3108, 525]]], + [ + [ + [3570, 1021], + [3559, 994], + [3500, 1004], + [3511, 1022], + [3570, 1021], + ], + ], + [ + [ + [4232, 1848], + [4234, 1880], + [4197, 1904], + [4172, 1883], + [4130, 1896], + [4104, 1856], + [3969, 1791], + [3987, 1831], + [3941, 1798], + [3929, 1753], + [3956, 1693], + [3999, 1657], + [3982, 1613], + [3951, 1618], + [3952, 1515], + [3972, 1447], + [4046, 1372], + [4097, 1349], + [4164, 1295], + [4243, 1249], + [4295, 1134], + [4324, 1039], + [4355, 983], + [4508, 842], + [4595, 804], + [4666, 801], + [4791, 822], + [4831, 780], + [4776, 731], + [4777, 691], + [4803, 671], + [4934, 618], + [5040, 591], + [5140, 527], + [5263, 487], + [5321, 437], + [5395, 344], + [5373, 247], + [5302, 273], + [5278, 332], + [5239, 378], + [5164, 374], + [5094, 397], + [5054, 427], + [5026, 402], + [4967, 290], + [4976, 256], + [4949, 206], + [4957, 172], + [5012, 157], + [5111, 103], + [5111, 19], + [5133, -6], + [5113, -47], + [5052, -47], + [4988, -111], + [5003, -197], + [4918, -289], + [4904, -348], + [4805, -351], + [4795, -270], + [4825, -257], + [4848, -197], + [4830, -143], + [4905, -111], + [4910, -66], + [4874, -17], + [4845, 89], + [4813, 123], + [4787, 211], + [4743, 268], + [4685, 243], + [4632, 288], + [4582, 305], + [4599, 352], + [4538, 431], + [4446, 398], + [4475, 442], + [4433, 472], + [4389, 467], + [4300, 585], + [4268, 571], + [4211, 594], + [4151, 571], + [4115, 620], + [4058, 632], + [4015, 684], + [3968, 713], + [3946, 762], + [3876, 798], + [3837, 869], + [3780, 903], + [3714, 902], + [3734, 937], + [3690, 992], + [3634, 1019], + [3644, 1045], + [3589, 1053], + [3594, 1118], + [3570, 1188], + [3547, 1214], + [3533, 1311], + [3500, 1371], + [3440, 1384], + [3317, 1469], + [3212, 1491], + [3157, 1458], + [3107, 1400], + [3093, 1358], + [3048, 1329], + [2951, 1315], + [2947, 1336], + [2994, 1398], + [2987, 1425], + [2929, 1412], + [2858, 1449], + [2825, 1488], + [2823, 1539], + [2868, 1577], + [2845, 1630], + [2803, 1651], + [2780, 1703], + [2830, 1708], + [2885, 1743], + [2898, 1787], + [2863, 1817], + [2860, 1855], + [2827, 1879], + [2830, 1910], + [2876, 1937], + [2908, 1923], + [2981, 1950], + [3039, 1928], + [3097, 1988], + [3091, 2025], + [3166, 2075], + [3162, 2022], + [3196, 1984], + [3243, 1967], + [3255, 1898], + [3287, 1913], + [3272, 1939], + [3331, 2036], + [3330, 2087], + [3365, 2089], + [3389, 2031], + [3470, 2049], + [3486, 2010], + [3509, 2022], + [3486, 2071], + [3495, 2121], + [3562, 2101], + [3551, 2141], + [3567, 2197], + [3676, 2170], + [3694, 2212], + [3737, 2234], + [3823, 2232], + [3913, 2265], + [3895, 2240], + [3956, 2154], + [4122, 2120], + [4216, 2116], + [4152, 2046], + [4209, 2017], + [4176, 1965], + [4209, 1955], + [4203, 1909], + [4269, 1861], + [4232, 1848], + ], + [ + [3995, 1344], + [3998, 1370], + [3986, 1365], + [3979, 1352], + [3995, 1344], + ], + [[4013, 764], [4013, 764], [4013, 764], [4013, 764], [4013, 764]], + ], + [ + [ + [4478, -359], + [4561, -334], + [4623, -299], + [4666, -313], + [4761, -256], + [4763, -319], + [4702, -424], + [4681, -501], + [4688, -552], + [4748, -640], + [4712, -662], + [4694, -749], + [4551, -718], + [4496, -647], + [4450, -628], + [4404, -635], + [4296, -582], + [4228, -529], + [4153, -506], + [4105, -511], + [4048, -440], + [4064, -380], + [4122, -328], + [4157, -371], + [4202, -322], + [4252, -310], + [4270, -344], + [4366, -378], + [4418, -353], + [4478, -359], + ], + ], + [ + [ + [3266, -34], + [3251, -99], + [3213, -132], + [3155, -125], + [3146, -78], + [3104, -26], + [3106, 18], + [3148, 164], + [3115, 173], + [3137, 231], + [3132, 293], + [3100, 371], + [3066, 368], + [3061, 416], + [3084, 469], + [3148, 443], + [3203, 467], + [3307, 568], + [3353, 545], + [3381, 525], + [3369, 495], + [3439, 349], + [3393, 274], + [3417, 221], + [3396, 45], + [3376, -56], + [3315, -32], + [3266, -34], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'SM', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.68, + 'hc-middle-y': 0.41, + 'hc-key': 'sm', + 'hc-a2': 'SM', + name: 'San Marino', + labelrank: '6', + 'country-abbrev': 'S.M.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'SMR', + 'iso-a2': 'SM', + 'woe-id': '23424947', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [3995, 1344], + [3979, 1352], + [3986, 1365], + [3998, 1370], + [3995, 1344], + ], + ], + }, + }, + { + type: 'Feature', + id: 'VA', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.62, + 'hc-middle-y': 0.44, + 'hc-key': 'va', + 'hc-a2': 'VA', + name: 'Vatican', + labelrank: '6', + 'country-abbrev': 'Vat.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'VAT', + 'iso-a2': 'VA', + 'woe-id': '23424986', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [[4013, 764], [4013, 764], [4013, 764], [4013, 764], [4013, 764]], + ], + }, + }, + { + type: 'Feature', + id: 'TR', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.62, + 'hc-middle-y': 0.51, + 'hc-key': 'tr', + 'hc-a2': 'TR', + name: 'Turkey', + labelrank: '2', + 'country-abbrev': 'Tur.', + subregion: 'Western Asia', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'TUR', + 'iso-a2': 'TR', + 'woe-id': '23424969', + continent: 'Asia', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [[[7048, 641], [7008, 614], [6984, 617], [7031, 663], [7048, 641]]], + [[[7377, 872], [7400, 872], [7378, 846], [7356, 860], [7377, 872]]], + [ + [ + [7026, 1104], + [7060, 1145], + [7058, 1175], + [7136, 1215], + [7149, 1241], + [7200, 1259], + [7271, 1219], + [7320, 1259], + [7366, 1265], + [7367, 1220], + [7404, 1176], + [7482, 1136], + [7608, 1115], + [7653, 1117], + [7644, 1044], + [7562, 1015], + [7478, 1025], + [7426, 979], + [7331, 959], + [7321, 909], + [7281, 839], + [7186, 763], + [7178, 732], + [7097, 621], + [7110, 666], + [7091, 700], + [7208, 812], + [7195, 827], + [7137, 795], + [7043, 777], + [7028, 811], + [7081, 892], + [7056, 973], + [7113, 1024], + [7089, 1088], + [7026, 1104], + ], + ], + [ + [ + [9732, 429], + [9709, 427], + [9717, 324], + [9732, 308], + [9732, 245], + [9709, 236], + [9731, 170], + [9699, 144], + [9700, 102], + [9638, 110], + [9642, 143], + [9568, 212], + [9628, 325], + [9607, 380], + [9556, 400], + [9498, 327], + [9502, 279], + [9445, 237], + [9287, 266], + [9243, 235], + [9170, 98], + [9163, 32], + [9133, 54], + [9107, -9], + [8982, -55], + [8915, -110], + [8801, -100], + [8689, -21], + [8509, 5], + [8352, -16], + [8335, -55], + [8356, -128], + [8340, -219], + [8301, -212], + [8181, -304], + [8158, -284], + [8099, -292], + [8040, -273], + [8000, -223], + [8004, -185], + [7961, -170], + [7948, -209], + [7892, -205], + [7879, -172], + [7800, -182], + [7811, -212], + [7781, -263], + [7741, -246], + [7754, -221], + [7682, -240], + [7674, -274], + [7600, -284], + [7653, -235], + [7752, -207], + [7737, -175], + [7792, -123], + [7626, -189], + [7594, -180], + [7558, -209], + [7560, -159], + [7597, -159], + [7617, -99], + [7583, -114], + [7568, -76], + [7518, -98], + [7500, -29], + [7450, -20], + [7499, 16], + [7480, 85], + [7391, 80], + [7355, 125], + [7323, 84], + [7232, 113], + [7280, 153], + [7234, 219], + [7268, 237], + [7305, 205], + [7329, 146], + [7417, 196], + [7380, 197], + [7311, 268], + [7348, 280], + [7369, 348], + [7329, 331], + [7324, 377], + [7249, 421], + [7305, 498], + [7291, 525], + [7117, 451], + [7123, 498], + [7103, 589], + [7133, 619], + [7143, 674], + [7201, 751], + [7262, 762], + [7321, 796], + [7363, 765], + [7436, 783], + [7400, 829], + [7479, 841], + [7456, 812], + [7644, 862], + [7687, 862], + [7724, 893], + [7635, 896], + [7672, 943], + [7792, 990], + [7866, 1032], + [7743, 998], + [7655, 1041], + [7651, 1092], + [7679, 1126], + [7825, 1139], + [7879, 1153], + [7902, 1180], + [8032, 1178], + [8116, 1207], + [8142, 1249], + [8133, 1281], + [8262, 1408], + [8278, 1451], + [8340, 1507], + [8402, 1540], + [8471, 1606], + [8686, 1658], + [8761, 1684], + [8797, 1744], + [8844, 1737], + [8842, 1713], + [8888, 1673], + [8964, 1661], + [9041, 1721], + [9086, 1704], + [9106, 1660], + [9194, 1625], + [9215, 1675], + [9298, 1682], + [9322, 1656], + [9449, 1661], + [9460, 1698], + [9520, 1672], + [9616, 1692], + [9691, 1735], + [9724, 1777], + [9732, 1781], + [9732, 429], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'MT', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.67, + 'hc-middle-y': 0.77, + 'hc-key': 'mt', + 'hc-a2': 'MT', + name: 'Malta', + labelrank: '5', + 'country-abbrev': 'Malta', + subregion: 'Southern Europe', + 'region-wb': 'Middle East & North Africa', + 'iso-a3': 'MLT', + 'iso-a2': 'MT', + 'woe-id': '23424897', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [4588, -999], + [4533, -992], + [4526, -965], + [4572, -975], + [4588, -999], + ], + ], + [ + [ + [4514, -952], + [4492, -948], + [4508, -935], + [4528, -946], + [4514, -952], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'FR', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.47, + 'hc-middle-y': 0.47, + 'hc-key': 'fr', + 'hc-a2': 'FR', + name: 'France', + labelrank: '2', + 'country-abbrev': 'Fr.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'FRA', + 'iso-a2': 'FR', + 'woe-id': '-90', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [1209, 2125], + [1227, 2092], + [1216, 2069], + [1190, 2121], + [1209, 2125], + ], + ], + [ + [ + [1184, 2202], + [1214, 2184], + [1223, 2170], + [1167, 2205], + [1184, 2202], + ], + ], + [ + [ + [1077, 2433], + [1065, 2431], + [1059, 2452], + [1077, 2447], + [1077, 2433], + ], + ], + [[[915, 2566], [923, 2556], [890, 2567], [893, 2589], [915, 2566]]], + [ + [ + [2720, 2051], + [2736, 2073], + [2835, 2080], + [2844, 1995], + [2876, 1937], + [2830, 1910], + [2827, 1879], + [2860, 1855], + [2863, 1817], + [2898, 1787], + [2885, 1743], + [2830, 1708], + [2780, 1703], + [2803, 1651], + [2845, 1630], + [2868, 1577], + [2823, 1539], + [2825, 1488], + [2858, 1449], + [2929, 1412], + [2987, 1425], + [2994, 1398], + [2947, 1336], + [2951, 1315], + [2945, 1307], + [2937, 1301], + [2931, 1307], + [2922, 1295], + [2876, 1277], + [2872, 1248], + [2784, 1209], + [2754, 1175], + [2770, 1150], + [2592, 1113], + [2547, 1158], + [2487, 1170], + [2478, 1211], + [2429, 1206], + [2454, 1234], + [2402, 1241], + [2378, 1215], + [2324, 1226], + [2315, 1252], + [2250, 1258], + [2231, 1287], + [2195, 1284], + [2072, 1222], + [2010, 1176], + [1989, 1130], + [1981, 1017], + [2005, 979], + [1953, 995], + [1848, 968], + [1811, 998], + [1760, 981], + [1691, 1033], + [1697, 1064], + [1634, 1067], + [1615, 1104], + [1478, 1158], + [1470, 1114], + [1390, 1120], + [1370, 1139], + [1324, 1134], + [1270, 1188], + [1213, 1182], + [1182, 1231], + [1135, 1241], + [1034, 1294], + [1059, 1338], + [989, 1363], + [984, 1392], + [1013, 1392], + [1059, 1437], + [1169, 1739], + [1152, 1731], + [1216, 1974], + [1230, 1995], + [1284, 1915], + [1291, 1943], + [1214, 2039], + [1247, 2091], + [1256, 2193], + [1130, 2285], + [1126, 2324], + [1083, 2386], + [1119, 2448], + [1091, 2486], + [1101, 2527], + [1073, 2513], + [1026, 2561], + [1060, 2567], + [1044, 2600], + [981, 2603], + [996, 2638], + [936, 2634], + [860, 2708], + [799, 2726], + [788, 2753], + [700, 2747], + [698, 2797], + [656, 2833], + [733, 2829], + [736, 2855], + [696, 2895], + [737, 2918], + [659, 2913], + [664, 2956], + [711, 2987], + [760, 2981], + [828, 2994], + [845, 2960], + [858, 2988], + [901, 2967], + [920, 3008], + [1000, 3002], + [1059, 2885], + [1137, 2923], + [1151, 2890], + [1227, 2916], + [1224, 2890], + [1313, 2887], + [1283, 2917], + [1297, 2997], + [1296, 3054], + [1264, 3110], + [1258, 3206], + [1317, 3176], + [1357, 3187], + [1384, 3157], + [1366, 3140], + [1383, 3100], + [1447, 3071], + [1523, 3053], + [1556, 3030], + [1633, 3059], + [1681, 3063], + [1625, 3083], + [1659, 3147], + [1746, 3178], + [1841, 3190], + [1906, 3248], + [1919, 3273], + [1946, 3441], + [2022, 3473], + [2124, 3485], + [2123, 3485], + [2129, 3413], + [2161, 3376], + [2227, 3382], + [2244, 3311], + [2310, 3281], + [2310, 3245], + [2377, 3244], + [2408, 3217], + [2390, 3138], + [2443, 3122], + [2486, 3135], + [2492, 3162], + [2529, 3175], + [2510, 3129], + [2519, 3074], + [2536, 3076], + [2629, 2982], + [2688, 2991], + [2719, 2961], + [2752, 2975], + [2791, 2962], + [2819, 2954], + [2854, 2877], + [2879, 2886], + [2960, 2853], + [2984, 2871], + [3032, 2830], + [3085, 2829], + [3136, 2805], + [3116, 2766], + [3059, 2708], + [3045, 2634], + [3008, 2560], + [3016, 2533], + [2996, 2470], + [3006, 2412], + [2964, 2369], + [2892, 2392], + [2862, 2351], + [2897, 2346], + [2805, 2247], + [2773, 2237], + [2768, 2184], + [2706, 2139], + [2688, 2089], + [2704, 2071], + [2664, 2007], + [2731, 2035], + [2720, 2051], + ], + [ + [1743, 1010], + [1751, 1009], + [1746, 1022], + [1741, 1016], + [1743, 1010], + ], + ], + [ + [ + [3204, 798], + [3163, 857], + [3201, 949], + [3285, 996], + [3325, 981], + [3337, 1073], + [3354, 1080], + [3367, 1026], + [3360, 972], + [3377, 942], + [3380, 816], + [3347, 770], + [3346, 698], + [3306, 600], + [3212, 657], + [3241, 695], + [3192, 706], + [3203, 766], + [3169, 777], + [3204, 798], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'NO', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.43, + 'hc-middle-y': 0.8, + 'hc-key': 'no', + 'hc-a2': 'NO', + name: 'Norway', + labelrank: '3', + 'country-abbrev': 'Nor.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'NOR', + 'iso-a2': 'NO', + 'woe-id': '-90', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [2823, 5756], + [2848, 5748], + [2843, 5737], + [2818, 5753], + [2823, 5756], + ], + ], + [ + [ + [2800, 5766], + [2790, 5779], + [2796, 5789], + [2803, 5778], + [2800, 5766], + ], + ], + [ + [ + [2884, 5781], + [2873, 5785], + [2877, 5796], + [2899, 5793], + [2884, 5781], + ], + ], + [ + [ + [2777, 5805], + [2777, 5769], + [2759, 5778], + [2769, 5841], + [2777, 5805], + ], + ], + [ + [ + [2778, 5961], + [2792, 5938], + [2757, 5944], + [2763, 5974], + [2778, 5961], + ], + ], + [ + [ + [2819, 5951], + [2791, 5950], + [2785, 5984], + [2810, 5991], + [2819, 5951], + ], + ], + [ + [ + [2847, 6026], + [2842, 5982], + [2822, 5979], + [2818, 6024], + [2847, 6026], + ], + ], + [ + [ + [2789, 6032], + [2789, 6009], + [2776, 6024], + [2782, 6042], + [2789, 6032], + ], + ], + [ + [ + [2770, 6105], + [2770, 6070], + [2748, 6098], + [2755, 6142], + [2770, 6105], + ], + ], + [ + [ + [2764, 6164], + [2782, 6157], + [2786, 6132], + [2759, 6160], + [2764, 6164], + ], + ], + [ + [ + [2744, 6285], + [2757, 6268], + [2750, 6265], + [2737, 6285], + [2744, 6285], + ], + ], + [ + [ + [2734, 6314], + [2729, 6303], + [2722, 6324], + [2730, 6330], + [2734, 6314], + ], + ], + [ + [ + [2758, 6346], + [2771, 6338], + [2743, 6323], + [2745, 6350], + [2758, 6346], + ], + ], + [ + [ + [2782, 6565], + [2805, 6551], + [2775, 6531], + [2760, 6550], + [2782, 6565], + ], + ], + [ + [ + [2800, 6596], + [2811, 6592], + [2802, 6572], + [2789, 6604], + [2800, 6596], + ], + ], + [ + [ + [2893, 6675], + [2901, 6648], + [2869, 6646], + [2873, 6674], + [2893, 6675], + ], + ], + [ + [ + [2880, 6686], + [2899, 6693], + [2896, 6683], + [2868, 6687], + [2880, 6686], + ], + ], + [ + [ + [2943, 6687], + [2915, 6661], + [2907, 6693], + [2927, 6711], + [2943, 6687], + ], + ], + [ + [ + [2964, 6713], + [2978, 6701], + [2947, 6703], + [2938, 6713], + [2964, 6713], + ], + ], + [ + [ + [3061, 6794], + [3062, 6784], + [3029, 6773], + [3032, 6794], + [3061, 6794], + ], + ], + [ + [ + [3050, 6830], + [3065, 6830], + [3059, 6806], + [3046, 6817], + [3050, 6830], + ], + ], + [ + [ + [3200, 6891], + [3183, 6874], + [3169, 6884], + [3176, 6896], + [3200, 6891], + ], + ], + [ + [ + [3168, 6874], + [3147, 6853], + [3131, 6886], + [3153, 6875], + [3168, 6874], + ], + ], + [ + [ + [3253, 6915], + [3238, 6915], + [3235, 6931], + [3244, 6931], + [3253, 6915], + ], + ], + [ + [ + [3237, 6913], + [3214, 6907], + [3203, 6920], + [3223, 6938], + [3237, 6913], + ], + ], + [ + [ + [3227, 6967], + [3188, 6977], + [3215, 7006], + [3238, 6981], + [3227, 6967], + ], + ], + [ + [ + [3321, 7101], + [3324, 7076], + [3313, 7067], + [3257, 7062], + [3321, 7101], + ], + ], + [ + [ + [3651, 7346], + [3663, 7333], + [3660, 7319], + [3649, 7325], + [3651, 7346], + ], + ], + [ + [ + [3633, 7339], + [3658, 7299], + [3628, 7308], + [3615, 7351], + [3633, 7339], + ], + ], + [ + [ + [3648, 7351], + [3644, 7336], + [3627, 7357], + [3642, 7363], + [3648, 7351], + ], + ], + [ + [ + [3629, 7427], + [3613, 7424], + [3581, 7411], + [3614, 7439], + [3629, 7427], + ], + ], + [ + [ + [3580, 7414], + [3570, 7409], + [3576, 7431], + [3617, 7446], + [3580, 7414], + ], + ], + [ + [ + [3699, 7488], + [3672, 7467], + [3667, 7471], + [3675, 7487], + [3699, 7488], + ], + ], + [ + [ + [3759, 7501], + [3747, 7473], + [3727, 7478], + [3750, 7520], + [3759, 7501], + ], + ], + [ + [ + [3773, 7608], + [3785, 7573], + [3736, 7520], + [3740, 7562], + [3773, 7608], + ], + ], + [ + [ + [3716, 7662], + [3713, 7631], + [3693, 7638], + [3701, 7661], + [3716, 7662], + ], + ], + [ + [ + [3809, 7748], + [3780, 7719], + [3765, 7722], + [3777, 7749], + [3809, 7748], + ], + ], + [ + [ + [3791, 7809], + [3797, 7789], + [3783, 7773], + [3755, 7758], + [3791, 7809], + ], + ], + [ + [ + [3814, 7846], + [3823, 7829], + [3809, 7822], + [3803, 7832], + [3814, 7846], + ], + ], + [ + [ + [3830, 7885], + [3824, 7862], + [3812, 7870], + [3813, 7887], + [3830, 7885], + ], + ], + [ + [ + [3971, 8096], + [3969, 8064], + [3943, 8083], + [3950, 8101], + [3971, 8096], + ], + ], + [ + [ + [3984, 8190], + [3983, 8182], + [3965, 8175], + [3980, 8195], + [3984, 8190], + ], + ], + [ + [ + [4054, 8360], + [4075, 8347], + [4039, 8341], + [4039, 8358], + [4054, 8360], + ], + ], + [ + [ + [4072, 8359], + [4062, 8358], + [4059, 8367], + [4066, 8380], + [4072, 8359], + ], + ], + [ + [ + [3826, 8372], + [3831, 8341], + [3794, 8296], + [3813, 8365], + [3826, 8372], + ], + ], + [ + [ + [3859, 8374], + [3843, 8351], + [3835, 8373], + [3863, 8394], + [3859, 8374], + ], + ], + [ + [ + [4024, 8439], + [4013, 8439], + [4022, 8456], + [4030, 8450], + [4024, 8439], + ], + ], + [ + [ + [3950, 8456], + [3946, 8436], + [3940, 8449], + [3930, 8460], + [3950, 8456], + ], + ], + [ + [ + [3920, 8440], + [3929, 8414], + [3900, 8406], + [3887, 8379], + [3868, 8396], + [3868, 8430], + [3920, 8440], + ], + ], + [ + [ + [4049, 8500], + [4009, 8443], + [3948, 8407], + [3978, 8458], + [3965, 8474], + [3993, 8493], + [4049, 8500], + ], + ], + [ + [ + [4187, 8508], + [4154, 8495], + [4161, 8532], + [4178, 8540], + [4187, 8508], + ], + ], + [ + [ + [4004, 8514], + [3985, 8532], + [4029, 8533], + [4018, 8515], + [4004, 8514], + ], + ], + [ + [ + [4255, 8614], + [4227, 8601], + [4226, 8616], + [4242, 8644], + [4255, 8614], + ], + ], + [ + [ + [4265, 8646], + [4263, 8664], + [4288, 8650], + [4267, 8626], + [4265, 8646], + ], + ], + [ + [ + [4018, 8630], + [4005, 8632], + [4008, 8645], + [4017, 8645], + [4018, 8630], + ], + ], + [ + [ + [4174, 8672], + [4190, 8672], + [4192, 8647], + [4157, 8669], + [4174, 8672], + ], + ], + [ + [ + [4280, 8687], + [4273, 8700], + [4282, 8716], + [4293, 8708], + [4280, 8687], + ], + ], + [ + [ + [4108, 8681], + [4067, 8660], + [4079, 8704], + [4131, 8772], + [4131, 8720], + [4108, 8681], + ], + ], + [ + [ + [4402, 8972], + [4427, 8934], + [4405, 8912], + [4411, 8885], + [4347, 8859], + [4324, 8875], + [4355, 8879], + [4340, 8913], + [4355, 8940], + [4400, 8943], + [4402, 8972], + ], + ], + [ + [ + [4594, 8976], + [4583, 8973], + [4580, 9002], + [4595, 9008], + [4594, 8976], + ], + ], + [ + [ + [5553, 9194], + [5561, 9190], + [5528, 9163], + [5532, 9212], + [5553, 9194], + ], + ], + [ + [ + [4490, 8977], + [4471, 8969], + [4472, 8994], + [4504, 9015], + [4490, 8977], + ], + ], + [ + [ + [4616, 9050], + [4630, 9045], + [4617, 9023], + [4596, 9036], + [4616, 9050], + ], + ], + [ + [ + [4434, 9036], + [4474, 9017], + [4462, 8968], + [4435, 8949], + [4388, 8992], + [4397, 9014], + [4434, 9036], + ], + ], + [ + [ + [4391, 9028], + [4409, 9033], + [4384, 9003], + [4379, 9041], + [4391, 9028], + ], + ], + [ + [ + [4606, 9062], + [4599, 9059], + [4596, 9083], + [4607, 9071], + [4606, 9062], + ], + ], + [ + [ + [4467, 9047], + [4447, 9050], + [4446, 9063], + [4454, 9064], + [4467, 9047], + ], + ], + [ + [ + [4592, 9071], + [4576, 9048], + [4553, 9062], + [4568, 9105], + [4594, 9096], + [4592, 9071], + ], + ], + [ + [ + [4425, 9091], + [4432, 9055], + [4420, 9048], + [4408, 9057], + [4425, 9091], + ], + ], + [ + [ + [4476, 9096], + [4491, 9074], + [4528, 9061], + [4496, 9041], + [4471, 9086], + [4476, 9096], + ], + ], + [ + [ + [4683, 9132], + [4676, 9137], + [4675, 9169], + [4684, 9161], + [4683, 9132], + ], + ], + [ + [ + [4774, 9185], + [4804, 9172], + [4813, 9150], + [4754, 9152], + [4753, 9181], + [4774, 9185], + ], + ], + [ + [ + [4843, 9269], + [4867, 9228], + [4848, 9178], + [4821, 9162], + [4791, 9208], + [4843, 9269], + ], + ], + [ + [ + [4869, 9303], + [4905, 9283], + [4873, 9246], + [4852, 9298], + [4869, 9303], + ], + ], + [ + [ + [4876, 9399], + [4883, 9370], + [4863, 9379], + [4864, 9402], + [4876, 9399], + ], + ], + [ + [ + [4940, 9438], + [4944, 9418], + [4926, 9424], + [4933, 9441], + [4940, 9438], + ], + ], + [ + [ + [5023, 9477], + [5051, 9449], + [5083, 9441], + [5024, 9405], + [4993, 9434], + [5023, 9477], + ], + ], + [ + [ + [1712, 9534], + [1697, 9493], + [1622, 9482], + [1587, 9453], + [1577, 9474], + [1647, 9502], + [1675, 9535], + [1712, 9534], + ], + ], + [ + [ + [2837, 6137], + [2847, 6128], + [2861, 6143], + [2864, 6225], + [2838, 6190], + [2804, 6173], + [2756, 6246], + [2808, 6216], + [2808, 6249], + [2774, 6257], + [2774, 6317], + [2832, 6307], + [2898, 6331], + [2951, 6306], + [2999, 6341], + [3049, 6311], + [3103, 6327], + [3106, 6341], + [3048, 6320], + [2986, 6367], + [2975, 6324], + [2939, 6346], + [2852, 6338], + [2825, 6323], + [2809, 6354], + [2778, 6366], + [2772, 6425], + [2831, 6461], + [2782, 6487], + [2782, 6518], + [2834, 6545], + [2839, 6563], + [2889, 6540], + [2997, 6528], + [2848, 6572], + [2810, 6563], + [2834, 6599], + [2804, 6641], + [2820, 6655], + [2854, 6608], + [2853, 6645], + [2921, 6644], + [2937, 6675], + [3031, 6713], + [2977, 6718], + [3009, 6739], + [2972, 6738], + [2981, 6761], + [3020, 6745], + [3043, 6771], + [3086, 6769], + [3142, 6735], + [3144, 6774], + [3186, 6789], + [3226, 6784], + [3219, 6802], + [3125, 6778], + [3116, 6795], + [3070, 6791], + [3065, 6852], + [3114, 6874], + [3143, 6843], + [3207, 6860], + [3223, 6899], + [3256, 6854], + [3254, 6831], + [3293, 6829], + [3234, 6900], + [3284, 6904], + [3282, 6916], + [3268, 6913], + [3248, 6934], + [3277, 6938], + [3279, 6933], + [3276, 6952], + [3314, 6967], + [3323, 6991], + [3380, 6970], + [3367, 7013], + [3438, 7053], + [3472, 6989], + [3455, 6960], + [3491, 6959], + [3490, 6992], + [3517, 7000], + [3583, 6986], + [3598, 7001], + [3566, 7025], + [3612, 7076], + [3668, 7101], + [3620, 7126], + [3671, 7165], + [3640, 7169], + [3602, 7143], + [3617, 7110], + [3596, 7079], + [3532, 7034], + [3467, 7015], + [3451, 7067], + [3481, 7094], + [3418, 7059], + [3418, 7091], + [3503, 7139], + [3469, 7145], + [3499, 7216], + [3555, 7265], + [3555, 7291], + [3591, 7298], + [3599, 7336], + [3626, 7290], + [3653, 7276], + [3670, 7328], + [3654, 7368], + [3710, 7397], + [3684, 7402], + [3717, 7441], + [3664, 7398], + [3633, 7401], + [3653, 7431], + [3707, 7452], + [3725, 7476], + [3747, 7468], + [3802, 7496], + [3840, 7559], + [3789, 7501], + [3768, 7537], + [3803, 7582], + [3793, 7633], + [3773, 7616], + [3765, 7646], + [3815, 7745], + [3843, 7777], + [3805, 7768], + [3823, 7796], + [3901, 7831], + [3954, 7833], + [3906, 7846], + [3842, 7816], + [3875, 7848], + [3836, 7863], + [3856, 7880], + [3862, 7946], + [3889, 7960], + [3894, 7999], + [3925, 8002], + [3898, 8039], + [3971, 8056], + [3984, 8110], + [4032, 8130], + [4047, 8109], + [4068, 8132], + [4100, 8120], + [4110, 8135], + [4064, 8142], + [4074, 8162], + [4019, 8130], + [4019, 8148], + [3979, 8135], + [4013, 8192], + [4034, 8179], + [4058, 8201], + [4020, 8211], + [4051, 8236], + [4106, 8209], + [4149, 8246], + [4108, 8224], + [4081, 8226], + [4071, 8262], + [4114, 8296], + [4088, 8311], + [4030, 8258], + [4023, 8284], + [4048, 8291], + [4021, 8312], + [4043, 8335], + [4077, 8336], + [4131, 8359], + [4149, 8378], + [4143, 8378], + [4136, 8369], + [4120, 8376], + [4106, 8379], + [4072, 8380], + [4095, 8411], + [4142, 8414], + [4143, 8449], + [4160, 8428], + [4157, 8385], + [4183, 8343], + [4187, 8376], + [4208, 8350], + [4209, 8385], + [4190, 8403], + [4197, 8447], + [4164, 8472], + [4214, 8458], + [4169, 8483], + [4220, 8504], + [4236, 8481], + [4313, 8520], + [4310, 8551], + [4258, 8516], + [4201, 8512], + [4206, 8574], + [4269, 8615], + [4315, 8661], + [4285, 8660], + [4307, 8721], + [4347, 8749], + [4335, 8783], + [4360, 8847], + [4398, 8795], + [4432, 8809], + [4379, 8837], + [4379, 8860], + [4415, 8874], + [4438, 8829], + [4476, 8818], + [4476, 8781], + [4494, 8783], + [4475, 8829], + [4454, 8825], + [4426, 8878], + [4434, 8933], + [4453, 8950], + [4503, 8963], + [4497, 8924], + [4518, 8910], + [4514, 8952], + [4528, 8955], + [4537, 9010], + [4565, 8998], + [4562, 8851], + [4539, 8804], + [4572, 8846], + [4587, 8905], + [4581, 8963], + [4644, 9005], + [4660, 9055], + [4723, 9003], + [4718, 9051], + [4704, 9071], + [4669, 9076], + [4632, 9106], + [4666, 9144], + [4703, 9099], + [4692, 9135], + [4736, 9150], + [4749, 9138], + [4812, 9136], + [4828, 9084], + [4863, 9066], + [4880, 9092], + [4839, 9106], + [4860, 9124], + [4842, 9148], + [4868, 9173], + [4858, 9194], + [4891, 9245], + [4932, 9245], + [4908, 9261], + [4923, 9308], + [4953, 9294], + [4939, 9329], + [4913, 9329], + [4917, 9362], + [4944, 9340], + [4936, 9401], + [4987, 9394], + [5005, 9357], + [5018, 9381], + [5061, 9402], + [5068, 9391], + [5007, 9267], + [5022, 9278], + [5032, 9211], + [5015, 9183], + [5022, 9138], + [5040, 9142], + [5067, 9216], + [5053, 9221], + [5092, 9324], + [5092, 9351], + [5111, 9405], + [5136, 9438], + [5151, 9400], + [5149, 9363], + [5123, 9338], + [5155, 9343], + [5159, 9257], + [5203, 9350], + [5195, 9385], + [5226, 9426], + [5181, 9438], + [5201, 9450], + [5186, 9473], + [5220, 9459], + [5211, 9501], + [5245, 9491], + [5272, 9513], + [5278, 9486], + [5314, 9491], + [5314, 9454], + [5298, 9425], + [5252, 9415], + [5293, 9408], + [5255, 9357], + [5312, 9402], + [5312, 9374], + [5284, 9325], + [5323, 9308], + [5342, 9231], + [5329, 9315], + [5333, 9413], + [5347, 9465], + [5372, 9475], + [5414, 9455], + [5416, 9427], + [5455, 9448], + [5454, 9414], + [5477, 9450], + [5582, 9386], + [5590, 9401], + [5620, 9356], + [5571, 9330], + [5547, 9266], + [5450, 9255], + [5399, 9256], + [5388, 9238], + [5508, 9223], + [5489, 9196], + [5519, 9206], + [5527, 9154], + [5560, 9161], + [5576, 9184], + [5564, 9210], + [5601, 9202], + [5638, 9209], + [5659, 9172], + [5664, 9128], + [5628, 9120], + [5599, 9138], + [5597, 9081], + [5581, 9050], + [5529, 9010], + [5532, 8960], + [5509, 8926], + [5490, 8946], + [5485, 8979], + [5515, 9065], + [5476, 9121], + [5392, 9139], + [5361, 9160], + [5320, 9205], + [5290, 9182], + [5252, 9135], + [5225, 9140], + [5190, 9125], + [5173, 9058], + [5157, 9048], + [5153, 8993], + [5162, 8948], + [5159, 8892], + [5178, 8840], + [5171, 8799], + [5127, 8767], + [5129, 8714], + [5106, 8686], + [5079, 8712], + [5041, 8717], + [4991, 8740], + [4976, 8706], + [4923, 8666], + [4900, 8683], + [4835, 8679], + [4823, 8711], + [4776, 8761], + [4725, 8830], + [4687, 8832], + [4662, 8795], + [4680, 8769], + [4669, 8753], + [4635, 8767], + [4625, 8745], + [4570, 8732], + [4600, 8702], + [4600, 8626], + [4575, 8586], + [4608, 8572], + [4579, 8529], + [4475, 8562], + [4432, 8556], + [4406, 8575], + [4379, 8560], + [4391, 8447], + [4367, 8387], + [4298, 8421], + [4246, 8357], + [4219, 8248], + [4188, 8230], + [4182, 8204], + [4224, 8141], + [4225, 8096], + [4186, 8043], + [4149, 7954], + [4123, 7920], + [4134, 7856], + [4086, 7816], + [4024, 7804], + [4042, 7721], + [4035, 7678], + [4036, 7564], + [4015, 7494], + [3940, 7341], + [4002, 7302], + [4012, 7233], + [3986, 7174], + [3894, 7193], + [3825, 7151], + [3762, 7043], + [3767, 7001], + [3741, 6952], + [3774, 6868], + [3759, 6845], + [3767, 6790], + [3760, 6746], + [3794, 6644], + [3777, 6495], + [3814, 6454], + [3841, 6445], + [3880, 6395], + [3857, 6297], + [3797, 6278], + [3816, 6212], + [3850, 6144], + [3836, 6080], + [3842, 6028], + [3790, 5963], + [3748, 5954], + [3756, 5924], + [3725, 5862], + [3747, 5773], + [3727, 5677], + [3695, 5669], + [3693, 5697], + [3682, 5728], + [3612, 5755], + [3600, 5745], + [3566, 5820], + [3574, 5870], + [3560, 5908], + [3573, 5946], + [3555, 5954], + [3549, 5910], + [3565, 5863], + [3549, 5847], + [3547, 5769], + [3531, 5776], + [3524, 5734], + [3471, 5685], + [3431, 5685], + [3368, 5649], + [3395, 5649], + [3249, 5484], + [3226, 5481], + [3190, 5441], + [3177, 5477], + [3158, 5436], + [3106, 5419], + [3017, 5426], + [2946, 5455], + [2973, 5484], + [2870, 5537], + [2865, 5560], + [2827, 5578], + [2797, 5647], + [2813, 5729], + [2839, 5695], + [2883, 5686], + [2862, 5740], + [2921, 5792], + [2897, 5830], + [2835, 5805], + [2825, 5838], + [2806, 5799], + [2767, 5869], + [2816, 5932], + [2853, 5912], + [2876, 5935], + [2841, 5964], + [2890, 5991], + [2919, 6065], + [2984, 6134], + [2928, 6105], + [2878, 6052], + [2875, 6012], + [2850, 6018], + [2855, 6053], + [2837, 6076], + [2815, 6056], + [2787, 6072], + [2784, 6124], + [2805, 6163], + [2820, 6150], + [2808, 6168], + [2862, 6203], + [2857, 6144], + [2837, 6137], + ], + ], + [ + [ + [3351, 7049], + [3352, 7056], + [3362, 7056], + [3368, 7050], + [3353, 7046], + [3369, 7031], + [3280, 6993], + [3251, 7003], + [3287, 7042], + [3342, 7057], + [3351, 7049], + ], + ], + [ + [ + [4021, 8662], + [4042, 8649], + [4054, 8642], + [4064, 8566], + [4036, 8541], + [4007, 8557], + [4044, 8579], + [4041, 8595], + [3986, 8552], + [3957, 8569], + [3990, 8595], + [4025, 8605], + [4021, 8662], + ], + ], + [ + [ + [4773, 9266], + [4803, 9297], + [4786, 9313], + [4816, 9315], + [4819, 9336], + [4816, 9285], + [4784, 9234], + [4713, 9205], + [4726, 9247], + [4694, 9238], + [4726, 9274], + [4773, 9266], + ], + ], + [ + [ + [4199, 8593], + [4192, 8544], + [4150, 8536], + [4140, 8493], + [4115, 8501], + [4104, 8462], + [4073, 8476], + [4050, 8462], + [4035, 8461], + [4061, 8507], + [4055, 8538], + [4084, 8562], + [4073, 8614], + [4091, 8659], + [4119, 8663], + [4119, 8609], + [4133, 8605], + [4118, 8557], + [4146, 8599], + [4158, 8649], + [4180, 8635], + [4199, 8593], + ], + ], + [ + [ + [4220, 8743], + [4241, 8781], + [4218, 8805], + [4266, 8805], + [4276, 8820], + [4250, 8833], + [4254, 8851], + [4291, 8832], + [4307, 8874], + [4333, 8847], + [4341, 8804], + [4323, 8792], + [4334, 8751], + [4284, 8737], + [4215, 8700], + [4238, 8726], + [4220, 8743], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'DE', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.47, + 'hc-middle-y': 0.53, + 'hc-key': 'de', + 'hc-a2': 'DE', + name: 'Germany', + labelrank: '2', + 'country-abbrev': 'Ger.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'DEU', + 'iso-a2': 'DE', + 'woe-id': '23424829', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [3422, 2394], + [3345, 2433], + [3297, 2473], + [3318, 2430], + [3264, 2425], + [3205, 2468], + [3164, 2431], + [3174, 2408], + [3006, 2412], + [2996, 2470], + [3016, 2533], + [3008, 2560], + [3045, 2634], + [3059, 2708], + [3116, 2766], + [3136, 2805], + [3085, 2829], + [3032, 2830], + [2984, 2871], + [2960, 2853], + [2879, 2886], + [2854, 2877], + [2819, 2954], + [2791, 2962], + [2825, 3058], + [2774, 3087], + [2759, 3155], + [2765, 3182], + [2809, 3209], + [2804, 3257], + [2779, 3261], + [2778, 3297], + [2746, 3338], + [2761, 3382], + [2737, 3419], + [2780, 3452], + [2766, 3475], + [2794, 3519], + [2779, 3594], + [2751, 3642], + [2788, 3666], + [2832, 3644], + [2910, 3678], + [2887, 3701], + [2952, 3754], + [2945, 3818], + [2897, 3827], + [2912, 3874], + [2959, 3874], + [2969, 3933], + [2988, 3965], + [2993, 4045], + [3013, 4070], + [2965, 4084], + [2978, 4144], + [3003, 4166], + [3128, 4178], + [3163, 4128], + [3144, 4114], + [3169, 4087], + [3189, 4115], + [3179, 4143], + [3231, 4125], + [3218, 4165], + [3235, 4214], + [3283, 4206], + [3343, 4213], + [3309, 4223], + [3280, 4265], + [3282, 4328], + [3250, 4334], + [3247, 4367], + [3286, 4374], + [3312, 4400], + [3259, 4467], + [3255, 4513], + [3282, 4516], + [3384, 4487], + [3384, 4487], + [3408, 4503], + [3483, 4447], + [3481, 4410], + [3608, 4345], + [3659, 4353], + [3658, 4307], + [3605, 4266], + [3628, 4244], + [3677, 4260], + [3725, 4229], + [3731, 4256], + [3770, 4302], + [3833, 4308], + [3872, 4347], + [3897, 4397], + [3961, 4368], + [3987, 4389], + [4002, 4345], + [4064, 4296], + [4103, 4313], + [4119, 4289], + [4122, 4320], + [4193, 4256], + [4187, 4247], + [4192, 4239], + [4137, 4226], + [4146, 4291], + [4124, 4280], + [4141, 4255], + [4127, 4235], + [4157, 4207], + [4206, 4188], + [4238, 4067], + [4231, 4002], + [4198, 3974], + [4196, 3943], + [4292, 3870], + [4276, 3824], + [4307, 3777], + [4322, 3727], + [4295, 3647], + [4322, 3611], + [4327, 3566], + [4367, 3549], + [4385, 3489], + [4354, 3378], + [4318, 3372], + [4293, 3419], + [4256, 3423], + [4269, 3379], + [4136, 3323], + [4109, 3288], + [4070, 3282], + [4030, 3255], + [3940, 3221], + [3900, 3155], + [3860, 3197], + [3894, 3121], + [3947, 3082], + [3923, 3034], + [4004, 2918], + [4043, 2910], + [4079, 2860], + [4139, 2811], + [4163, 2815], + [4205, 2765], + [4189, 2693], + [4151, 2710], + [4132, 2649], + [4062, 2613], + [4008, 2569], + [4059, 2492], + [4041, 2456], + [4066, 2454], + [4072, 2390], + [4021, 2406], + [4016, 2438], + [3965, 2426], + [3902, 2446], + [3900, 2416], + [3794, 2409], + [3724, 2353], + [3670, 2350], + [3632, 2385], + [3558, 2401], + [3566, 2362], + [3538, 2323], + [3467, 2387], + [3422, 2394], + ], + [ + [3343, 4213], + [3357, 4210], + [3357, 4210], + [3357, 4210], + [3357, 4210], + [3403, 4138], + [3374, 4205], + [3357, 4210], + [3357, 4210], + [3357, 4210], + [3357, 4210], + [3354, 4215], + [3343, 4213], + ], + ], + [ + [ + [3731, 4262], + [3727, 4247], + [3711, 4250], + [3726, 4265], + [3731, 4262], + ], + ], + [ + [ + [3291, 4389], + [3278, 4399], + [3284, 4404], + [3304, 4405], + [3291, 4389], + ], + ], + [ + [ + [3688, 4393], + [3698, 4374], + [3646, 4389], + [3665, 4409], + [3688, 4393], + ], + ], + [ + [ + [4044, 4454], + [4086, 4437], + [4077, 4404], + [4111, 4369], + [4066, 4367], + [4028, 4339], + [4002, 4362], + [4024, 4377], + [4008, 4423], + [4044, 4454], + ], + ], + [ + [ + [3239, 4455], + [3210, 4462], + [3221, 4473], + [3236, 4473], + [3239, 4455], + ], + ], + [ + [ + [3210, 4514], + [3193, 4513], + [3208, 4554], + [3204, 4535], + [3210, 4514], + ], + ], + [[[3319, 2429], [3321, 2426], [3321, 2426], [3319, 2429]]], + ], + }, + }, + { + type: 'Feature', + id: 'IE', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.61, + 'hc-middle-y': 0.6, + 'hc-key': 'ie', + 'hc-a2': 'IE', + name: 'Ireland', + labelrank: '3', + 'country-abbrev': 'Ire.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'IRL', + 'iso-a2': 'IE', + 'woe-id': '23424803', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [[[135, 4725], [124, 4687], [114, 4713], [82, 4730], [135, 4725]]], + [ + [ + [746, 4592], + [766, 4559], + [727, 4568], + [735, 4525], + [725, 4463], + [742, 4439], + [725, 4388], + [719, 4263], + [663, 4188], + [656, 4154], + [613, 4108], + [605, 4057], + [529, 4093], + [512, 4071], + [418, 4086], + [382, 4055], + [338, 4055], + [299, 4028], + [255, 4032], + [161, 3989], + [135, 4002], + [56, 3997], + [36, 4014], + [-44, 4006], + [16, 4039], + [29, 4070], + [-68, 4058], + [-72, 4082], + [1, 4110], + [-65, 4105], + [-114, 4157], + [-78, 4178], + [-14, 4185], + [-5, 4200], + [-102, 4220], + [-96, 4241], + [-38, 4256], + [9, 4227], + [26, 4264], + [10, 4280], + [61, 4287], + [79, 4310], + [137, 4294], + [196, 4300], + [197, 4332], + [162, 4301], + [95, 4324], + [45, 4325], + [112, 4353], + [151, 4397], + [130, 4404], + [181, 4452], + [237, 4436], + [245, 4471], + [130, 4499], + [143, 4528], + [92, 4528], + [114, 4544], + [74, 4553], + [62, 4608], + [121, 4610], + [123, 4652], + [182, 4646], + [190, 4674], + [130, 4679], + [153, 4697], + [142, 4783], + [178, 4806], + [276, 4765], + [279, 4723], + [304, 4760], + [397, 4731], + [372, 4762], + [448, 4791], + [481, 4819], + [390, 4835], + [376, 4862], + [424, 4888], + [462, 4881], + [447, 4915], + [493, 4969], + [574, 4962], + [602, 4975], + [614, 4903], + [622, 4975], + [655, 4972], + [651, 4996], + [711, 4932], + [652, 4902], + [622, 4890], + [581, 4822], + [532, 4831], + [538, 4795], + [459, 4770], + [496, 4684], + [576, 4637], + [639, 4710], + [662, 4684], + [668, 4641], + [690, 4626], + [685, 4588], + [746, 4592], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'UA', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.58, + 'hc-middle-y': 0.41, + 'hc-key': 'ua', + 'hc-a2': 'UA', + name: 'Ukraine', + labelrank: '3', + 'country-abbrev': 'Ukr.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'UKR', + 'iso-a2': 'UA', + 'woe-id': '23424976', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [7455, 2386], + [7493, 2450], + [7501, 2459], + [7470, 2406], + [7455, 2386], + ], + ], + [ + [ + [7966, 2676], + [7994, 2681], + [8031, 2696], + [8047, 2688], + [7966, 2676], + ], + ], + [ + [ + [7864, 2673], + [7779, 2665], + [7752, 2669], + [7846, 2675], + [7864, 2673], + ], + ], + [ + [ + [5798, 2837], + [5793, 2890], + [5819, 2928], + [5819, 2970], + [5841, 3040], + [5904, 3029], + [5867, 3073], + [5861, 3130], + [5837, 3173], + [5900, 3310], + [5994, 3455], + [6035, 3467], + [6051, 3510], + [6010, 3586], + [6038, 3595], + [5989, 3635], + [5976, 3670], + [5922, 3719], + [5907, 3769], + [5926, 3810], + [5970, 3801], + [6008, 3848], + [6025, 3898], + [6082, 3911], + [6159, 3947], + [6262, 3963], + [6378, 3967], + [6462, 3957], + [6519, 3969], + [6542, 3930], + [6616, 3948], + [6634, 3914], + [6639, 3956], + [6687, 3955], + [6704, 3988], + [6737, 3959], + [6780, 3978], + [6813, 3942], + [6825, 3992], + [6865, 4022], + [6918, 3960], + [6961, 4007], + [7005, 4004], + [7053, 4033], + [7103, 3994], + [7140, 3984], + [7149, 4017], + [7106, 4084], + [7114, 4151], + [7144, 4237], + [7196, 4244], + [7228, 4275], + [7278, 4286], + [7305, 4275], + [7359, 4306], + [7358, 4378], + [7461, 4389], + [7495, 4437], + [7544, 4450], + [7559, 4434], + [7598, 4468], + [7657, 4432], + [7685, 4375], + [7746, 4356], + [7755, 4326], + [7716, 4303], + [7775, 4229], + [7767, 4189], + [7843, 4209], + [7871, 4200], + [7929, 4227], + [7978, 4187], + [8043, 4111], + [8032, 4093], + [8058, 4058], + [8114, 4038], + [8131, 4069], + [8177, 4085], + [8220, 4059], + [8238, 4073], + [8284, 4059], + [8325, 4117], + [8405, 4175], + [8447, 4151], + [8492, 4103], + [8559, 4075], + [8583, 4097], + [8571, 4130], + [8675, 4127], + [8730, 4116], + [8766, 4149], + [8806, 4125], + [8846, 4141], + [8909, 4111], + [8957, 4148], + [8960, 4107], + [9002, 4059], + [8986, 3990], + [8948, 3965], + [8976, 3938], + [9015, 3941], + [8984, 3894], + [8990, 3846], + [9021, 3859], + [9090, 3791], + [9081, 3739], + [9100, 3657], + [8932, 3589], + [8934, 3537], + [8873, 3489], + [8881, 3393], + [8905, 3344], + [8790, 3293], + [8767, 3220], + [8748, 3228], + [8710, 3193], + [8685, 3138], + [8660, 3145], + [8577, 3079], + [8526, 3055], + [8457, 2941], + [8432, 2953], + [8409, 2894], + [8369, 2847], + [8405, 2786], + [8463, 2728], + [8547, 2667], + [8583, 2657], + [8621, 2681], + [8638, 2731], + [8673, 2711], + [8692, 2749], + [8781, 2772], + [8770, 2707], + [8791, 2664], + [8756, 2632], + [8717, 2630], + [8685, 2601], + [8631, 2618], + [8538, 2498], + [8491, 2476], + [8444, 2431], + [8433, 2370], + [8377, 2301], + [8328, 2290], + [8246, 2312], + [8278, 2340], + [8252, 2382], + [8259, 2429], + [8232, 2470], + [8195, 2485], + [8168, 2467], + [8079, 2498], + [8006, 2470], + [7998, 2503], + [8048, 2572], + [8195, 2713], + [8166, 2718], + [8144, 2762], + [8135, 2728], + [8065, 2759], + [8051, 2728], + [7988, 2706], + [7938, 2672], + [7887, 2672], + [7783, 2705], + [7811, 2745], + [7721, 2746], + [7876, 2771], + [7896, 2816], + [7798, 2795], + [7766, 2837], + [7766, 2785], + [7693, 2768], + [7604, 2727], + [7565, 2690], + [7579, 2673], + [7551, 2554], + [7503, 2462], + [7472, 2461], + [7470, 2423], + [7440, 2382], + [7406, 2436], + [7425, 2339], + [7451, 2343], + [7468, 2301], + [7457, 2266], + [7445, 2302], + [7373, 2312], + [7282, 2223], + [7186, 2225], + [7150, 2258], + [7203, 2283], + [7190, 2327], + [7228, 2391], + [7223, 2426], + [7259, 2448], + [7256, 2502], + [7235, 2519], + [7222, 2574], + [7258, 2609], + [7279, 2560], + [7319, 2610], + [7355, 2583], + [7369, 2620], + [7405, 2591], + [7448, 2613], + [7404, 2644], + [7384, 2725], + [7302, 2743], + [7303, 2774], + [7273, 2849], + [7248, 2829], + [7174, 2884], + [7170, 2984], + [7141, 3008], + [7112, 2987], + [7070, 3029], + [7015, 3026], + [6981, 3041], + [6926, 3031], + [6850, 3073], + [6803, 3068], + [6749, 3021], + [6685, 3015], + [6652, 2968], + [6596, 2941], + [6585, 2873], + [6419, 2808], + [6400, 2767], + [6360, 2740], + [6283, 2792], + [6223, 2767], + [6132, 2776], + [6052, 2762], + [6000, 2782], + [5962, 2732], + [5928, 2776], + [5901, 2766], + [5872, 2803], + [5848, 2799], + [5824, 2842], + [5798, 2837], + ], + [ + [7457, 2615], + [7536, 2553], + [7547, 2572], + [7470, 2626], + [7457, 2615], + ], + [ + [8226, 2751], + [8230, 2774], + [8290, 2767], + [8336, 2746], + [8341, 2716], + [8384, 2771], + [8375, 2732], + [8448, 2722], + [8511, 2641], + [8573, 2639], + [8552, 2659], + [8454, 2726], + [8380, 2809], + [8334, 2833], + [8341, 2785], + [8309, 2776], + [8319, 2817], + [8239, 2836], + [8226, 2787], + [8209, 2801], + [8147, 2787], + [8226, 2751], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'FI', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.58, + 'hc-middle-y': 0.72, + 'hc-key': 'fi', + 'hc-a2': 'FI', + name: 'Finland', + labelrank: '3', + 'country-abbrev': 'Fin.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'FIN', + 'iso-a2': 'FI', + 'woe-id': '23424812', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [4993, 6096], + [4976, 6089], + [4970, 6088], + [4977, 6101], + [4993, 6096], + ], + ], + [ + [ + [4992, 6109], + [5004, 6120], + [5016, 6114], + [5011, 6102], + [4992, 6109], + ], + ], + [ + [ + [4939, 6118], + [4961, 6095], + [4955, 6084], + [4930, 6101], + [4939, 6118], + ], + ], + [ + [ + [4959, 6128], + [4966, 6130], + [4964, 6111], + [4954, 6118], + [4959, 6128], + ], + ], + [ + [ + [4873, 6139], + [4861, 6117], + [4851, 6132], + [4858, 6155], + [4873, 6139], + ], + ], + [ + [ + [4902, 6194], + [4957, 6174], + [4947, 6141], + [4922, 6163], + [4931, 6115], + [4891, 6105], + [4867, 6158], + [4902, 6194], + ], + ], + [ + [ + [5277, 6163], + [5280, 6143], + [5272, 6140], + [5263, 6163], + [5277, 6163], + ], + ], + [ + [ + [5158, 6164], + [5156, 6153], + [5142, 6149], + [5147, 6172], + [5158, 6164], + ], + ], + [ + [ + [5191, 6183], + [5175, 6160], + [5167, 6161], + [5170, 6182], + [5191, 6183], + ], + ], + [ + [ + [5210, 6170], + [5199, 6182], + [5212, 6195], + [5210, 6182], + [5210, 6170], + ], + ], + [ + [ + [5722, 6296], + [5708, 6311], + [5710, 6317], + [5727, 6305], + [5722, 6296], + ], + ], + [ + [ + [5326, 6209], + [5314, 6149], + [5284, 6144], + [5272, 6198], + [5326, 6209], + ], + ], + [ + [ + [5243, 6212], + [5215, 6212], + [5220, 6227], + [5248, 6226], + [5243, 6212], + ], + ], + [ + [ + [5261, 6239], + [5254, 6226], + [5245, 6233], + [5256, 6244], + [5261, 6239], + ], + ], + [ + [ + [5222, 6241], + [5239, 6247], + [5240, 6243], + [5227, 6236], + [5222, 6241], + ], + ], + [ + [ + [5196, 6222], + [5169, 6235], + [5179, 6259], + [5200, 6229], + [5196, 6222], + ], + ], + [ + [ + [5114, 6275], + [5115, 6255], + [5107, 6259], + [5095, 6277], + [5114, 6275], + ], + ], + [ + [ + [5079, 6373], + [5065, 6389], + [5072, 6396], + [5084, 6386], + [5079, 6373], + ], + ], + [ + [ + [4937, 7061], + [4954, 7049], + [4977, 7043], + [4964, 7024], + [4937, 7061], + ], + ], + [ + [ + [5064, 7083], + [5069, 7094], + [5088, 7090], + [5076, 7072], + [5064, 7083], + ], + ], + [ + [ + [4972, 7074], + [4968, 7065], + [4954, 7075], + [4968, 7088], + [4972, 7074], + ], + ], + [ + [ + [5135, 7240], + [5138, 7228], + [5131, 7222], + [5121, 7233], + [5135, 7240], + ], + ], + [ + [ + [5322, 7664], + [5299, 7629], + [5286, 7647], + [5295, 7662], + [5322, 7664], + ], + ], + [ + [ + [5345, 6190], + [5331, 6207], + [5327, 6241], + [5281, 6204], + [5269, 6214], + [5287, 6256], + [5239, 6250], + [5173, 6282], + [5163, 6310], + [5142, 6267], + [5098, 6304], + [5093, 6379], + [5067, 6421], + [5089, 6423], + [5097, 6469], + [5073, 6573], + [5103, 6565], + [5073, 6596], + [5037, 6676], + [5017, 6687], + [5013, 6796], + [4984, 6806], + [4983, 6864], + [4964, 6884], + [4975, 6939], + [5002, 6971], + [5001, 7006], + [5028, 6998], + [4995, 7046], + [5044, 7070], + [5050, 7045], + [5104, 7098], + [5073, 7134], + [5102, 7148], + [5112, 7214], + [5146, 7203], + [5158, 7255], + [5202, 7289], + [5195, 7332], + [5255, 7403], + [5254, 7443], + [5289, 7495], + [5290, 7539], + [5322, 7603], + [5356, 7625], + [5385, 7602], + [5393, 7628], + [5369, 7651], + [5398, 7650], + [5360, 7689], + [5364, 7730], + [5355, 7797], + [5315, 7825], + [5266, 7823], + [5238, 7871], + [5223, 7856], + [5191, 7866], + [5161, 7928], + [5117, 7968], + [5095, 8033], + [5116, 8076], + [5106, 8131], + [5115, 8151], + [5047, 8242], + [5053, 8324], + [5012, 8336], + [5020, 8369], + [4997, 8455], + [5012, 8473], + [4945, 8521], + [4925, 8569], + [4893, 8592], + [4833, 8607], + [4808, 8603], + [4787, 8627], + [4732, 8654], + [4661, 8729], + [4625, 8745], + [4635, 8767], + [4669, 8753], + [4680, 8769], + [4662, 8795], + [4687, 8832], + [4725, 8830], + [4776, 8761], + [4823, 8711], + [4835, 8679], + [4900, 8683], + [4923, 8666], + [4976, 8706], + [4991, 8740], + [5041, 8717], + [5079, 8712], + [5106, 8686], + [5129, 8714], + [5127, 8767], + [5171, 8799], + [5178, 8840], + [5159, 8892], + [5162, 8948], + [5153, 8993], + [5157, 9048], + [5173, 9058], + [5190, 9125], + [5225, 9140], + [5252, 9135], + [5290, 9182], + [5320, 9205], + [5361, 9160], + [5392, 9139], + [5476, 9121], + [5515, 9065], + [5485, 8979], + [5490, 8946], + [5509, 8926], + [5467, 8875], + [5508, 8866], + [5495, 8771], + [5543, 8678], + [5621, 8661], + [5680, 8597], + [5730, 8568], + [5735, 8514], + [5708, 8441], + [5685, 8340], + [5696, 8295], + [5773, 8209], + [5793, 8170], + [5847, 8111], + [5891, 8036], + [5907, 7989], + [5863, 7968], + [5889, 7883], + [5880, 7852], + [5913, 7851], + [5920, 7819], + [5900, 7782], + [5939, 7733], + [5974, 7739], + [6000, 7703], + [5979, 7678], + [6002, 7628], + [6081, 7597], + [6094, 7531], + [6072, 7463], + [6049, 7441], + [6136, 7380], + [6185, 7369], + [6251, 7333], + [6261, 7312], + [6320, 7265], + [6313, 7140], + [6287, 7068], + [6260, 7026], + [6195, 6828], + [6171, 6788], + [6144, 6709], + [6100, 6652], + [6036, 6533], + [6004, 6463], + [5961, 6425], + [5915, 6445], + [5896, 6417], + [5808, 6365], + [5760, 6377], + [5762, 6313], + [5734, 6307], + [5718, 6339], + [5702, 6300], + [5659, 6290], + [5659, 6272], + [5580, 6239], + [5570, 6198], + [5551, 6217], + [5449, 6162], + [5424, 6157], + [5404, 6119], + [5356, 6102], + [5399, 6143], + [5377, 6144], + [5394, 6176], + [5356, 6176], + [5346, 6188], + [5344, 6176], + [5342, 6158], + [5333, 6178], + [5345, 6190], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'SE', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.52, + 'hc-middle-y': 0.34, + 'hc-key': 'se', + 'hc-a2': 'SE', + name: 'Sweden', + labelrank: '3', + 'country-abbrev': 'Swe.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'SWE', + 'iso-a2': 'SE', + 'woe-id': '23424954', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [4581, 5272], + [4583, 5238], + [4535, 5043], + [4529, 4978], + [4507, 4942], + [4497, 5032], + [4523, 5130], + [4538, 5137], + [4566, 5259], + [4581, 5272], + ], + ], + [ + [ + [4891, 5495], + [4910, 5490], + [4866, 5467], + [4871, 5487], + [4891, 5495], + ], + ], + [ + [ + [3744, 5428], + [3733, 5400], + [3712, 5397], + [3709, 5423], + [3744, 5428], + ], + ], + [ + [ + [3751, 5482], + [3754, 5447], + [3710, 5435], + [3696, 5456], + [3732, 5493], + [3751, 5482], + ], + ], + [ + [ + [4523, 5546], + [4520, 5537], + [4508, 5566], + [4529, 5555], + [4523, 5546], + ], + ], + [ + [ + [4726, 5760], + [4721, 5748], + [4707, 5740], + [4707, 5752], + [4726, 5760], + ], + ], + [ + [ + [4703, 5774], + [4693, 5756], + [4681, 5760], + [4687, 5772], + [4703, 5774], + ], + ], + [ + [ + [4628, 5737], + [4620, 5738], + [4617, 5776], + [4629, 5757], + [4628, 5737], + ], + ], + [ + [ + [4738, 5788], + [4732, 5773], + [4722, 5779], + [4737, 5805], + [4738, 5788], + ], + ], + [ + [ + [4740, 5856], + [4743, 5848], + [4741, 5838], + [4713, 5856], + [4740, 5856], + ], + ], + [ + [ + [4755, 5930], + [4740, 5895], + [4731, 5912], + [4741, 5929], + [4755, 5930], + ], + ], + [ + [ + [4779, 5953], + [4788, 5967], + [4786, 5948], + [4777, 5952], + [4779, 5953], + ], + ], + [ + [ + [4790, 6015], + [4791, 6010], + [4776, 6006], + [4783, 6029], + [4790, 6015], + ], + ], + [ + [ + [4688, 6191], + [4710, 6150], + [4685, 6166], + [4681, 6205], + [4688, 6191], + ], + ], + [ + [ + [4563, 6851], + [4572, 6851], + [4569, 6834], + [4556, 6831], + [4563, 6851], + ], + ], + [ + [ + [4889, 7192], + [4898, 7199], + [4898, 7178], + [4891, 7169], + [4889, 7192], + ], + ], + [ + [ + [4984, 7737], + [4981, 7732], + [4983, 7723], + [4969, 7739], + [4984, 7737], + ], + ], + [ + [ + [5014, 7760], + [5021, 7760], + [5017, 7746], + [5009, 7757], + [5014, 7760], + ], + ], + [ + [ + [4737, 5337], + [4781, 5427], + [4820, 5465], + [4829, 5444], + [4861, 5466], + [4876, 5446], + [4837, 5414], + [4844, 5332], + [4867, 5322], + [4830, 5286], + [4840, 5271], + [4792, 5232], + [4785, 5177], + [4761, 5169], + [4776, 5205], + [4743, 5265], + [4752, 5301], + [4737, 5337], + ], + ], + [ + [ + [4625, 8745], + [4661, 8729], + [4732, 8654], + [4787, 8627], + [4808, 8603], + [4833, 8607], + [4893, 8592], + [4925, 8569], + [4945, 8521], + [5012, 8473], + [4997, 8455], + [5020, 8369], + [5012, 8336], + [5053, 8324], + [5047, 8242], + [5115, 8151], + [5106, 8131], + [5116, 8076], + [5095, 8033], + [5117, 7968], + [5161, 7928], + [5191, 7866], + [5167, 7842], + [5135, 7857], + [5097, 7848], + [5074, 7811], + [5013, 7844], + [5017, 7815], + [4988, 7838], + [4970, 7786], + [4995, 7744], + [4913, 7774], + [4968, 7739], + [4929, 7731], + [4946, 7697], + [4891, 7682], + [4922, 7655], + [4919, 7613], + [4879, 7513], + [4863, 7506], + [4936, 7408], + [4882, 7303], + [4872, 7224], + [4838, 7205], + [4820, 7152], + [4789, 7151], + [4754, 7104], + [4749, 7076], + [4715, 7110], + [4726, 7067], + [4695, 7077], + [4698, 7043], + [4673, 6991], + [4656, 6999], + [4622, 6975], + [4596, 6913], + [4609, 6891], + [4560, 6858], + [4538, 6870], + [4560, 6814], + [4521, 6754], + [4482, 6780], + [4472, 6739], + [4501, 6688], + [4488, 6609], + [4501, 6542], + [4458, 6497], + [4477, 6471], + [4490, 6327], + [4518, 6257], + [4502, 6243], + [4558, 6233], + [4571, 6196], + [4609, 6224], + [4619, 6200], + [4713, 6127], + [4678, 6140], + [4708, 6106], + [4754, 6099], + [4781, 6040], + [4762, 6002], + [4798, 6008], + [4748, 5958], + [4717, 5912], + [4660, 5882], + [4732, 5872], + [4721, 5897], + [4770, 5878], + [4763, 5862], + [4703, 5859], + [4729, 5811], + [4676, 5782], + [4660, 5738], + [4637, 5738], + [4632, 5796], + [4611, 5784], + [4615, 5719], + [4522, 5639], + [4417, 5642], + [4446, 5623], + [4502, 5632], + [4528, 5600], + [4497, 5582], + [4512, 5550], + [4514, 5494], + [4490, 5435], + [4465, 5421], + [4515, 5366], + [4494, 5370], + [4518, 5303], + [4498, 5275], + [4491, 5215], + [4513, 5179], + [4452, 4992], + [4446, 4944], + [4421, 4893], + [4415, 4914], + [4373, 4924], + [4334, 4902], + [4274, 4907], + [4232, 4897], + [4247, 4864], + [4201, 4861], + [4161, 4798], + [4160, 4770], + [4191, 4714], + [4163, 4674], + [4114, 4683], + [4016, 4653], + [3962, 4674], + [3956, 4718], + [3976, 4746], + [3953, 4767], + [3880, 4916], + [3927, 4904], + [3897, 4958], + [3939, 4970], + [3934, 5026], + [3912, 5025], + [3889, 5074], + [3853, 5099], + [3798, 5256], + [3779, 5227], + [3775, 5302], + [3742, 5330], + [3738, 5364], + [3762, 5474], + [3756, 5503], + [3707, 5491], + [3692, 5535], + [3665, 5507], + [3672, 5577], + [3645, 5689], + [3660, 5725], + [3693, 5697], + [3695, 5669], + [3727, 5677], + [3747, 5773], + [3725, 5862], + [3756, 5924], + [3748, 5954], + [3790, 5963], + [3842, 6028], + [3836, 6080], + [3850, 6144], + [3816, 6212], + [3797, 6278], + [3857, 6297], + [3880, 6395], + [3841, 6445], + [3814, 6454], + [3777, 6495], + [3794, 6644], + [3760, 6746], + [3767, 6790], + [3759, 6845], + [3774, 6868], + [3741, 6952], + [3767, 7001], + [3762, 7043], + [3825, 7151], + [3894, 7193], + [3986, 7174], + [4012, 7233], + [4002, 7302], + [3940, 7341], + [4015, 7494], + [4036, 7564], + [4035, 7678], + [4042, 7721], + [4024, 7804], + [4086, 7816], + [4134, 7856], + [4123, 7920], + [4149, 7954], + [4186, 8043], + [4225, 8096], + [4224, 8141], + [4182, 8204], + [4188, 8230], + [4219, 8248], + [4246, 8357], + [4298, 8421], + [4367, 8387], + [4391, 8447], + [4379, 8560], + [4406, 8575], + [4432, 8556], + [4475, 8562], + [4579, 8529], + [4608, 8572], + [4575, 8586], + [4600, 8626], + [4600, 8702], + [4570, 8732], + [4625, 8745], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'RU', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.59, + 'hc-middle-y': 0.45, + 'hc-key': 'ru', + 'hc-a2': 'RU', + name: 'Russia', + labelrank: '2', + 'country-abbrev': 'Rus.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'RUS', + 'iso-a2': 'RU', + 'woe-id': '23424936', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [6161, 5739], + [6243, 5717], + [6237, 5759], + [6194, 5799], + [6149, 5776], + [6124, 5800], + [6149, 5876], + [6122, 5986], + [6102, 6021], + [6106, 6046], + [6108, 6072], + [6115, 6109], + [6124, 6119], + [6130, 6125], + [6119, 6126], + [6130, 6125], + [6143, 6139], + [6126, 6160], + [6111, 6169], + [6091, 6230], + [6097, 6261], + [6148, 6234], + [6154, 6294], + [6188, 6280], + [6221, 6303], + [6234, 6358], + [6388, 6364], + [6381, 6399], + [6342, 6396], + [6317, 6431], + [6199, 6407], + [6158, 6445], + [6127, 6446], + [6091, 6487], + [6133, 6467], + [6112, 6530], + [6078, 6516], + [6061, 6476], + [6004, 6463], + [6036, 6533], + [6100, 6652], + [6144, 6709], + [6171, 6788], + [6195, 6828], + [6260, 7026], + [6287, 7068], + [6313, 7140], + [6320, 7265], + [6261, 7312], + [6251, 7333], + [6185, 7369], + [6136, 7380], + [6049, 7441], + [6072, 7463], + [6094, 7531], + [6081, 7597], + [6002, 7628], + [5979, 7678], + [6000, 7703], + [5974, 7739], + [5939, 7733], + [5900, 7782], + [5920, 7819], + [5913, 7851], + [5880, 7852], + [5889, 7883], + [5863, 7968], + [5907, 7989], + [5891, 8036], + [5847, 8111], + [5793, 8170], + [5773, 8209], + [5696, 8295], + [5685, 8340], + [5708, 8441], + [5735, 8514], + [5730, 8568], + [5680, 8597], + [5621, 8661], + [5543, 8678], + [5495, 8771], + [5508, 8866], + [5467, 8875], + [5509, 8926], + [5532, 8960], + [5529, 9010], + [5581, 9050], + [5597, 9081], + [5599, 9138], + [5628, 9120], + [5664, 9128], + [5659, 9172], + [5638, 9209], + [5685, 9209], + [5710, 9193], + [5747, 9204], + [5726, 9251], + [5760, 9239], + [5736, 9277], + [5746, 9292], + [5820, 9258], + [5849, 9267], + [5881, 9239], + [5863, 9208], + [5786, 9206], + [5779, 9175], + [5814, 9193], + [5836, 9176], + [5895, 9185], + [5883, 9145], + [5922, 9186], + [5944, 9186], + [5940, 9121], + [5965, 9116], + [5964, 9160], + [6046, 9184], + [6077, 9175], + [6141, 9187], + [6142, 9207], + [6217, 9203], + [6264, 9182], + [6330, 9171], + [6416, 9139], + [6441, 9140], + [6559, 9072], + [6574, 9088], + [6704, 9042], + [6761, 9048], + [6812, 9033], + [6845, 8998], + [6855, 9022], + [6905, 9008], + [6932, 8944], + [6953, 8939], + [6971, 8891], + [6994, 8896], + [7027, 8838], + [7034, 8774], + [7005, 8628], + [6980, 8579], + [6916, 8501], + [6838, 8442], + [6764, 8422], + [6626, 8430], + [6572, 8412], + [6444, 8403], + [6359, 8434], + [6325, 8401], + [6282, 8430], + [6243, 8419], + [6195, 8445], + [6200, 8416], + [6106, 8461], + [6091, 8493], + [6038, 8497], + [6028, 8483], + [6073, 8455], + [6081, 8424], + [6125, 8392], + [6171, 8394], + [6159, 8338], + [6198, 8349], + [6253, 8343], + [6252, 8307], + [6375, 8282], + [6437, 8236], + [6462, 8184], + [6427, 8204], + [6459, 8148], + [6442, 8071], + [6519, 7996], + [6512, 7973], + [6552, 7949], + [6545, 7915], + [6581, 7883], + [6562, 7858], + [6666, 7811], + [6708, 7845], + [6743, 7813], + [6782, 7804], + [6801, 7775], + [6860, 7771], + [6919, 7785], + [6942, 7770], + [7012, 7842], + [7014, 7867], + [6972, 7910], + [6972, 7940], + [6922, 7956], + [6891, 7915], + [6859, 7919], + [6783, 7980], + [6758, 7982], + [6722, 8032], + [6761, 8060], + [6742, 8112], + [6761, 8128], + [6859, 8118], + [6917, 8089], + [7033, 8099], + [7129, 8080], + [7147, 8130], + [7199, 8115], + [7240, 8128], + [7178, 8223], + [7129, 8251], + [7045, 8320], + [7033, 8381], + [7069, 8437], + [7094, 8533], + [7145, 8580], + [7172, 8670], + [7178, 8751], + [7236, 8752], + [7235, 8729], + [7303, 8780], + [7377, 8744], + [7353, 8690], + [7399, 8745], + [7436, 8729], + [7476, 8684], + [7413, 8795], + [7402, 8910], + [7374, 8932], + [7369, 8976], + [7324, 9009], + [7263, 9008], + [7238, 9051], + [7210, 9191], + [7194, 9213], + [7159, 9318], + [7139, 9335], + [7019, 9368], + [7027, 9390], + [7093, 9384], + [7223, 9450], + [7299, 9457], + [7325, 9430], + [7402, 9407], + [7463, 9341], + [7403, 9282], + [7343, 9236], + [7359, 9198], + [7338, 9166], + [7360, 9106], + [7449, 9098], + [7514, 9042], + [7542, 9038], + [7591, 9079], + [7600, 9064], + [7667, 9142], + [7689, 9179], + [7655, 9230], + [7644, 9306], + [7615, 9329], + [7639, 9386], + [7683, 9428], + [7668, 9467], + [7697, 9484], + [7728, 9545], + [7765, 9652], + [7773, 9713], + [7794, 9714], + [7870, 9851], + [7872, 9851], + [7892, 9835], + [7898, 9795], + [7929, 9801], + [7936, 9851], + [8020, 9851], + [8021, 9833], + [8055, 9851], + [9732, 9851], + [9732, 2582], + [9688, 2568], + [9659, 2542], + [9662, 2497], + [9589, 2522], + [9379, 2615], + [9285, 2633], + [9196, 2619], + [9107, 2671], + [9032, 2637], + [8968, 2690], + [8806, 2713], + [8834, 2751], + [8827, 2795], + [8896, 2789], + [8901, 2761], + [8965, 2827], + [9012, 2828], + [8978, 2893], + [8970, 2849], + [8950, 2912], + [8981, 2954], + [8977, 3041], + [9017, 3090], + [9065, 3076], + [9077, 3107], + [9018, 3114], + [8967, 3143], + [8941, 3127], + [8863, 3194], + [8924, 3204], + [8970, 3283], + [9035, 3333], + [9069, 3391], + [9105, 3400], + [9077, 3467], + [9026, 3422], + [8905, 3344], + [8881, 3393], + [8873, 3489], + [8934, 3537], + [8932, 3589], + [9100, 3657], + [9081, 3739], + [9090, 3791], + [9021, 3859], + [8990, 3846], + [8984, 3894], + [9015, 3941], + [8976, 3938], + [8948, 3965], + [8986, 3990], + [9002, 4059], + [8960, 4107], + [8957, 4148], + [8909, 4111], + [8846, 4141], + [8806, 4125], + [8766, 4149], + [8730, 4116], + [8675, 4127], + [8571, 4130], + [8583, 4097], + [8559, 4075], + [8492, 4103], + [8447, 4151], + [8405, 4175], + [8325, 4117], + [8284, 4059], + [8238, 4073], + [8220, 4059], + [8177, 4085], + [8131, 4069], + [8114, 4038], + [8058, 4058], + [8032, 4093], + [8043, 4111], + [7978, 4187], + [7929, 4227], + [7871, 4200], + [7843, 4209], + [7767, 4189], + [7775, 4229], + [7716, 4303], + [7755, 4326], + [7746, 4356], + [7685, 4375], + [7657, 4432], + [7598, 4468], + [7559, 4434], + [7544, 4450], + [7495, 4437], + [7461, 4389], + [7358, 4378], + [7359, 4306], + [7305, 4275], + [7278, 4286], + [7227, 4334], + [7171, 4478], + [7114, 4511], + [7126, 4570], + [7180, 4585], + [7246, 4572], + [7290, 4620], + [7320, 4704], + [7266, 4719], + [7254, 4763], + [7183, 4772], + [7129, 4751], + [7118, 4826], + [7024, 4849], + [6987, 4904], + [6960, 4909], + [6966, 4950], + [6889, 4976], + [6884, 5017], + [6907, 5053], + [6852, 5115], + [6861, 5155], + [6840, 5206], + [6818, 5198], + [6759, 5240], + [6715, 5246], + [6663, 5224], + [6610, 5166], + [6584, 5189], + [6576, 5237], + [6517, 5241], + [6489, 5207], + [6449, 5241], + [6400, 5217], + [6371, 5238], + [6371, 5279], + [6340, 5347], + [6284, 5395], + [6262, 5427], + [6240, 5414], + [6248, 5510], + [6241, 5547], + [6181, 5574], + [6177, 5602], + [6151, 5595], + [6159, 5682], + [6194, 5705], + [6161, 5739], + ], + [ + [5965, 9116], + [5965, 9113], + [5965, 9113], + [5965, 9113], + [5933, 9064], + [5966, 9090], + [5965, 9113], + [5965, 9113], + [5965, 9113], + [5967, 9115], + [5965, 9116], + ], + ], + [ + [ + [6120, 6424], + [6130, 6432], + [6151, 6421], + [6138, 6413], + [6120, 6424], + ], + ], + [ + [ + [6732, 7851], + [6707, 7864], + [6714, 7869], + [6731, 7863], + [6732, 7851], + ], + ], + [ + [ + [6624, 8069], + [6645, 8030], + [6594, 8040], + [6591, 8054], + [6624, 8069], + ], + ], + [ + [ + [6641, 8087], + [6652, 8081], + [6676, 8089], + [6657, 8072], + [6641, 8087], + ], + ], + [ + [ + [7211, 8811], + [7186, 8812], + [7174, 8829], + [7188, 8834], + [7211, 8811], + ], + ], + [ + [ + [7795, 9756], + [7773, 9714], + [7788, 9768], + [7821, 9784], + [7795, 9756], + ], + ], + [ + [ + [6041, 9195], + [6002, 9182], + [5996, 9191], + [6016, 9204], + [6041, 9195], + ], + ], + [ + [ + [5279, 4758], + [5218, 4659], + [5310, 4654], + [5333, 4669], + [5314, 4740], + [5326, 4758], + [5472, 4718], + [5549, 4740], + [5594, 4700], + [5595, 4571], + [5615, 4546], + [5604, 4540], + [5111, 4489], + [5209, 4577], + [5134, 4570], + [5118, 4544], + [5118, 4544], + [5118, 4544], + [5137, 4642], + [5191, 4649], + [5231, 4685], + [5268, 4759], + [5279, 4758], + [5279, 4758], + ], + ], + [ + [ + [5088, 4491], + [5086, 4492], + [5103, 4518], + [5103, 4518], + [5088, 4491], + ], + ], + [ + [ + [7186, 8155], + [7163, 8163], + [7191, 8181], + [7206, 8168], + [7216, 8145], + [7193, 8153], + [7230, 8134], + [7199, 8120], + [7145, 8136], + [7155, 8151], + [7186, 8155], + ], + ], + [ + [ + [5103, 4518], + [5118, 4544], + [5118, 4544], + [5118, 4544], + [5117, 4538], + [5103, 4518], + [5103, 4518], + ], + ], + [ + [ + [7399, 9803], + [7406, 9851], + [7585, 9851], + [7583, 9843], + [7591, 9782], + [7564, 9727], + [7510, 9677], + [7448, 9702], + [7399, 9803], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'GB', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.18, + 'hc-middle-y': 0.36, + 'hc-key': 'gb', + 'hc-a2': 'GB', + name: 'United Kingdom', + labelrank: '2', + 'country-abbrev': 'U.K.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'GBR', + 'iso-a2': 'GB', + 'woe-id': '-90', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [1201, 3080], + [1215, 3052], + [1176, 3062], + [1178, 3081], + [1201, 3080], + ], + ], + [ + [ + [1423, 3486], + [1461, 3456], + [1411, 3434], + [1382, 3463], + [1423, 3486], + ], + ], + [[[968, 4314], [973, 4313], [980, 4292], [962, 4305], [968, 4314]]], + [ + [ + [1043, 4292], + [1070, 4288], + [1010, 4250], + [979, 4298], + [986, 4332], + [1036, 4324], + [1043, 4292], + ], + ], + [ + [ + [1017, 4928], + [983, 4948], + [995, 5006], + [1025, 4996], + [1017, 4928], + ], + ], + [ + [ + [1052, 5006], + [1038, 5025], + [1033, 5063], + [1050, 5050], + [1052, 5006], + ], + ], + [ + [ + [885, 5073], + [888, 5028], + [851, 5030], + [842, 5065], + [811, 5045], + [830, 5088], + [886, 5105], + [885, 5073], + ], + ], + [[[898, 5153], [887, 5135], [874, 5134], [891, 5156], [898, 5153]]], + [[[961, 5153], [957, 5129], [905, 5060], [894, 5095], [961, 5153]]], + [[[803, 5273], [790, 5294], [831, 5297], [807, 5283], [803, 5273]]], + [ + [ + [946, 5292], + [953, 5262], + [986, 5245], + [991, 5217], + [878, 5206], + [922, 5254], + [894, 5284], + [935, 5305], + [946, 5292], + ], + ], + [[[862, 5305], [840, 5306], [862, 5321], [885, 5326], [862, 5305]]], + [[[763, 5445], [745, 5435], [733, 5442], [754, 5460], [763, 5445]]], + [[[935, 5412], [925, 5393], [906, 5415], [929, 5426], [935, 5412]]], + [[[796, 5561], [811, 5523], [775, 5475], [769, 5517], [796, 5561]]], + [[[811, 5581], [819, 5559], [805, 5558], [790, 5574], [811, 5581]]], + [[[838, 5625], [833, 5583], [780, 5621], [795, 5637], [838, 5625]]], + [ + [ + [1551, 5818], + [1538, 5794], + [1529, 5824], + [1542, 5826], + [1551, 5818], + ], + ], + [ + [ + [1501, 5850], + [1508, 5826], + [1487, 5818], + [1473, 5849], + [1501, 5850], + ], + ], + [ + [ + [1527, 5917], + [1583, 5845], + [1561, 5835], + [1544, 5861], + [1509, 5854], + [1490, 5887], + [1502, 5918], + [1527, 5917], + ], + ], + [ + [ + [1607, 5906], + [1619, 5887], + [1606, 5883], + [1600, 5908], + [1607, 5906], + ], + ], + [ + [ + [1548, 5925], + [1554, 5910], + [1540, 5912], + [1538, 5930], + [1548, 5925], + ], + ], + [ + [ + [1590, 5936], + [1590, 5908], + [1582, 5907], + [1578, 5924], + [1590, 5936], + ], + ], + [ + [ + [1647, 5941], + [1626, 5926], + [1614, 5932], + [1619, 5939], + [1647, 5941], + ], + ], + [ + [ + [1569, 5971], + [1575, 5943], + [1558, 5948], + [1549, 5970], + [1569, 5971], + ], + ], + [ + [ + [1936, 6281], + [1938, 6271], + [1924, 6271], + [1919, 6289], + [1936, 6281], + ], + ], + [ + [ + [1871, 6164], + [1837, 6082], + [1824, 6092], + [1855, 6186], + [1824, 6165], + [1802, 6213], + [1845, 6210], + [1841, 6261], + [1817, 6262], + [1863, 6293], + [1847, 6234], + [1892, 6239], + [1871, 6164], + ], + ], + [ + [ + [1904, 6323], + [1916, 6320], + [1900, 6254], + [1883, 6259], + [1904, 6323], + ], + ], + [ + [ + [1949, 6333], + [1938, 6303], + [1918, 6307], + [1936, 6350], + [1949, 6333], + ], + ], + [ + [ + [1131, 3142], + [1108, 3146], + [1111, 3154], + [1140, 3166], + [1131, 3142], + ], + ], + [ + [ + [1023, 4529], + [989, 4528], + [1011, 4570], + [1049, 4605], + [1082, 4612], + [1081, 4575], + [1023, 4529], + ], + ], + [[[-207, -551], [-210, -560], [-212, -550], [-207, -551]]], + [ + [ + [9095, -490], + [9069, -492], + [9034, -504], + [9046, -485], + [9095, -490], + ], + ], + [ + [ + [9270, -328], + [9261, -336], + [9242, -332], + [9236, -330], + [9242, -332], + [9237, -333], + [9224, -339], + [9224, -339], + [9223, -335], + [9219, -325], + [9213, -324], + [9213, -324], + [9233, -318], + [9262, -296], + [9262, -296], + [9261, -299], + [9240, -313], + [9270, -328], + ], + [ + [9232, -327], + [9232, -324], + [9229, -325], + [9230, -327], + [9232, -327], + ], + ], + [ + [ + [1830, 3601], + [1855, 3592], + [1936, 3594], + [1915, 3521], + [1853, 3503], + [1840, 3469], + [1808, 3479], + [1725, 3455], + [1705, 3437], + [1628, 3471], + [1555, 3474], + [1508, 3461], + [1496, 3491], + [1420, 3494], + [1303, 3481], + [1290, 3456], + [1211, 3481], + [1203, 3467], + [1138, 3522], + [1064, 3519], + [1015, 3491], + [1009, 3452], + [970, 3405], + [944, 3406], + [885, 3466], + [776, 3474], + [761, 3448], + [714, 3448], + [705, 3410], + [674, 3387], + [633, 3446], + [587, 3433], + [597, 3463], + [644, 3463], + [728, 3514], + [738, 3539], + [784, 3551], + [840, 3602], + [856, 3659], + [889, 3647], + [934, 3701], + [1004, 3698], + [1069, 3668], + [1134, 3657], + [1142, 3691], + [1204, 3735], + [1257, 3796], + [1213, 3761], + [1161, 3761], + [1116, 3721], + [1053, 3733], + [1010, 3807], + [985, 3794], + [929, 3803], + [923, 3866], + [870, 3863], + [817, 3838], + [812, 3872], + [776, 3942], + [818, 3963], + [861, 3953], + [986, 4004], + [1026, 4074], + [1039, 4180], + [985, 4185], + [961, 4159], + [918, 4168], + [955, 4201], + [1001, 4221], + [1048, 4271], + [1194, 4279], + [1224, 4247], + [1220, 4281], + [1244, 4294], + [1243, 4326], + [1286, 4374], + [1263, 4388], + [1277, 4433], + [1324, 4481], + [1291, 4516], + [1249, 4491], + [1225, 4578], + [1205, 4617], + [1266, 4714], + [1298, 4729], + [1242, 4752], + [1231, 4719], + [1190, 4724], + [1165, 4701], + [1132, 4713], + [1101, 4753], + [1094, 4689], + [1025, 4757], + [1006, 4744], + [1011, 4691], + [980, 4761], + [1017, 4840], + [1101, 4927], + [1065, 4997], + [1080, 5048], + [1101, 5062], + [1100, 5109], + [1065, 5045], + [1039, 5069], + [1010, 5064], + [1006, 5031], + [970, 4998], + [950, 4923], + [903, 4915], + [958, 5036], + [958, 5101], + [1001, 5152], + [978, 5167], + [1013, 5213], + [1069, 5218], + [1025, 5232], + [1071, 5292], + [995, 5245], + [951, 5291], + [971, 5303], + [922, 5320], + [932, 5335], + [982, 5321], + [988, 5362], + [1054, 5463], + [1027, 5491], + [1037, 5556], + [1062, 5536], + [1051, 5587], + [1058, 5629], + [1093, 5647], + [1112, 5620], + [1131, 5643], + [1167, 5614], + [1127, 5685], + [1148, 5677], + [1145, 5729], + [1192, 5729], + [1185, 5753], + [1229, 5825], + [1273, 5794], + [1400, 5774], + [1464, 5786], + [1521, 5771], + [1498, 5737], + [1500, 5708], + [1474, 5681], + [1325, 5602], + [1324, 5566], + [1362, 5562], + [1274, 5481], + [1382, 5502], + [1401, 5520], + [1462, 5496], + [1488, 5501], + [1546, 5480], + [1637, 5469], + [1654, 5405], + [1613, 5366], + [1592, 5311], + [1554, 5245], + [1512, 5212], + [1491, 5171], + [1429, 5146], + [1432, 5118], + [1469, 5088], + [1431, 5067], + [1403, 5076], + [1362, 5041], + [1296, 5041], + [1370, 5007], + [1422, 5032], + [1448, 5025], + [1519, 4972], + [1558, 4882], + [1586, 4863], + [1584, 4742], + [1603, 4625], + [1628, 4576], + [1711, 4521], + [1730, 4457], + [1778, 4405], + [1750, 4383], + [1756, 4346], + [1794, 4266], + [1763, 4265], + [1724, 4304], + [1739, 4267], + [1791, 4218], + [1813, 4142], + [1806, 4103], + [1743, 4053], + [1803, 4017], + [1843, 4064], + [1911, 4056], + [1963, 4037], + [2022, 3985], + [2034, 3900], + [2002, 3841], + [1988, 3788], + [1913, 3738], + [1898, 3712], + [1872, 3728], + [1844, 3654], + [1767, 3648], + [1809, 3635], + [1781, 3619], + [1823, 3604], + [1821, 3625], + [1842, 3614], + [1848, 3599], + [1830, 3601], + ], + ], + [ + [ + [989, 5494], + [996, 5479], + [1046, 5460], + [1035, 5441], + [976, 5406], + [984, 5454], + [937, 5454], + [922, 5503], + [886, 5554], + [922, 5560], + [917, 5592], + [950, 5557], + [973, 5607], + [990, 5569], + [977, 5518], + [989, 5495], + [995, 5528], + [1011, 5545], + [999, 5516], + [989, 5494], + ], + ], + [ + [ + [902, 5785], + [935, 5767], + [936, 5789], + [1032, 5834], + [1037, 5783], + [993, 5753], + [989, 5703], + [954, 5676], + [875, 5640], + [862, 5666], + [909, 5691], + [872, 5716], + [902, 5785], + ], + ], + [ + [ + [652, 4902], + [679, 4888], + [706, 4926], + [738, 4913], + [787, 4923], + [845, 4898], + [875, 4749], + [902, 4722], + [907, 4664], + [888, 4631], + [888, 4687], + [855, 4642], + [877, 4622], + [822, 4614], + [780, 4566], + [746, 4592], + [685, 4588], + [690, 4626], + [668, 4641], + [662, 4684], + [639, 4710], + [576, 4637], + [496, 4684], + [459, 4770], + [538, 4795], + [532, 4831], + [581, 4822], + [622, 4890], + [652, 4902], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'CY', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.19, + 'hc-middle-y': 0.71, + 'hc-key': 'cy', + 'hc-a2': 'CY', + name: 'Cyprus', + labelrank: '5', + 'country-abbrev': 'Cyp.', + subregion: 'Western Asia', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'CYP', + 'iso-a2': 'CY', + 'woe-id': '-90', + continent: 'Asia', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [9232, -327], + [9230, -327], + [9229, -325], + [9232, -324], + [9232, -327], + ], + ], + [ + [ + [9291, -290], + [9318, -310], + [9270, -328], + [9240, -313], + [9261, -299], + [9270, -299], + [9291, -290], + ], + ], + [ + [ + [9224, -339], + [9216, -390], + [9095, -490], + [9046, -485], + [9034, -504], + [8942, -502], + [8881, -414], + [8923, -412], + [8944, -370], + [8955, -373], + [8960, -360], + [8968, -358], + [9008, -383], + [9083, -327], + [9139, -309], + [9162, -352], + [9223, -335], + [9224, -339], + [9224, -339], + ], + ], + [ + [ + [9236, -330], + [9239, -329], + [9245, -331], + [9242, -332], + [9236, -330], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'PT', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.48, + 'hc-middle-y': 0.36, + 'hc-key': 'pt', + 'hc-a2': 'PT', + name: 'Portugal', + labelrank: '2', + 'country-abbrev': 'Port.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'PRT', + 'iso-a2': 'PT', + 'woe-id': '23424925', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-896, 403], + [-979, 424], + [-941, 512], + [-901, 573], + [-905, 609], + [-867, 611], + [-810, 675], + [-731, 789], + [-719, 832], + [-619, 1023], + [-609, 1164], + [-611, 1246], + [-566, 1304], + [-534, 1320], + [-441, 1327], + [-423, 1288], + [-463, 1252], + [-457, 1228], + [-354, 1228], + [-338, 1204], + [-257, 1193], + [-226, 1223], + [-107, 1176], + [-122, 1124], + [-54, 1057], + [-134, 993], + [-168, 993], + [-220, 941], + [-249, 936], + [-238, 881], + [-270, 768], + [-262, 740], + [-328, 703], + [-304, 645], + [-361, 562], + [-476, 588], + [-438, 511], + [-449, 478], + [-430, 404], + [-393, 365], + [-423, 324], + [-479, 302], + [-520, 224], + [-481, 131], + [-444, 129], + [-473, 83], + [-533, 84], + [-559, 40], + [-621, -20], + [-621, -134], + [-720, -162], + [-761, -157], + [-805, -120], + [-906, -83], + [-999, -89], + [-917, 33], + [-889, 160], + [-903, 172], + [-858, 231], + [-850, 282], + [-874, 333], + [-937, 322], + [-929, 397], + [-896, 403], + ], + [ + [-896, 403], + [-894, 402], + [-893, 403], + [-893, 403], + [-893, 404], + [-850, 411], + [-856, 453], + [-893, 404], + [-893, 404], + [-893, 404], + [-896, 403], + ], + ], + }, + }, + { + type: 'Feature', + id: 'GR', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.21, + 'hc-middle-y': 0.4, + 'hc-key': 'gr', + 'hc-a2': 'GR', + name: 'Greece', + labelrank: '3', + 'country-abbrev': 'Greece', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'GRC', + 'iso-a2': 'GR', + 'woe-id': '23424833', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [7604, -670], + [7608, -677], + [7582, -697], + [7580, -676], + [7604, -670], + ], + ], + [ + [ + [7631, -545], + [7629, -606], + [7642, -663], + [7609, -618], + [7631, -545], + ], + ], + [ + [ + [6616, -642], + [6582, -647], + [6584, -593], + [6626, -630], + [6616, -642], + ], + ], + [ + [ + [7823, -305], + [7805, -407], + [7756, -489], + [7713, -417], + [7751, -352], + [7823, -305], + ], + ], + [ + [ + [7182, -475], + [7175, -489], + [7154, -487], + [7169, -474], + [7182, -475], + ], + ], + [ + [ + [7617, -345], + [7625, -359], + [7626, -370], + [7604, -352], + [7617, -345], + ], + ], + [ + [ + [7396, -360], + [7364, -392], + [7351, -370], + [7370, -374], + [7396, -360], + ], + ], + [ + [ + [7712, -275], + [7723, -272], + [7731, -295], + [7701, -292], + [7712, -275], + ], + ], + [ + [ + [6934, -404], + [6941, -431], + [6892, -453], + [6893, -421], + [6934, -404], + ], + ], + [ + [ + [7139, -377], + [7138, -400], + [7105, -385], + [7113, -363], + [7139, -377], + ], + ], + [ + [ + [7551, -257], + [7495, -300], + [7519, -256], + [7566, -224], + [7551, -257], + ], + ], + [ + [ + [7286, -293], + [7247, -333], + [7238, -318], + [7267, -285], + [7286, -293], + ], + ], + [ + [ + [6946, -321], + [6976, -342], + [6967, -360], + [6944, -328], + [6946, -321], + ], + ], + [ + [ + [7485, -202], + [7503, -208], + [7503, -228], + [7477, -234], + [7485, -202], + ], + ], + [ + [ + [7046, -318], + [7057, -279], + [7081, -269], + [7077, -311], + [7046, -318], + ], + ], + [ + [ + [7438, -167], + [7460, -189], + [7449, -192], + [7429, -173], + [7438, -167], + ], + ], + [ + [ + [7161, -259], + [7139, -319], + [7104, -279], + [7140, -233], + [7161, -259], + ], + ], + [ + [ + [6896, -283], + [6906, -283], + [6912, -303], + [6889, -307], + [6896, -283], + ], + ], + [ + [ + [6670, -285], + [6660, -295], + [6632, -304], + [6650, -286], + [6670, -285], + ], + ], + [ + [ + [6880, -220], + [6863, -259], + [6857, -221], + [6868, -204], + [6880, -220], + ], + ], + [ + [ + [7078, -153], + [7107, -159], + [7096, -177], + [7075, -183], + [7078, -153], + ], + ], + [ + [ + [6996, -203], + [6979, -218], + [6972, -209], + [6981, -174], + [6996, -203], + ], + ], + [ + [ + [7008, -125], + [7047, -125], + [7046, -153], + [6989, -133], + [7008, -125], + ], + ], + [ + [ + [6842, -149], + [6851, -166], + [6828, -198], + [6824, -172], + [6842, -149], + ], + ], + [[[7294, -67], [7241, -114], [7221, -109], [7237, -79], [7294, -67]]], + [ + [ + [6639, -190], + [6630, -189], + [6618, -168], + [6650, -162], + [6639, -190], + ], + ], + [ + [ + [7431, 3], + [7459, -6], + [7400, -38], + [7346, -22], + [7402, 12], + [7431, 3], + ], + ], + [ + [ + [5994, -248], + [6054, -276], + [6018, -305], + [5965, -262], + [5994, -248], + ], + ], + [[[6938, -60], [6962, -58], [6965, -113], [6899, -63], [6938, -60]]], + [ + [ + [6631, -102], + [6637, -116], + [6621, -132], + [6605, -127], + [6631, -102], + ], + ], + [ + [ + [5926, -73], + [5995, -185], + [5927, -181], + [5891, -111], + [5913, -123], + [5926, -73], + ], + ], + [ + [ + [7173, 194], + [7198, 187], + [7214, 118], + [7188, 68], + [7149, 90], + [7172, 121], + [7124, 182], + [7173, 194], + ], + ], + [[[5956, -15], [5922, -30], [5914, -10], [5935, 41], [5956, -15]]], + [[[6817, 208], [6846, 190], [6813, 180], [6793, 232], [6817, 208]]], + [[[6561, 245], [6551, 230], [6536, 231], [6549, 254], [6561, 245]]], + [[[6579, 258], [6627, 240], [6618, 227], [6600, 227], [6579, 258]]], + [[[6648, 257], [6642, 262], [6651, 293], [6659, 292], [6648, 257]]], + [ + [ + [7202, 424], + [7264, 345], + [7228, 323], + [7167, 325], + [7082, 354], + [7082, 378], + [7183, 438], + [7202, 424], + ], + ], + [[[5724, 291], [5711, 248], [5738, 200], [5658, 269], [5724, 291]]], + [ + [ + [6940, 577], + [6935, 505], + [6895, 528], + [6865, 505], + [6853, 550], + [6911, 552], + [6940, 577], + ], + ], + [[[6963, 721], [6969, 703], [6950, 692], [6917, 710], [6963, 721]]], + [[[6760, 718], [6700, 711], [6718, 764], [6750, 754], [6760, 718]]], + [ + [ + [5744, 264], + [5783, 255], + [5827, 318], + [5801, 361], + [5871, 401], + [5896, 516], + [5934, 546], + [5929, 587], + [5950, 612], + [5928, 589], + [5909, 607], + [5912, 616], + [5923, 633], + [5943, 639], + [5999, 661], + [6044, 658], + [6105, 737], + [6162, 765], + [6216, 761], + [6280, 788], + [6278, 832], + [6313, 844], + [6357, 845], + [6390, 877], + [6462, 882], + [6547, 945], + [6645, 975], + [6671, 941], + [6714, 926], + [6735, 946], + [6831, 918], + [6884, 953], + [6956, 965], + [7004, 992], + [7003, 1040], + [6967, 1083], + [7026, 1104], + [7089, 1088], + [7113, 1024], + [7056, 973], + [7081, 892], + [7028, 811], + [7001, 837], + [6909, 825], + [6792, 840], + [6750, 785], + [6693, 803], + [6656, 791], + [6651, 758], + [6606, 719], + [6537, 721], + [6516, 691], + [6698, 573], + [6683, 554], + [6645, 591], + [6585, 607], + [6539, 585], + [6563, 553], + [6615, 538], + [6624, 490], + [6572, 514], + [6539, 553], + [6475, 558], + [6465, 536], + [6562, 466], + [6484, 465], + [6455, 542], + [6391, 557], + [6335, 600], + [6368, 621], + [6348, 644], + [6284, 580], + [6307, 555], + [6293, 492], + [6303, 460], + [6382, 390], + [6406, 343], + [6451, 320], + [6522, 239], + [6421, 274], + [6413, 212], + [6469, 187], + [6414, 128], + [6373, 132], + [6413, 100], + [6482, 95], + [6494, 74], + [6546, 82], + [6561, 42], + [6600, 46], + [6643, 14], + [6710, 7], + [6747, -23], + [6728, -40], + [6771, -143], + [6765, -175], + [6694, -139], + [6639, -80], + [6561, -117], + [6518, -163], + [6560, -167], + [6567, -224], + [6600, -217], + [6659, -253], + [6559, -304], + [6568, -274], + [6468, -264], + [6483, -304], + [6544, -376], + [6599, -470], + [6582, -493], + [6638, -568], + [6536, -516], + [6516, -478], + [6473, -492], + [6460, -548], + [6474, -588], + [6434, -581], + [6425, -525], + [6361, -440], + [6312, -460], + [6310, -537], + [6267, -521], + [6258, -476], + [6217, -423], + [6238, -381], + [6193, -305], + [6081, -240], + [6125, -148], + [6122, -119], + [6178, -130], + [6208, -82], + [6250, -63], + [6320, -96], + [6430, -113], + [6480, -142], + [6472, -115], + [6552, -79], + [6528, -63], + [6420, -38], + [6387, -49], + [6346, -11], + [6348, -44], + [6254, -40], + [6153, -91], + [6112, -64], + [6067, -102], + [6041, -37], + [5962, 66], + [6037, 101], + [5958, 121], + [5942, 72], + [5926, 106], + [5844, 158], + [5781, 221], + [5788, 250], + [5744, 264], + ], + ], + [[[5953, -97], [5966, -114], [5953, -98], [5953, -97], [5953, -97]]], + [ + [ + [6631, 30], + [6624, 62], + [6509, 131], + [6453, 139], + [6520, 197], + [6560, 161], + [6601, 132], + [6666, 117], + [6715, 125], + [6761, 87], + [6757, 52], + [6808, -13], + [6863, -2], + [6866, -56], + [6825, -66], + [6725, 22], + [6724, 42], + [6631, 30], + ], + ], + [ + [ + [7250, -790], + [7315, -764], + [7313, -812], + [7342, -826], + [7437, -752], + [7449, -825], + [7297, -867], + [7180, -916], + [7094, -936], + [7076, -889], + [6997, -876], + [6845, -893], + [6778, -888], + [6780, -790], + [6813, -814], + [6809, -762], + [6836, -803], + [6921, -771], + [6955, -832], + [7059, -791], + [7119, -780], + [7144, -796], + [7250, -790], + ], + ], + [[[5953, -97], [5936, -73], [5949, -66], [5953, -97], [5953, -97]]], + ], + }, + }, + { + type: 'Feature', + id: 'LT', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.6, + 'hc-middle-y': 0.49, + 'hc-key': 'lt', + 'hc-a2': 'LT', + name: 'Lithuania', + labelrank: '5', + 'country-abbrev': 'Lith.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'LTU', + 'iso-a2': 'LT', + 'woe-id': '23424875', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [5326, 4758], + [5306, 4834], + [5272, 4895], + [5254, 4987], + [5276, 4994], + [5291, 5038], + [5404, 5112], + [5500, 5110], + [5529, 5132], + [5570, 5111], + [5594, 5133], + [5661, 5141], + [5729, 5127], + [5783, 5137], + [5842, 5202], + [5891, 5137], + [5981, 5144], + [5992, 5129], + [6081, 5080], + [6104, 5054], + [6159, 5044], + [6157, 4946], + [6218, 4942], + [6193, 4890], + [6147, 4887], + [6131, 4831], + [6080, 4791], + [6092, 4704], + [6071, 4634], + [6100, 4633], + [6118, 4585], + [6086, 4576], + [6065, 4618], + [6026, 4598], + [6009, 4557], + [5972, 4554], + [5971, 4502], + [5952, 4504], + [5908, 4464], + [5875, 4477], + [5784, 4444], + [5756, 4450], + [5735, 4513], + [5628, 4561], + [5615, 4546], + [5595, 4571], + [5594, 4700], + [5549, 4740], + [5472, 4718], + [5326, 4758], + ], + ], + [ + [ + [5268, 4759], + [5285, 4824], + [5279, 4758], + [5279, 4758], + [5268, 4759], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'SI', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.38, + 'hc-middle-y': 0.62, + 'hc-key': 'si', + 'hc-a2': 'SI', + name: 'Slovenia', + labelrank: '6', + 'country-abbrev': 'Slo.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'SVN', + 'iso-a2': 'SI', + 'woe-id': '23424945', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [4209, 1816], + [4208, 1830], + [4232, 1848], + [4269, 1861], + [4203, 1909], + [4209, 1955], + [4176, 1965], + [4209, 2017], + [4152, 2046], + [4216, 2116], + [4358, 2100], + [4386, 2084], + [4444, 2153], + [4485, 2170], + [4565, 2165], + [4597, 2198], + [4673, 2197], + [4685, 2247], + [4720, 2250], + [4777, 2150], + [4722, 2143], + [4734, 2110], + [4614, 2053], + [4602, 2023], + [4625, 2002], + [4624, 1943], + [4581, 1934], + [4542, 1900], + [4570, 1837], + [4525, 1818], + [4428, 1842], + [4403, 1876], + [4369, 1822], + [4286, 1828], + [4271, 1801], + [4209, 1816], + ], + ], + }, + }, + { + type: 'Feature', + id: 'BA', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.49, + 'hc-middle-y': 0.42, + 'hc-key': 'ba', + 'hc-a2': 'BA', + name: 'Bosnia and Herzegovina', + labelrank: '5', + 'country-abbrev': 'B.H.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'BIH', + 'iso-a2': 'BA', + 'woe-id': '23424761', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [5115, 1130], + [5093, 1141], + [5098, 1143], + [5095, 1184], + [5062, 1201], + [5019, 1256], + [5010, 1291], + [4976, 1298], + [4890, 1365], + [4881, 1385], + [4775, 1482], + [4747, 1571], + [4668, 1659], + [4662, 1750], + [4705, 1771], + [4754, 1721], + [4781, 1716], + [4805, 1774], + [4867, 1774], + [4893, 1807], + [4950, 1773], + [4966, 1787], + [5030, 1773], + [5051, 1788], + [5085, 1763], + [5120, 1791], + [5164, 1799], + [5229, 1777], + [5259, 1787], + [5308, 1729], + [5333, 1734], + [5363, 1755], + [5405, 1749], + [5402, 1704], + [5369, 1637], + [5388, 1571], + [5489, 1511], + [5411, 1478], + [5467, 1428], + [5478, 1370], + [5448, 1380], + [5419, 1354], + [5360, 1334], + [5401, 1286], + [5364, 1294], + [5321, 1259], + [5320, 1192], + [5282, 1179], + [5293, 1114], + [5315, 1079], + [5293, 1053], + [5161, 1114], + [5115, 1130], + ], + ], + }, + }, + { + type: 'Feature', + id: 'MC', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.47, + 'hc-middle-y': 0.63, + 'hc-key': 'mc', + 'hc-a2': 'MC', + name: 'Monaco', + labelrank: '6', + 'country-abbrev': 'Mco.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'MCO', + 'iso-a2': 'MC', + 'woe-id': '23424892', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [2937, 1301], + [2930, 1294], + [2922, 1295], + [2931, 1307], + [2937, 1301], + ], + ], + }, + }, + { + type: 'Feature', + id: 'AL', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.3, + 'hc-middle-y': 0.65, + 'hc-key': 'al', + 'hc-a2': 'AL', + name: 'Albania', + labelrank: '6', + 'country-abbrev': 'Alb.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'ALB', + 'iso-a2': 'AL', + 'woe-id': '23424742', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [[[5907, 643], [5905, 642], [5902, 648], [5906, 645], [5907, 643]]], + [ + [ + [5827, 689], + [5837, 642], + [5854, 641], + [5874, 648], + [5902, 648], + [5899, 643], + [5909, 635], + [5909, 634], + [5900, 609], + [5912, 616], + [5909, 607], + [5928, 589], + [5924, 584], + [5929, 587], + [5934, 546], + [5896, 516], + [5871, 401], + [5801, 361], + [5827, 318], + [5783, 255], + [5744, 264], + [5742, 309], + [5697, 364], + [5606, 400], + [5597, 470], + [5552, 520], + [5567, 589], + [5586, 602], + [5563, 670], + [5575, 704], + [5543, 743], + [5572, 801], + [5568, 869], + [5519, 873], + [5511, 904], + [5511, 941], + [5532, 960], + [5508, 1011], + [5560, 1115], + [5593, 1064], + [5642, 1094], + [5686, 1036], + [5749, 1011], + [5782, 938], + [5778, 915], + [5765, 818], + [5792, 778], + [5782, 752], + [5827, 689], + ], + ], + [[[5503, 1000], [5503, 997], [5502, 997], [5503, 1000]]], + ], + }, + }, + { + type: 'Feature', + id: 'CNM', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.66, + 'hc-middle-y': 0.61, + 'hc-key': 'cnm', + 'hc-a2': 'CN', + name: 'Cyprus No Mans Area', + labelrank: '9', + 'country-abbrev': null, + subregion: 'Western Asia', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': '-99', + 'iso-a2': null, + 'woe-id': '-99', + continent: 'Asia', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [9288, -289], + [9288, -289], + [9291, -290], + [9270, -299], + [9261, -299], + [9262, -296], + [9276, -291], + [9288, -289], + ], + ], + [ + [ + [8944, -370], + [8947, -367], + [8947, -367], + [8952, -370], + [8956, -361], + [8958, -360], + [8960, -360], + [8955, -373], + [8944, -370], + ], + ], + [ + [ + [8968, -358], + [8968, -358], + [8973, -358], + [9012, -377], + [9084, -318], + [9132, -299], + [9160, -323], + [9213, -324], + [9213, -324], + [9219, -325], + [9223, -335], + [9162, -352], + [9139, -309], + [9083, -327], + [9008, -383], + [8968, -358], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'NC', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.59, + 'hc-middle-y': 0.61, + 'hc-key': 'nc', + 'hc-a2': 'NC', + name: 'Northern Cyprus', + labelrank: '6', + 'country-abbrev': 'N. Cy.', + subregion: 'Western Asia', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': '-99', + 'iso-a2': 'NC', + 'woe-id': '-90', + continent: 'Asia', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [9160, -323], + [9132, -299], + [9084, -318], + [9012, -377], + [8973, -358], + [9011, -353], + [9001, -280], + [9126, -260], + [9253, -171], + [9359, -64], + [9360, -79], + [9246, -235], + [9288, -289], + [9276, -291], + [9262, -296], + [9262, -296], + [9233, -318], + [9213, -324], + [9213, -324], + [9160, -323], + ], + ], + [ + [ + [8947, -367], + [8951, -364], + [8956, -361], + [8952, -370], + [8947, -367], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'RS', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.47, + 'hc-middle-y': 0.51, + 'hc-key': 'rs', + 'hc-a2': 'RS', + name: 'Republic of Serbia', + labelrank: '5', + 'country-abbrev': 'Serb.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'SRB', + 'iso-a2': 'RS', + 'woe-id': '-90', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [5333, 1734], + [5332, 1816], + [5399, 1831], + [5390, 1853], + [5313, 1878], + [5308, 1936], + [5265, 2001], + [5272, 2037], + [5302, 2065], + [5342, 2061], + [5393, 2121], + [5468, 2131], + [5533, 2124], + [5557, 2094], + [5657, 2038], + [5663, 1963], + [5714, 1924], + [5826, 1887], + [5805, 1838], + [5841, 1827], + [5814, 1802], + [5881, 1761], + [5954, 1762], + [5997, 1730], + [6036, 1801], + [6113, 1770], + [6059, 1736], + [6116, 1666], + [6105, 1620], + [6067, 1588], + [6066, 1533], + [6118, 1443], + [6229, 1382], + [6192, 1283], + [6146, 1270], + [6144, 1181], + [6170, 1136], + [6140, 1104], + [6119, 1116], + [5976, 1056], + [5999, 1185], + [5913, 1193], + [5912, 1226], + [5882, 1230], + [5837, 1284], + [5780, 1298], + [5772, 1323], + [5728, 1295], + [5747, 1275], + [5690, 1184], + [5685, 1207], + [5636, 1220], + [5590, 1254], + [5522, 1261], + [5419, 1354], + [5448, 1380], + [5478, 1370], + [5467, 1428], + [5411, 1478], + [5489, 1511], + [5388, 1571], + [5369, 1637], + [5402, 1704], + [5405, 1749], + [5363, 1755], + [5333, 1734], + ], + ], + }, + }, + { + type: 'Feature', + id: 'RO', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.45, + 'hc-middle-y': 0.54, + 'hc-key': 'ro', + 'hc-a2': 'RO', + name: 'Romania', + labelrank: '3', + 'country-abbrev': 'Rom.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'ROU', + 'iso-a2': 'RO', + 'woe-id': '23424933', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [6059, 1736], + [6113, 1770], + [6036, 1801], + [5997, 1730], + [5954, 1762], + [5881, 1761], + [5814, 1802], + [5841, 1827], + [5805, 1838], + [5826, 1887], + [5714, 1924], + [5663, 1963], + [5657, 2038], + [5557, 2094], + [5533, 2124], + [5575, 2150], + [5605, 2141], + [5645, 2188], + [5703, 2199], + [5724, 2302], + [5756, 2338], + [5767, 2428], + [5790, 2458], + [5814, 2573], + [5856, 2646], + [5943, 2693], + [5962, 2732], + [6000, 2782], + [6052, 2762], + [6132, 2776], + [6223, 2767], + [6283, 2792], + [6360, 2740], + [6400, 2767], + [6419, 2808], + [6585, 2873], + [6596, 2941], + [6652, 2968], + [6687, 2976], + [6729, 2959], + [6775, 2912], + [6821, 2832], + [6884, 2789], + [6953, 2710], + [7003, 2689], + [7070, 2596], + [7089, 2531], + [7089, 2403], + [7132, 2304], + [7114, 2288], + [7150, 2258], + [7186, 2225], + [7282, 2223], + [7373, 2312], + [7445, 2302], + [7457, 2266], + [7476, 2165], + [7469, 2151], + [7380, 2113], + [7337, 2172], + [7324, 2132], + [7352, 2077], + [7322, 2035], + [7356, 2049], + [7322, 1963], + [7352, 1873], + [7353, 1794], + [7278, 1781], + [7223, 1793], + [7199, 1830], + [7163, 1808], + [7144, 1825], + [7089, 1809], + [7055, 1833], + [7006, 1837], + [6838, 1749], + [6780, 1652], + [6698, 1611], + [6610, 1620], + [6512, 1615], + [6444, 1587], + [6264, 1592], + [6183, 1561], + [6168, 1606], + [6193, 1640], + [6116, 1666], + [6115, 1666], + [6059, 1736], + ], + ], + }, + }, + { + type: 'Feature', + id: 'ME', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.29, + 'hc-middle-y': 0.67, + 'hc-key': 'me', + 'hc-a2': 'ME', + name: 'Montenegro', + labelrank: '6', + 'country-abbrev': 'Mont.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'MNE', + 'iso-a2': 'ME', + 'woe-id': '20069817', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [5642, 1094], + [5593, 1064], + [5560, 1115], + [5508, 1011], + [5505, 1006], + [5503, 1000], + [5502, 997], + [5456, 988], + [5511, 941], + [5511, 904], + [5519, 873], + [5473, 892], + [5463, 922], + [5396, 986], + [5377, 978], + [5344, 1027], + [5311, 1013], + [5298, 1030], + [5293, 1053], + [5315, 1079], + [5293, 1114], + [5282, 1179], + [5320, 1192], + [5321, 1259], + [5364, 1294], + [5401, 1286], + [5360, 1334], + [5419, 1354], + [5522, 1261], + [5590, 1254], + [5636, 1220], + [5685, 1207], + [5690, 1184], + [5626, 1144], + [5642, 1094], + ], + ], + }, + }, + { + type: 'Feature', + id: 'LI', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.62, + 'hc-middle-y': 0.51, + 'hc-key': 'li', + 'hc-a2': 'LI', + name: 'Liechtenstein', + labelrank: '6', + 'country-abbrev': 'Liech.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'LIE', + 'iso-a2': 'LI', + 'woe-id': '23424879', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [3383, 2312], + [3402, 2266], + [3395, 2252], + [3374, 2254], + [3383, 2312], + ], + ], + }, + }, + { + type: 'Feature', + id: 'AT', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.68, + 'hc-middle-y': 0.5, + 'hc-key': 'at', + 'hc-a2': 'AT', + name: 'Austria', + labelrank: '4', + 'country-abbrev': 'Aust.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'AUT', + 'iso-a2': 'AT', + 'woe-id': '23424750', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [3395, 2252], + [3402, 2266], + [3383, 2312], + [3409, 2354], + [3390, 2383], + [3413, 2380], + [3422, 2394], + [3467, 2387], + [3538, 2323], + [3566, 2362], + [3558, 2401], + [3632, 2385], + [3670, 2350], + [3724, 2353], + [3794, 2409], + [3900, 2416], + [3902, 2446], + [3965, 2426], + [4016, 2438], + [4021, 2406], + [4072, 2390], + [4066, 2454], + [4041, 2456], + [4059, 2492], + [4008, 2569], + [4062, 2613], + [4132, 2649], + [4151, 2710], + [4189, 2693], + [4205, 2765], + [4257, 2717], + [4304, 2710], + [4329, 2736], + [4376, 2724], + [4392, 2779], + [4415, 2776], + [4422, 2848], + [4476, 2844], + [4558, 2815], + [4583, 2821], + [4627, 2791], + [4689, 2788], + [4702, 2808], + [4787, 2794], + [4804, 2763], + [4792, 2692], + [4860, 2595], + [4836, 2551], + [4854, 2508], + [4801, 2493], + [4763, 2511], + [4726, 2482], + [4770, 2475], + [4777, 2426], + [4737, 2393], + [4759, 2293], + [4717, 2291], + [4685, 2247], + [4673, 2197], + [4597, 2198], + [4565, 2165], + [4485, 2170], + [4444, 2153], + [4386, 2084], + [4358, 2100], + [4216, 2116], + [4122, 2120], + [3956, 2154], + [3895, 2240], + [3913, 2265], + [3823, 2232], + [3737, 2234], + [3694, 2212], + [3676, 2170], + [3567, 2197], + [3550, 2234], + [3500, 2191], + [3450, 2218], + [3449, 2240], + [3395, 2252], + ], + ], + }, + }, + { + type: 'Feature', + id: 'SK', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.4, + 'hc-middle-y': 0.46, + 'hc-key': 'sk', + 'hc-a2': 'SK', + name: 'Slovakia', + labelrank: '6', + 'country-abbrev': 'Svk.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'SVK', + 'iso-a2': 'SK', + 'woe-id': '23424877', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [4860, 2595], + [4792, 2692], + [4804, 2763], + [4839, 2840], + [4910, 2834], + [4968, 2872], + [5005, 2912], + [5019, 2981], + [5077, 3047], + [5131, 3062], + [5160, 3030], + [5198, 3039], + [5241, 3102], + [5283, 3050], + [5310, 3051], + [5313, 2997], + [5371, 2995], + [5381, 3035], + [5411, 3063], + [5481, 3078], + [5533, 3055], + [5545, 3087], + [5585, 3108], + [5692, 3104], + [5736, 3063], + [5841, 3040], + [5819, 2970], + [5819, 2928], + [5793, 2890], + [5798, 2837], + [5724, 2806], + [5656, 2860], + [5600, 2830], + [5535, 2843], + [5479, 2822], + [5459, 2748], + [5381, 2693], + [5328, 2714], + [5305, 2677], + [5184, 2641], + [5168, 2619], + [5187, 2581], + [5078, 2545], + [4999, 2535], + [4947, 2553], + [4897, 2596], + [4860, 2595], + ], + ], + }, + }, + { + type: 'Feature', + id: 'HU', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.45, + 'hc-middle-y': 0.54, + 'hc-key': 'hu', + 'hc-a2': 'HU', + name: 'Hungary', + labelrank: '5', + 'country-abbrev': 'Hun.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'HUN', + 'iso-a2': 'HU', + 'woe-id': '23424844', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [4777, 2150], + [4720, 2250], + [4685, 2247], + [4717, 2291], + [4759, 2293], + [4737, 2393], + [4777, 2426], + [4770, 2475], + [4726, 2482], + [4763, 2511], + [4801, 2493], + [4854, 2508], + [4836, 2551], + [4860, 2595], + [4897, 2596], + [4947, 2553], + [4999, 2535], + [5078, 2545], + [5187, 2581], + [5168, 2619], + [5184, 2641], + [5305, 2677], + [5328, 2714], + [5381, 2693], + [5459, 2748], + [5479, 2822], + [5535, 2843], + [5600, 2830], + [5656, 2860], + [5724, 2806], + [5798, 2837], + [5824, 2842], + [5848, 2799], + [5872, 2803], + [5901, 2766], + [5928, 2776], + [5962, 2732], + [5943, 2693], + [5856, 2646], + [5814, 2573], + [5790, 2458], + [5767, 2428], + [5756, 2338], + [5724, 2302], + [5703, 2199], + [5645, 2188], + [5605, 2141], + [5575, 2150], + [5533, 2124], + [5468, 2131], + [5393, 2121], + [5342, 2061], + [5302, 2065], + [5272, 2037], + [5227, 2026], + [5180, 1971], + [5138, 1979], + [5070, 1968], + [5008, 2009], + [4959, 2009], + [4924, 2054], + [4877, 2075], + [4851, 2116], + [4777, 2150], + ], + ], + }, + }, + { + type: 'Feature', + id: 'AD', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.48, + 'hc-middle-y': 0.52, + 'hc-key': 'ad', + 'hc-a2': 'AD', + name: 'Andorra', + labelrank: '6', + 'country-abbrev': 'And.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'AND', + 'iso-a2': 'AD', + 'woe-id': '23424744', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [1691, 1033], + [1645, 1016], + [1634, 1067], + [1697, 1064], + [1691, 1033], + ], + ], + }, + }, + { + type: 'Feature', + id: 'LU', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.5, + 'hc-middle-y': 0.58, + 'hc-key': 'lu', + 'hc-a2': 'LU', + name: 'Luxembourg', + labelrank: '6', + 'country-abbrev': 'Lux.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'LUX', + 'iso-a2': 'LU', + 'woe-id': '23424881', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [2791, 2962], + [2752, 2975], + [2719, 2961], + [2688, 2991], + [2708, 3020], + [2680, 3091], + [2737, 3172], + [2759, 3155], + [2774, 3087], + [2825, 3058], + [2791, 2962], + ], + ], + }, + }, + { + type: 'Feature', + id: 'CH', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.51, + 'hc-middle-y': 0.49, + 'hc-key': 'ch', + 'hc-a2': 'CH', + name: 'Switzerland', + labelrank: '4', + 'country-abbrev': 'Switz.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'CHE', + 'iso-a2': 'CH', + 'woe-id': '23424957', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [3006, 2412], + [3174, 2408], + [3164, 2431], + [3205, 2468], + [3264, 2425], + [3318, 2430], + [3319, 2429], + [3321, 2426], + [3321, 2426], + [3378, 2377], + [3390, 2383], + [3409, 2354], + [3383, 2312], + [3374, 2254], + [3395, 2252], + [3449, 2240], + [3450, 2218], + [3500, 2191], + [3550, 2234], + [3567, 2197], + [3551, 2141], + [3562, 2101], + [3495, 2121], + [3486, 2071], + [3509, 2022], + [3486, 2010], + [3470, 2049], + [3389, 2031], + [3365, 2089], + [3330, 2087], + [3331, 2036], + [3272, 1939], + [3287, 1913], + [3255, 1898], + [3243, 1967], + [3196, 1984], + [3162, 2022], + [3166, 2075], + [3091, 2025], + [3097, 1988], + [3039, 1928], + [2981, 1950], + [2908, 1923], + [2876, 1937], + [2844, 1995], + [2835, 2080], + [2852, 2092], + [2803, 2112], + [2741, 2096], + [2720, 2051], + [2731, 2035], + [2664, 2007], + [2704, 2071], + [2688, 2089], + [2706, 2139], + [2768, 2184], + [2773, 2237], + [2805, 2247], + [2897, 2346], + [2862, 2351], + [2892, 2392], + [2964, 2369], + [3006, 2412], + [3006, 2412], + ], + ], + }, + }, + { + type: 'Feature', + id: 'BE', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.53, + 'hc-middle-y': 0.37, + 'hc-key': 'be', + 'hc-a2': 'BE', + name: 'Belgium', + labelrank: '2', + 'country-abbrev': 'Belg.', + subregion: 'Western Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'BEL', + 'iso-a2': 'BE', + 'woe-id': '23424757', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [2759, 3155], + [2737, 3172], + [2680, 3091], + [2708, 3020], + [2688, 2991], + [2629, 2982], + [2536, 3076], + [2519, 3074], + [2510, 3129], + [2529, 3175], + [2492, 3162], + [2486, 3135], + [2443, 3122], + [2390, 3138], + [2408, 3217], + [2377, 3244], + [2310, 3245], + [2310, 3281], + [2244, 3311], + [2227, 3382], + [2161, 3376], + [2129, 3413], + [2124, 3485], + [2239, 3543], + [2280, 3553], + [2285, 3515], + [2330, 3523], + [2380, 3495], + [2437, 3537], + [2452, 3509], + [2444, 3537], + [2467, 3530], + [2486, 3564], + [2511, 3546], + [2537, 3566], + [2561, 3534], + [2581, 3557], + [2614, 3492], + [2660, 3498], + [2723, 3456], + [2690, 3344], + [2746, 3338], + [2778, 3297], + [2779, 3261], + [2804, 3257], + [2809, 3209], + [2765, 3182], + [2759, 3155], + ], + ], + }, + }, + { + type: 'Feature', + id: 'KV', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.89, + 'hc-middle-y': 0.48, + 'hc-key': 'kv', + 'hc-a2': 'KV', + name: 'Kosovo', + labelrank: '6', + 'country-abbrev': 'Kos.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': '-99', + 'iso-a2': 'KV', + 'woe-id': '-90', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [5778, 915], + [5782, 938], + [5749, 1011], + [5686, 1036], + [5642, 1094], + [5626, 1144], + [5690, 1184], + [5747, 1275], + [5728, 1295], + [5772, 1323], + [5780, 1298], + [5837, 1284], + [5882, 1230], + [5912, 1226], + [5913, 1193], + [5999, 1185], + [5976, 1056], + [5945, 1049], + [5913, 1002], + [5878, 1026], + [5813, 977], + [5816, 931], + [5778, 915], + ], + ], + }, + }, + { + type: 'Feature', + id: 'PL', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.56, + 'hc-middle-y': 0.5, + 'hc-key': 'pl', + 'hc-a2': 'PL', + name: 'Poland', + labelrank: '3', + 'country-abbrev': 'Pol.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'POL', + 'iso-a2': 'PL', + 'woe-id': '23424923', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [5615, 4546], + [5628, 4561], + [5735, 4513], + [5756, 4450], + [5791, 4360], + [5868, 4241], + [5895, 4126], + [5890, 4104], + [5817, 4042], + [5789, 3973], + [5882, 3930], + [5894, 3906], + [5886, 3834], + [5907, 3769], + [5922, 3719], + [5976, 3670], + [5989, 3635], + [6038, 3595], + [6010, 3586], + [6051, 3510], + [6035, 3467], + [5994, 3455], + [5900, 3310], + [5837, 3173], + [5861, 3130], + [5867, 3073], + [5904, 3029], + [5841, 3040], + [5736, 3063], + [5692, 3104], + [5585, 3108], + [5545, 3087], + [5533, 3055], + [5481, 3078], + [5411, 3063], + [5381, 3035], + [5371, 2995], + [5313, 2997], + [5310, 3051], + [5283, 3050], + [5241, 3102], + [5198, 3039], + [5160, 3030], + [5131, 3062], + [5114, 3108], + [5088, 3112], + [5067, 3169], + [4967, 3187], + [4931, 3173], + [4880, 3222], + [4880, 3250], + [4830, 3248], + [4797, 3277], + [4739, 3283], + [4762, 3230], + [4718, 3186], + [4643, 3260], + [4615, 3272], + [4648, 3301], + [4636, 3338], + [4591, 3335], + [4470, 3369], + [4453, 3363], + [4435, 3411], + [4378, 3418], + [4385, 3380], + [4354, 3378], + [4385, 3489], + [4367, 3549], + [4327, 3566], + [4322, 3611], + [4295, 3647], + [4322, 3727], + [4307, 3777], + [4276, 3824], + [4292, 3870], + [4196, 3943], + [4198, 3974], + [4231, 4002], + [4238, 4067], + [4206, 4188], + [4249, 4181], + [4266, 4236], + [4192, 4239], + [4187, 4247], + [4193, 4256], + [4220, 4252], + [4288, 4290], + [4511, 4381], + [4576, 4464], + [4637, 4484], + [4699, 4531], + [4787, 4562], + [4858, 4575], + [4910, 4497], + [4917, 4464], + [4989, 4447], + [5048, 4464], + [5048, 4464], + [5027, 4450], + [5056, 4436], + [5111, 4489], + [5604, 4540], + [5615, 4546], + ], + ], + [ + [ + [5086, 4492], + [5088, 4491], + [5060, 4472], + [5060, 4472], + [5086, 4492], + ], + ], + [ + [ + [5048, 4464], + [5060, 4472], + [5060, 4472], + [5050, 4465], + [5048, 4464], + [5048, 4464], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'MK', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.49, + 'hc-middle-y': 0.49, + 'hc-key': 'mk', + 'hc-a2': 'MK', + name: 'Macedonia', + labelrank: '6', + 'country-abbrev': 'Mkd.', + subregion: 'Southern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'MKD', + 'iso-a2': 'MK', + 'woe-id': '23424890', + continent: 'Europe', + }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [[[5909, 635], [5910, 635], [5909, 634], [5909, 635]]], + [ + [ + [6140, 1104], + [6189, 1058], + [6262, 1037], + [6313, 957], + [6303, 916], + [6313, 844], + [6278, 832], + [6280, 788], + [6216, 761], + [6162, 765], + [6105, 737], + [6044, 658], + [5999, 661], + [5943, 639], + [5902, 680], + [5907, 643], + [5906, 645], + [5902, 648], + [5902, 648], + [5874, 648], + [5854, 641], + [5866, 703], + [5827, 689], + [5782, 752], + [5792, 778], + [5765, 818], + [5778, 915], + [5816, 931], + [5813, 977], + [5878, 1026], + [5913, 1002], + [5945, 1049], + [5976, 1056], + [6119, 1116], + [6140, 1104], + ], + ], + ], + }, + }, + { + type: 'Feature', + id: 'LV', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.68, + 'hc-middle-y': 0.47, + 'hc-key': 'lv', + 'hc-a2': 'LV', + name: 'Latvia', + labelrank: '5', + 'country-abbrev': 'Lat.', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'LVA', + 'iso-a2': 'LV', + 'woe-id': '23424874', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [6371, 5238], + [6337, 5217], + [6307, 5156], + [6308, 5118], + [6209, 5104], + [6192, 5064], + [6159, 5044], + [6104, 5054], + [6081, 5080], + [5992, 5129], + [5981, 5144], + [5891, 5137], + [5842, 5202], + [5783, 5137], + [5729, 5127], + [5661, 5141], + [5594, 5133], + [5570, 5111], + [5529, 5132], + [5500, 5110], + [5404, 5112], + [5291, 5038], + [5276, 4994], + [5254, 4987], + [5233, 5037], + [5222, 5208], + [5266, 5271], + [5258, 5343], + [5288, 5426], + [5332, 5447], + [5414, 5508], + [5433, 5460], + [5517, 5412], + [5549, 5343], + [5626, 5314], + [5663, 5335], + [5716, 5410], + [5714, 5443], + [5669, 5588], + [5699, 5617], + [5801, 5677], + [5861, 5642], + [5926, 5637], + [5934, 5617], + [6022, 5561], + [6071, 5605], + [6151, 5595], + [6177, 5602], + [6181, 5574], + [6241, 5547], + [6248, 5510], + [6240, 5414], + [6262, 5427], + [6284, 5395], + [6340, 5347], + [6371, 5279], + [6371, 5238], + ], + ], + }, + }, + { + type: 'Feature', + id: 'BY', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.48, + 'hc-middle-y': 0.57, + 'hc-key': 'by', + 'hc-a2': 'BY', + name: 'Belarus', + labelrank: '4', + 'country-abbrev': 'Bela.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'BLR', + 'iso-a2': 'BY', + 'woe-id': '23424765', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [6159, 5044], + [6192, 5064], + [6209, 5104], + [6308, 5118], + [6307, 5156], + [6337, 5217], + [6371, 5238], + [6400, 5217], + [6449, 5241], + [6489, 5207], + [6517, 5241], + [6576, 5237], + [6584, 5189], + [6610, 5166], + [6663, 5224], + [6715, 5246], + [6759, 5240], + [6818, 5198], + [6840, 5206], + [6861, 5155], + [6852, 5115], + [6907, 5053], + [6884, 5017], + [6889, 4976], + [6966, 4950], + [6960, 4909], + [6987, 4904], + [7024, 4849], + [7118, 4826], + [7129, 4751], + [7183, 4772], + [7254, 4763], + [7266, 4719], + [7320, 4704], + [7290, 4620], + [7246, 4572], + [7180, 4585], + [7126, 4570], + [7114, 4511], + [7171, 4478], + [7227, 4334], + [7278, 4286], + [7228, 4275], + [7196, 4244], + [7144, 4237], + [7114, 4151], + [7106, 4084], + [7149, 4017], + [7140, 3984], + [7103, 3994], + [7053, 4033], + [7005, 4004], + [6961, 4007], + [6918, 3960], + [6865, 4022], + [6825, 3992], + [6813, 3942], + [6780, 3978], + [6737, 3959], + [6704, 3988], + [6687, 3955], + [6639, 3956], + [6634, 3914], + [6616, 3948], + [6542, 3930], + [6519, 3969], + [6462, 3957], + [6378, 3967], + [6262, 3963], + [6159, 3947], + [6082, 3911], + [6025, 3898], + [6008, 3848], + [5970, 3801], + [5926, 3810], + [5907, 3769], + [5886, 3834], + [5894, 3906], + [5882, 3930], + [5789, 3973], + [5817, 4042], + [5890, 4104], + [5895, 4126], + [5868, 4241], + [5791, 4360], + [5756, 4450], + [5784, 4444], + [5875, 4477], + [5908, 4464], + [5952, 4504], + [5971, 4502], + [5972, 4554], + [6009, 4557], + [6026, 4598], + [6065, 4618], + [6086, 4576], + [6118, 4585], + [6100, 4633], + [6071, 4634], + [6092, 4704], + [6080, 4791], + [6131, 4831], + [6147, 4887], + [6193, 4890], + [6218, 4942], + [6157, 4946], + [6159, 5044], + ], + ], + }, + }, + { + type: 'Feature', + id: 'IS', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.59, + 'hc-middle-y': 0.68, + 'hc-key': 'is', + 'hc-a2': 'IS', + name: 'Iceland', + labelrank: '3', + 'country-abbrev': 'Iceland', + subregion: 'Northern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'ISL', + 'iso-a2': 'IS', + 'woe-id': '23424845', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [23, 7765], + [-31, 7764], + [-42, 7780], + [-86, 7762], + [-64, 7754], + [-101, 7722], + [-209, 7727], + [-271, 7767], + [-318, 7818], + [-367, 7843], + [-388, 7915], + [-443, 7984], + [-435, 8008], + [-470, 7988], + [-517, 8017], + [-554, 8023], + [-582, 8046], + [-631, 8058], + [-594, 8126], + [-590, 8089], + [-546, 8080], + [-466, 8107], + [-487, 8122], + [-442, 8153], + [-483, 8140], + [-497, 8153], + [-458, 8196], + [-397, 8218], + [-488, 8200], + [-493, 8230], + [-466, 8281], + [-602, 8368], + [-616, 8355], + [-649, 8375], + [-644, 8415], + [-596, 8393], + [-542, 8384], + [-532, 8401], + [-506, 8378], + [-474, 8390], + [-473, 8368], + [-433, 8366], + [-370, 8331], + [-345, 8373], + [-387, 8362], + [-439, 8405], + [-423, 8419], + [-332, 8436], + [-332, 8465], + [-371, 8459], + [-387, 8509], + [-413, 8504], + [-455, 8548], + [-556, 8542], + [-556, 8561], + [-613, 8605], + [-567, 8624], + [-538, 8578], + [-544, 8617], + [-519, 8656], + [-469, 8575], + [-488, 8630], + [-478, 8675], + [-451, 8648], + [-466, 8697], + [-455, 8712], + [-432, 8685], + [-436, 8718], + [-402, 8730], + [-378, 8700], + [-381, 8676], + [-344, 8653], + [-330, 8618], + [-337, 8579], + [-309, 8641], + [-344, 8686], + [-333, 8728], + [-353, 8755], + [-336, 8773], + [-272, 8752], + [-251, 8712], + [-259, 8681], + [-233, 8670], + [-219, 8634], + [-229, 8605], + [-208, 8600], + [-197, 8559], + [-209, 8522], + [-269, 8453], + [-246, 8455], + [-266, 8427], + [-254, 8402], + [-265, 8355], + [-201, 8434], + [-164, 8447], + [-167, 8384], + [-110, 8440], + [-96, 8526], + [-87, 8540], + [-45, 8536], + [-48, 8465], + [-33, 8447], + [-39, 8415], + [-19, 8396], + [-2, 8460], + [31, 8489], + [61, 8471], + [71, 8495], + [101, 8497], + [121, 8449], + [109, 8419], + [128, 8404], + [123, 8338], + [146, 8358], + [140, 8395], + [160, 8464], + [199, 8439], + [214, 8374], + [237, 8373], + [282, 8419], + [307, 8391], + [363, 8386], + [381, 8410], + [391, 8477], + [452, 8463], + [449, 8428], + [472, 8410], + [453, 8383], + [483, 8328], + [504, 8358], + [527, 8353], + [569, 8373], + [592, 8356], + [537, 8346], + [535, 8321], + [502, 8309], + [508, 8287], + [554, 8273], + [551, 8240], + [502, 8190], + [566, 8182], + [553, 8170], + [604, 8087], + [624, 8078], + [583, 8028], + [604, 8005], + [589, 7946], + [569, 7931], + [532, 7974], + [550, 7914], + [516, 7902], + [505, 7876], + [444, 7877], + [405, 7807], + [384, 7815], + [347, 7800], + [289, 7807], + [204, 7798], + [142, 7765], + [77, 7752], + [64, 7775], + [45, 7750], + [23, 7765], + ], + ], + }, + }, + { + type: 'Feature', + id: 'MD', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.47, + 'hc-middle-y': 0.3, + 'hc-key': 'md', + 'hc-a2': 'MD', + name: 'Moldova', + labelrank: '6', + 'country-abbrev': 'Mda.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'MDA', + 'iso-a2': 'MD', + 'woe-id': '23424885', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [7150, 2258], + [7114, 2288], + [7132, 2304], + [7089, 2403], + [7089, 2531], + [7070, 2596], + [7003, 2689], + [6953, 2710], + [6884, 2789], + [6821, 2832], + [6775, 2912], + [6729, 2959], + [6687, 2976], + [6652, 2968], + [6685, 3015], + [6749, 3021], + [6803, 3068], + [6850, 3073], + [6926, 3031], + [6981, 3041], + [7015, 3026], + [7070, 3029], + [7112, 2987], + [7141, 3008], + [7170, 2984], + [7174, 2884], + [7248, 2829], + [7273, 2849], + [7303, 2774], + [7302, 2743], + [7384, 2725], + [7404, 2644], + [7448, 2613], + [7405, 2591], + [7369, 2620], + [7355, 2583], + [7319, 2610], + [7279, 2560], + [7258, 2609], + [7222, 2574], + [7235, 2519], + [7256, 2502], + [7259, 2448], + [7223, 2426], + [7228, 2391], + [7190, 2327], + [7203, 2283], + [7150, 2258], + ], + ], + }, + }, + { + type: 'Feature', + id: 'CZ', + properties: { + 'hc-group': 'admin0', + 'hc-middle-x': 0.39, + 'hc-middle-y': 0.51, + 'hc-key': 'cz', + 'hc-a2': 'CZ', + name: 'Czech Republic', + labelrank: '5', + 'country-abbrev': 'Cz. Rep.', + subregion: 'Eastern Europe', + 'region-wb': 'Europe & Central Asia', + 'iso-a3': 'CZE', + 'iso-a2': 'CZ', + 'woe-id': '23424810', + continent: 'Europe', + }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [5131, 3062], + [5077, 3047], + [5019, 2981], + [5005, 2912], + [4968, 2872], + [4910, 2834], + [4839, 2840], + [4804, 2763], + [4787, 2794], + [4702, 2808], + [4689, 2788], + [4627, 2791], + [4583, 2821], + [4558, 2815], + [4476, 2844], + [4422, 2848], + [4415, 2776], + [4392, 2779], + [4376, 2724], + [4329, 2736], + [4304, 2710], + [4257, 2717], + [4205, 2765], + [4163, 2815], + [4139, 2811], + [4079, 2860], + [4043, 2910], + [4004, 2918], + [3923, 3034], + [3947, 3082], + [3894, 3121], + [3860, 3197], + [3900, 3155], + [3940, 3221], + [4030, 3255], + [4070, 3282], + [4109, 3288], + [4136, 3323], + [4269, 3379], + [4256, 3423], + [4293, 3419], + [4318, 3372], + [4354, 3378], + [4385, 3380], + [4378, 3418], + [4435, 3411], + [4453, 3363], + [4470, 3369], + [4591, 3335], + [4636, 3338], + [4648, 3301], + [4615, 3272], + [4643, 3260], + [4718, 3186], + [4762, 3230], + [4739, 3283], + [4797, 3277], + [4830, 3248], + [4880, 3250], + [4880, 3222], + [4931, 3173], + [4967, 3187], + [5067, 3169], + [5088, 3112], + [5114, 3108], + [5131, 3062], + ], + ], + }, + }, + ], +} diff --git a/src/pages/dashboard/components/browser.js b/src/pages/dashboard/components/browser.js new file mode 100644 index 0000000..c17239f --- /dev/null +++ b/src/pages/dashboard/components/browser.js @@ -0,0 +1,51 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Table, Tag } from 'antd' +import { Color } from 'utils' +import styles from './browser.less' + +const status = { + 1: { + color: Color.green, + }, + 2: { + color: Color.red, + }, + 3: { + color: Color.blue, + }, + 4: { + color: Color.yellow, + }, +} + +function Browser({ data }) { + const columns = [ + { + title: 'name', + dataIndex: 'name', + className: styles.name, + }, + { + title: 'percent', + dataIndex: 'percent', + className: styles.percent, + render: (text, it) => {text}%, + }, + ] + return ( + + ) +} + +Browser.propTypes = { + data: PropTypes.array, +} + +export default Browser diff --git a/src/pages/dashboard/components/browser.less b/src/pages/dashboard/components/browser.less new file mode 100644 index 0000000..631ad64 --- /dev/null +++ b/src/pages/dashboard/components/browser.less @@ -0,0 +1,7 @@ +.percent { + text-align: right !important; +} + +.name { + text-align: left !important; +} diff --git a/src/pages/dashboard/components/comments.js b/src/pages/dashboard/components/comments.js new file mode 100644 index 0000000..6403860 --- /dev/null +++ b/src/pages/dashboard/components/comments.js @@ -0,0 +1,68 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Table, Tag } from 'antd' +import { Color } from 'utils' +import styles from './comments.less' + +const status = { + 1: { + color: Color.green, + text: 'APPROVED', + }, + 2: { + color: Color.yellow, + text: 'PENDING', + }, + 3: { + color: Color.red, + text: 'REJECTED', + }, +} + +function Comments({ data }) { + const columns = [ + { + title: 'avatar', + dataIndex: 'avatar', + width: 48, + className: styles.avatarcolumn, + render: text => ( + + ), + }, + { + title: 'content', + dataIndex: 'content', + render: (text, it) => ( +
+
{it.name}
+

{it.content}

+
+ {status[it.status].text} + {it.date} +
+
+ ), + }, + ] + return ( +
+
key < 3)} + /> + + ) +} + +Comments.propTypes = { + data: PropTypes.array, +} + +export default Comments diff --git a/src/pages/dashboard/components/comments.less b/src/pages/dashboard/components/comments.less new file mode 100644 index 0000000..98cbeaf --- /dev/null +++ b/src/pages/dashboard/components/comments.less @@ -0,0 +1,43 @@ +@import '~themes/vars'; + +.comments { + :global .ant-table-thead > tr > th { + background: #fff; + border-bottom: solid 1px @border-color-base; + } + + .avatar { + width: 48px; + height: 48px; + background-position: center; + background-size: cover; + border-radius: 50%; + background: #f8f8f8; + display: inline-block; + } + + .content { + text-align: left; + color: #757575; + } + + .date { + color: #a3a3a3; + line-height: 30px; + } + + .daterow { + display: flex; + justify-content: space-between; + } + + .name { + font-size: 14px; + color: #474747; + text-align: left; + } + + .avatarcolumn { + vertical-align: top; + } +} diff --git a/src/pages/dashboard/components/completed.js b/src/pages/dashboard/components/completed.js new file mode 100644 index 0000000..02ad904 --- /dev/null +++ b/src/pages/dashboard/components/completed.js @@ -0,0 +1,109 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import { Color } from 'utils' +import { + AreaChart, + Area, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, + ResponsiveContainer, +} from 'recharts' +import styles from './completed.less' + +function Completed({ data }) { + return ( +
+
TEAM TOTAL COMPLETED
+ + + { + const { payload } = prop + return ( +
    + {payload.map((item, key) => ( +
  • + + {item.value} +
  • + ))} +
+ ) + }} + /> + + + + { + const list = content.payload.map((item, key) => ( +
  • + + {`${item.name}:${item.value}`} +
  • + )) + return ( +
    +

    {content.label}

    + {content.payload &&
      {list}
    } +
    + ) + }} + /> + + +
    +
    +
    + ) +} + +Completed.propTypes = { + data: PropTypes.array, +} + +export default Completed diff --git a/src/pages/dashboard/components/completed.less b/src/pages/dashboard/components/completed.less new file mode 100644 index 0000000..b334092 --- /dev/null +++ b/src/pages/dashboard/components/completed.less @@ -0,0 +1,49 @@ +@import '~themes/vars'; + +.sales { + .title { + margin-left: 32px; + font-size: 16px; + } +} + +.radiusdot { + width: 12px; + height: 12px; + margin-right: 8px; + border-radius: 50%; + display: inline-block; +} + +.legend { + text-align: right; + color: #999; + font-size: 14px; + + li { + height: 48px; + line-height: 48px; + display: inline-block; + + & + li { + margin-left: 24px; + } + } +} + +.tooltip { + background: #fff; + padding: 20px; + font-size: 14px; + + .tiptitle { + font-weight: 700; + font-size: 16px; + margin-bottom: 8px; + } + + .tipitem { + height: 32px; + line-height: 32px; + } +} diff --git a/src/pages/dashboard/components/cpu.js b/src/pages/dashboard/components/cpu.js new file mode 100644 index 0000000..3561555 --- /dev/null +++ b/src/pages/dashboard/components/cpu.js @@ -0,0 +1,79 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Color } from 'utils' +import CountUp from 'react-countup' +import { + LineChart, + Line, + XAxis, + YAxis, + CartesianGrid, + ResponsiveContainer, +} from 'recharts' +import styles from './cpu.less' + +const countUpProps = { + start: 0, + duration: 2.75, + useEasing: true, + useGrouping: true, + separator: ',', +} + +function Cpu({ usage = 0, space = 0, cpu = 0, data }) { + return ( +
    +
    +
    +

    usage

    +

    + +

    +
    +
    +

    space

    +

    + +

    +
    +
    +

    cpu

    +

    + +

    +
    +
    + + + + + + + + +
    + ) +} + +Cpu.propTypes = { + data: PropTypes.array, + usage: PropTypes.number, + space: PropTypes.number, + cpu: PropTypes.number, +} + +export default Cpu diff --git a/src/pages/dashboard/components/cpu.less b/src/pages/dashboard/components/cpu.less new file mode 100644 index 0000000..d23163b --- /dev/null +++ b/src/pages/dashboard/components/cpu.less @@ -0,0 +1,40 @@ +.cpu { + .number { + display: flex; + height: 64px; + justify-content: space-between; + margin-bottom: 32px; + + .item { + text-align: center; + height: 64px; + width: 100%; + position: relative; + + & + .item { + &::before { + content: ''; + display: block; + width: 1px; + height: 40px; + position: absolute; + background: #f5f5f5; + top: 12px; + } + } + + p { + color: #757575; + + &:first-child { + font-size: 16px; + } + + &:last-child { + font-size: 20px; + font-weight: 700; + } + } + } + } +} diff --git a/src/pages/dashboard/components/index.js b/src/pages/dashboard/components/index.js new file mode 100644 index 0000000..a3d2993 --- /dev/null +++ b/src/pages/dashboard/components/index.js @@ -0,0 +1,23 @@ +import NumberCard from './numberCard' +import Quote from './quote' +import Sales from './sales' +import Weather from './weather' +import RecentSales from './recentSales' +import Comments from './comments' +import Completed from './completed' +import Browser from './browser' +import Cpu from './cpu' +import User from './user' + +export { + NumberCard, + Quote, + Sales, + Weather, + RecentSales, + Comments, + Completed, + Browser, + Cpu, + User, +} diff --git a/src/pages/dashboard/components/numberCard.js b/src/pages/dashboard/components/numberCard.js new file mode 100644 index 0000000..dbab616 --- /dev/null +++ b/src/pages/dashboard/components/numberCard.js @@ -0,0 +1,45 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Card } from 'antd' +import CountUp from 'react-countup' +import iconMap from 'utils/iconMap' +import styles from './numberCard.less' + + +function NumberCard({ icon, color, title, number, countUp }) { + return ( + + + {iconMap[icon]} + +
    +

    {title || 'No Title'}

    +

    + +

    +
    +
    + ) +} + +NumberCard.propTypes = { + icon: PropTypes.string, + color: PropTypes.string, + title: PropTypes.string, + number: PropTypes.number, + countUp: PropTypes.object, +} + +export default NumberCard diff --git a/src/pages/dashboard/components/numberCard.less b/src/pages/dashboard/components/numberCard.less new file mode 100644 index 0000000..237d3bf --- /dev/null +++ b/src/pages/dashboard/components/numberCard.less @@ -0,0 +1,33 @@ +@import '~themes/vars'; + +.numberCard { + padding: 32px; + margin-bottom: 24px; + cursor: pointer; + + .iconWarp { + font-size: 54px; + float: left; + } + + .content { + width: 100%; + padding-left: 78px; + + .title { + line-height: 16px; + font-size: 16px; + margin-bottom: 8px; + height: 16px; + .text-overflow(); + } + + .number { + line-height: 32px; + font-size: 24px; + height: 32px; + .text-overflow(); + margin-bottom: 0; + } + } +} diff --git a/src/pages/dashboard/components/quote.js b/src/pages/dashboard/components/quote.js new file mode 100644 index 0000000..751a65d --- /dev/null +++ b/src/pages/dashboard/components/quote.js @@ -0,0 +1,30 @@ +import React from 'react' +import PropTypes from 'prop-types' +import styles from './quote.less' + +function Quote({ name, content, title, avatar }) { + return ( +
    +
    {content}
    +
    +
    +

    -{name}-

    +

    {title}

    +
    +
    +
    +
    + ) +} + +Quote.propTypes = { + name: PropTypes.string, + content: PropTypes.string, + title: PropTypes.string, + avatar: PropTypes.string, +} + +export default Quote diff --git a/src/pages/dashboard/components/quote.less b/src/pages/dashboard/components/quote.less new file mode 100644 index 0000000..18e8d92 --- /dev/null +++ b/src/pages/dashboard/components/quote.less @@ -0,0 +1,52 @@ +@import '~themes/vars'; + +.quote { + color: #fff; + height: 100%; + width: 100%; + padding: 24px; + font-size: 16px; + font-weight: 700; + + .inner { + text-overflow: ellipsis; + word-wrap: normal; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; + overflow: hidden; + text-indent: 24px; + } + + .footer { + position: relative; + margin-top: 14px; + + .description { + width: 100%; + + p { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-right: 64px; + text-align: right; + + &:last-child { + font-weight: 100; + } + } + } + + .avatar { + width: 48px; + height: 48px; + background-position: center; + background-size: cover; + border-radius: 50%; + position: absolute; + right: 0; + top: 0; + } + } +} diff --git a/src/pages/dashboard/components/recentSales.js b/src/pages/dashboard/components/recentSales.js new file mode 100644 index 0000000..01907dc --- /dev/null +++ b/src/pages/dashboard/components/recentSales.js @@ -0,0 +1,67 @@ +import React from 'react' +import moment from 'moment' +import PropTypes from 'prop-types' +import { Table, Tag } from 'antd' +import { Color } from 'utils' +import styles from './recentSales.less' + +const status = { + 1: { + color: Color.green, + text: 'SALE', + }, + 2: { + color: Color.yellow, + text: 'REJECT', + }, + 3: { + color: Color.red, + text: 'TAX', + }, + 4: { + color: Color.blue, + text: 'EXTENDED', + }, +} + +function RecentSales({ data }) { + const columns = [ + { + title: 'NAME', + dataIndex: 'name', + }, + { + title: 'STATUS', + dataIndex: 'status', + render: text => {status[text].text}, + }, + { + title: 'DATE', + dataIndex: 'date', + render: text => moment(text).format('YYYY-MM-DD'), + }, + { + title: 'PRICE', + dataIndex: 'price', + render: (text, it) => ( + ${text} + ), + }, + ] + return ( +
    +
    key < 5)} + /> + + ) +} + +RecentSales.propTypes = { + data: PropTypes.array, +} + +export default RecentSales diff --git a/src/pages/dashboard/components/recentSales.less b/src/pages/dashboard/components/recentSales.less new file mode 100644 index 0000000..9fcb7a2 --- /dev/null +++ b/src/pages/dashboard/components/recentSales.less @@ -0,0 +1,8 @@ +@import '~themes/vars'; + +.recentsales { + :global .ant-table-thead > tr > th { + background: #fff; + border-bottom: solid 1px @border-color-base; + } +} diff --git a/src/pages/dashboard/components/sales.js b/src/pages/dashboard/components/sales.js new file mode 100644 index 0000000..0c6e78d --- /dev/null +++ b/src/pages/dashboard/components/sales.js @@ -0,0 +1,115 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import { Color } from 'utils' +import { + LineChart, + Line, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, + ResponsiveContainer, +} from 'recharts' +import styles from './sales.less' + +function Sales({ data }) { + return ( +
    +
    Yearly Sales
    + + + { + const { payload } = prop + return ( +
      + {payload.map((item, key) => ( +
    • + + {item.value} +
    • + ))} +
    + ) + }} + /> + + + + { + const list = content.payload.map((item, key) => ( +
  • + + {`${item.name}:${item.value}`} +
  • + )) + return ( +
    +

    {content.label}

    + {content.payload &&
      {list}
    } +
    + ) + }} + /> + + + +
    +
    +
    + ) +} + +Sales.propTypes = { + data: PropTypes.array, +} + +export default Sales diff --git a/src/pages/dashboard/components/sales.less b/src/pages/dashboard/components/sales.less new file mode 100644 index 0000000..6d07f21 --- /dev/null +++ b/src/pages/dashboard/components/sales.less @@ -0,0 +1,50 @@ +@import '~themes/vars'; + +.sales { + overflow: hidden; + .title { + margin-left: 32px; + font-size: 16px; + } +} + +.radiusdot { + width: 12px; + height: 12px; + margin-right: 8px; + border-radius: 50%; + display: inline-block; +} + +.legend { + text-align: right; + color: #999; + font-size: 14px; + + li { + height: 48px; + line-height: 48px; + display: inline-block; + + & + li { + margin-left: 24px; + } + } +} + +.tooltip { + background: #fff; + padding: 20px; + font-size: 14px; + + .tiptitle { + font-weight: 700; + font-size: 16px; + margin-bottom: 8px; + } + + .tipitem { + height: 32px; + line-height: 32px; + } +} diff --git a/src/pages/dashboard/components/user-background.png b/src/pages/dashboard/components/user-background.png new file mode 100644 index 0000000000000000000000000000000000000000..5f99e137361588575fe0ac2dde3a5eae17724e90 GIT binary patch literal 51198 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≧K=IIG4<4OR<&-+69qZ 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 literal 0 HcmV?d00001 diff --git a/src/pages/dashboard/components/user.js b/src/pages/dashboard/components/user.js new file mode 100644 index 0000000..c988487 --- /dev/null +++ b/src/pages/dashboard/components/user.js @@ -0,0 +1,55 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Button, Avatar } from 'antd' +import CountUp from 'react-countup' +import { Color } from 'utils' +import styles from './user.less' + +const countUpProps = { + start: 0, + duration: 2.75, + useEasing: true, + useGrouping: true, + separator: ',', +} + +function User({ avatar, username, sales = 0, sold = 0 }) { + return ( +
    +
    +
    + +
    {username}
    +
    +
    +
    +
    +

    EARNING SALES

    +

    + +

    +
    +
    +

    ITEM SOLD

    +

    + +

    +
    +
    +
    + +
    +
    + ) +} + +User.propTypes = { + avatar: PropTypes.string, + username: PropTypes.string, + sales: PropTypes.number, + sold: PropTypes.number, +} + +export default User diff --git a/src/pages/dashboard/components/user.less b/src/pages/dashboard/components/user.less new file mode 100644 index 0000000..2babcc7 --- /dev/null +++ b/src/pages/dashboard/components/user.less @@ -0,0 +1,88 @@ +@import '~themes/vars'; + +.user { + .header { + display: flex; + justify-content: center; + text-align: center; + color: #fff; + height: 200px; + background-size: cover; + align-items: center; + + .headerinner { + z-index: 2; + } + + &::after { + content: ''; + background-image: url('./user-background.png'); + background-size: cover; + position: absolute; + width: 100%; + height: 200px; + left: 0; + top: 0; + opacity: 0.4; + z-index: 1; + } + + .name { + font-size: 16px; + margin-top: 8px; + } + } + + .number { + display: flex; + height: 116px; + justify-content: space-between; + border-bottom: solid 1px #f5f5f5; + + .item { + text-align: center; + height: 116px; + width: 100%; + position: relative; + padding: 30px 0; + + & + .item { + &::before { + content: ''; + display: block; + width: 1px; + height: 116px; + position: absolute; + background: #f5f5f5; + top: 0; + } + } + + p { + color: #757575; + + &:first-child { + font-size: 16px; + } + + &:last-child { + font-size: 20px; + font-weight: 700; + } + } + } + } + + .footer { + height: 116px; + display: flex; + justify-content: center; + align-items: center; + + :global .ant-btn { + color: @purple; + border-color: @purple; + padding: 6px 16px; + } + } +} diff --git a/src/pages/dashboard/components/weather.js b/src/pages/dashboard/components/weather.js new file mode 100644 index 0000000..2cc8d31 --- /dev/null +++ b/src/pages/dashboard/components/weather.js @@ -0,0 +1,39 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Spin } from 'antd' +import styles from './weather.less' + +function Weather({ city, icon, dateTime, temperature, name, loading }) { + return ( + +
    +
    +
    +

    {name}

    +
    +
    +

    {`${temperature}°`}

    +

    + {city},{dateTime} +

    +
    +
    + + ) +} + +Weather.propTypes = { + city: PropTypes.string, + icon: PropTypes.string, + dateTime: PropTypes.string, + temperature: PropTypes.string, + name: PropTypes.string, + loading: PropTypes.bool, +} + +export default Weather diff --git a/src/pages/dashboard/components/weather.less b/src/pages/dashboard/components/weather.less new file mode 100644 index 0000000..a3f0e5b --- /dev/null +++ b/src/pages/dashboard/components/weather.less @@ -0,0 +1,48 @@ +@import '~themes/vars'; + +.weather { + color: #fff; + height: 204px; + padding: 24px; + justify-content: space-between; + display: flex; + font-size: 14px; + + .left { + display: flex; + flex-direction: column; + width: 64px; + padding-top: 55px; + + .icon { + width: 64px; + height: 64px; + background-position: center; + background-size: contain; + } + + p { + margin-top: 16px; + } + } + + .right { + display: flex; + flex-direction: column; + width: 50%; + + .temperature { + font-size: 36px; + text-align: right; + height: 64px; + color: #fff; + } + + .description { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + text-align: right; + } + } +} diff --git a/src/pages/dashboard/index.js b/src/pages/dashboard/index.js new file mode 100644 index 0000000..0fbc129 --- /dev/null +++ b/src/pages/dashboard/index.js @@ -0,0 +1,162 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import { connect } from 'umi' +import { Row, Col, Card } from 'antd' +import { Color } from 'utils' +import { Page, ScrollBar } from 'components' +import { + NumberCard, + Quote, + Sales, + Weather, + RecentSales, + Comments, + Completed, + Browser, + Cpu, + User, +} from './components' +import styles from './index.less' +import store from 'store' + +const bodyStyle = { + bodyStyle: { + height: 432, + background: '#fff', + }, +} + +@connect(({ app, dashboard, loading }) => ({ + dashboard, + loading, +})) +class Dashboard extends PureComponent { + render() { + const userDetail = store.get('user') + const { avatar, username } = userDetail + const { dashboard, loading } = this.props + const { + weather, + sales, + quote, + numbers, + recentSales, + comments, + completed, + browser, + cpu, + user, + } = dashboard + + const numberCards = numbers.map((item, key) => ( +
    + + + )) + + return ( + + + {numberCards} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) + } +} + +Dashboard.propTypes = { + dashboard: PropTypes.object, + loading: PropTypes.object, +} + +export default Dashboard diff --git a/src/pages/dashboard/index.less b/src/pages/dashboard/index.less new file mode 100644 index 0000000..596b1c4 --- /dev/null +++ b/src/pages/dashboard/index.less @@ -0,0 +1,27 @@ +.dashboard { + position: relative; + :global { + .ant-card { + border-radius: 0; + margin-bottom: 24px; + &:hover { + box-shadow: 4px 4px 40px rgba(0, 0, 0, 0.05); + } + } + .ant-card-body { + overflow-x: hidden; + } + } + + .weather { + &:hover { + box-shadow: 4px 4px 40px rgba(143, 201, 251, 0.6); + } + } + + .quote { + &:hover { + box-shadow: 4px 4px 40px rgba(246, 152, 153, 0.6); + } + } +} diff --git a/src/pages/dashboard/model.js b/src/pages/dashboard/model.js new file mode 100644 index 0000000..19ae6a6 --- /dev/null +++ b/src/pages/dashboard/model.js @@ -0,0 +1,75 @@ +import { parse } from 'qs' +import modelExtend from 'dva-model-extend' +import api from 'api' +const { pathToRegexp } = require("path-to-regexp") +import { model } from 'utils/model' + +const { queryDashboard, queryWeather } = api +const avatar = '//cdn.antd-admin.zuiidea.com/bc442cf0cc6f7940dcc567e465048d1a8d634493198c4-sPx5BR_fw236.jpeg' + +export default modelExtend(model, { + namespace: 'dashboard', + state: { + weather: { + city: '深圳', + temperature: '30', + name: '晴', + icon: '//cdn.antd-admin.zuiidea.com/sun.png', + }, + sales: [], + quote: { + avatar, + }, + numbers: [], + recentSales: [], + comments: [], + completed: [], + browser: [], + cpu: {}, + user: { + avatar, + }, + }, + subscriptions: { + setup({ dispatch, history }) { + history.listen(({ pathname }) => { + if ( + pathToRegexp('/dashboard').exec(pathname) || + pathToRegexp('/').exec(pathname) + ) { + dispatch({ type: 'query' }) + dispatch({ type: 'queryWeather' }) + } + }) + }, + }, + effects: { + *query({ payload }, { call, put }) { + const data = yield call(queryDashboard, parse(payload)) + yield put({ + type: 'updateState', + payload: data, + }) + }, + *queryWeather({ payload = {} }, { call, put }) { + payload.location = 'shenzhen' + const result = yield call(queryWeather, payload) + const { success } = result + if (success) { + const data = result.results[0] + const weather = { + city: data.location.name, + temperature: data.now.temperature, + name: data.now.text, + icon: `//cdn.antd-admin.zuiidea.com/web/icons/3d_50/${data.now.code}.png`, + } + yield put({ + type: 'updateState', + payload: { + weather, + }, + }) + } + }, + }, +}) diff --git a/src/pages/dashboard/services/dashboard.js b/src/pages/dashboard/services/dashboard.js new file mode 100644 index 0000000..71e9470 --- /dev/null +++ b/src/pages/dashboard/services/dashboard.js @@ -0,0 +1,12 @@ +import { request, config } from 'utils' + +const { api } = config +const { dashboard } = api + +export function query(params) { + return request({ + url: dashboard, + method: 'get', + data: params, + }) +} diff --git a/src/pages/dashboard/services/weather.js b/src/pages/dashboard/services/weather.js new file mode 100644 index 0000000..a87179e --- /dev/null +++ b/src/pages/dashboard/services/weather.js @@ -0,0 +1,12 @@ +import { request, config } from 'utils' + +const { APIV1 } = config + +export function query(params) { + params.key = 'i7sau1babuzwhycn' + return request({ + url: `${APIV1}/weather/now.json`, + method: 'get', + data: params, + }) +} diff --git a/src/pages/editor/index.js b/src/pages/editor/index.js new file mode 100644 index 0000000..f65bb6a --- /dev/null +++ b/src/pages/editor/index.js @@ -0,0 +1,105 @@ +import { Component } from 'react' +import { Editor, Page } from 'components' +import { convertToRaw } from 'draft-js' +import { Row, Col, Card } from 'antd' +import draftToHtml from 'draftjs-to-html' +import draftToMarkdown from 'draftjs-to-markdown' + +export default class EditorPage extends Component { + constructor(props) { + super(props) + this.state = { + editorContent: null, + } + } + + onEditorStateChange = editorContent => { + this.setState({ + editorContent, + }) + } + + render() { + const { editorContent } = this.state + const colProps = { + lg: 12, + md: 24, + style: { + marginBottom: 32, + } + } + const textareaStyle = { + minHeight: 496, + width: '100%', + background: '#f7f7f7', + borderColor: '#F1F1F1', + padding: '16px 8px' + } + + return ( + + + + + + + + + +