From 23545a6b6d550141ba0edbdd405319b09a660dcd Mon Sep 17 00:00:00 2001 From: 100pah Date: Tue, 16 Jan 2024 04:21:38 +0800 Subject: [PATCH 1/2] feat: change to default ESM package. For developer testing and node usage in customization module scenario. --- build/package.json | 3 +++ dist/package.json | 3 +++ i18n/package.json | 3 +++ package.json | 41 +++++++++++++++++++++++++++++++++++- ssr/client/dist/package.json | 3 +++ test/package.json | 3 +++ theme/package.json | 3 +++ 7 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 build/package.json create mode 100644 dist/package.json create mode 100644 i18n/package.json create mode 100644 ssr/client/dist/package.json create mode 100644 test/package.json create mode 100644 theme/package.json diff --git a/build/package.json b/build/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/build/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file diff --git a/dist/package.json b/dist/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/dist/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file diff --git a/i18n/package.json b/i18n/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/i18n/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file diff --git a/package.json b/package.json index 5155f4eeba..12221897d3 100644 --- a/package.json +++ b/package.json @@ -101,5 +101,44 @@ "terser": "^5.16.1", "ts-jest": "^26.4.3", "typescript": "4.4.3" + }, + "type": "module", + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./index.js", + "require": "./dist/echarts.js" + }, + "./core": "./core.js", + "./core.js": "./core.js", + "./charts": "./charts.js", + "./charts.js": "./charts.js", + "./components": "./components.js", + "./components.js": "./components.js", + "./features": "./features.js", + "./features.js": "./features.js", + "./renderers": "./renderers.js", + "./renderers.js": "./renderers.js", + "./index.blank": "./index.blank.js", + "./index.blank.js": "./index.blank.js", + "./index.common": "./index.common.js", + "./index.common.js": "./index.common.js", + "./index.simple": "./index.simple.js", + "./index.simple.js": "./index.simple.js", + "./index": "./index.js", + "./index.js": "./index.js", + "./extension/dataTool": "./extension/dataTool/index.js", + "./extension/dataTool/index": "./extension/dataTool/index.js", + "./extension/dataTool/index.js": "./extension/dataTool/index.js", + "./extension/bmap/bmap": "./extension/bmap/bmap.js", + "./extension/bmap/bmap.js": "./extension/bmap/bmap.js", + "./lib/echarts": "./lib/echarts.js", + "./lib/echarts.js": "./lib/echarts.js", + "./lib/extension": "./lib/extension.js", + "./lib/extension.js": "./lib/extension.js", + "./*.js": "./*.js", + "./*.ts": "./*.ts", + "./*.json": "./*.json", + "./*": "./*.js" } -} +} \ No newline at end of file diff --git a/ssr/client/dist/package.json b/ssr/client/dist/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/ssr/client/dist/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file diff --git a/test/package.json b/test/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/test/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file diff --git a/theme/package.json b/theme/package.json new file mode 100644 index 0000000000..6a0d2ef2aa --- /dev/null +++ b/theme/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} \ No newline at end of file From abe29f0e76e93a9b662663832cf9a37a9310726a Mon Sep 17 00:00:00 2001 From: 100pah Date: Mon, 22 Jan 2024 12:39:52 +0800 Subject: [PATCH 2/2] [fix] tweak ssr ts type, impl, exports and eslint --- .eslintrc-common.yaml | 2 +- .gitignore | 3 ++ build/pre-publish.js | 21 +++++--- build/template/ssr/client/index.d.ts | 20 +++++++ build/template/ssr/client/index.js | 20 +++++++ package.json | 9 +++- ssr/client/dist/index.js | 73 ++++++++++++------------- ssr/client/dist/index.js.map | 2 +- ssr/client/src/.eslintrc.yaml | 48 +++++++++++++++++ ssr/client/src/index.ts | 80 +++++++++++++++++----------- test/ssr.html | 33 ++++++------ tsconfig.json | 1 + 12 files changed, 216 insertions(+), 96 deletions(-) create mode 100644 build/template/ssr/client/index.d.ts create mode 100644 build/template/ssr/client/index.js create mode 100644 ssr/client/src/.eslintrc.yaml diff --git a/.eslintrc-common.yaml b/.eslintrc-common.yaml index 4ae0d21d48..7eab58ca62 100644 --- a/.eslintrc-common.yaml +++ b/.eslintrc-common.yaml @@ -39,7 +39,7 @@ rules: - "error" prefer-const: 1 no-constant-condition: 0 - comma-dangle: 2 + comma-dangle: 0 no-debugger: 2 no-dupe-keys: 2 no-empty-character-class: 2 diff --git a/.gitignore b/.gitignore index 34c814925f..43197b694e 100644 --- a/.gitignore +++ b/.gitignore @@ -196,6 +196,9 @@ todo /extension-esm /extension /ssr/client/lib +/ssr/client/types +/ssr/client/index.js +/ssr/client/index.d.ts /core.js /core.d.ts /charts.js diff --git a/build/pre-publish.js b/build/pre-publish.js index cd99e65793..9f6b68149d 100644 --- a/build/pre-publish.js +++ b/build/pre-publish.js @@ -75,6 +75,7 @@ const ssrClientGlobby = { }; const ssrClientSrcDir = nodePath.resolve(ecDir, 'ssr/client/src'); const ssrClientESMDir = nodePath.resolve(ecDir, 'ssr/client/lib'); +const ssrClientTypeDir = nodePath.resolve(ecDir, 'ssr/client/types'); const typesDir = nodePath.resolve(ecDir, 'types'); const esmDir = 'lib'; @@ -148,9 +149,10 @@ const compileWorkList = [ logLabel: 'ssr client ts -> js-esm', compilerOptionsOverride: { module: 'ES2015', - declaration: false, + declaration: true, rootDir: ssrClientSrcDir, - outDir: ssrClientESMDir + outDir: ssrClientESMDir, + declarationDir: ssrClientTypeDir }, srcGlobby: ssrClientGlobby, transformOptions: { @@ -372,6 +374,7 @@ async function readFilePaths({patterns, cwd}) { ); } +// Bundle can be used in echarts-examples. async function bundleDTS() { const outDir = nodePath.resolve(__dirname, '../types/dist'); @@ -442,14 +445,16 @@ function readTSConfig() { function generateEntries() { - ['charts', 'components', 'renderers', 'core', 'features'].forEach(entryName => { - if (entryName !== 'option') { - const jsCode = fs.readFileSync(nodePath.join(__dirname, `template/${entryName}.js`), 'utf-8'); - fs.writeFileSync(nodePath.join(__dirname, `../${entryName}.js`), jsCode, 'utf-8'); + ['charts', 'components', 'renderers', 'core', 'features', 'ssr/client/index'].forEach(entryPath => { + if (entryPath !== 'option') { + const jsCode = fs.readFileSync(nodePath.join(__dirname, `template/${entryPath}.js`), 'utf-8'); + fs.writeFileSync(nodePath.join(__dirname, `../${entryPath}.js`), jsCode, 'utf-8'); } - const dtsCode = fs.readFileSync(nodePath.join(__dirname, `/template/${entryName}.d.ts`), 'utf-8'); - fs.writeFileSync(nodePath.join(__dirname, `../${entryName}.d.ts`), dtsCode, 'utf-8'); + // Make the d.ts in the same dir as .js, so that the can be found by tsc. + // package.json "types" in "exports" does not always seam to work. + const dtsCode = fs.readFileSync(nodePath.join(__dirname, `/template/${entryPath}.d.ts`), 'utf-8'); + fs.writeFileSync(nodePath.join(__dirname, `../${entryPath}.d.ts`), dtsCode, 'utf-8'); }); } diff --git a/build/template/ssr/client/index.d.ts b/build/template/ssr/client/index.d.ts new file mode 100644 index 0000000000..33876e9cf5 --- /dev/null +++ b/build/template/ssr/client/index.d.ts @@ -0,0 +1,20 @@ +/* +* 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. +*/ + +export * from './types/index'; diff --git a/build/template/ssr/client/index.js b/build/template/ssr/client/index.js new file mode 100644 index 0000000000..1dd9ed735f --- /dev/null +++ b/build/template/ssr/client/index.js @@ -0,0 +1,20 @@ +/* +* 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. +*/ + +export * from './lib/index.js'; diff --git a/package.json b/package.json index 12221897d3..3fc7aa42c1 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "mktest": "node test/build/mktest.js", "mktest:help": "node test/build/mktest.js -h", "checktype": "tsc --noEmit", - "lint": "npx eslint --cache --cache-location node_modules/.cache/eslint src/**/*.ts extension-src/**/*.ts", + "lint": "npx eslint --cache --cache-location node_modules/.cache/eslint src/**/*.ts ssr/client/src/**/*.ts extension-src/**/*.ts", "lint:fix": "npx eslint --fix src/**/*.ts extension-src/**/*.ts", "lint:dist": "echo 'It might take a while. Please wait ...' && npx jshint --config .jshintrc-dist dist/echarts.js" }, @@ -107,7 +107,7 @@ ".": { "types": "./index.d.ts", "import": "./index.js", - "require": "./dist/echarts.js" + "require": "./index.js" }, "./core": "./core.js", "./core.js": "./core.js", @@ -136,6 +136,11 @@ "./lib/echarts.js": "./lib/echarts.js", "./lib/extension": "./lib/extension.js", "./lib/extension.js": "./lib/extension.js", + "./ssr/client/index": { + "types": "./ssr/client/index.d.ts", + "import": "./ssr/client/index.js", + "require": "./ssr/client/dist/index.js" + }, "./*.js": "./*.js", "./*.ts": "./*.ts", "./*.json": "./*.json", diff --git a/ssr/client/dist/index.js b/ssr/client/dist/index.js index 818242b77c..14166beefc 100644 --- a/ssr/client/dist/index.js +++ b/ssr/client/dist/index.js @@ -48,58 +48,55 @@ */ function hydrate(dom, options) { var svgRoot = dom.querySelector('svg'); - if (!svgRoot) { console.error('No SVG element found in the DOM.'); return; } - - var children = svgRoot.children; - + // const children = svgRoot.children; function getIndex(child, attr) { var index = child.getAttribute(attr); - if (index) { return parseInt(index, 10); } else { - return null; + return undefined; } } - - var events = options.on; - - if (events) { - var _loop_1 = function (eventName) { - if (typeof events[eventName] === 'function') { - var _loop_2 = function (i) { - var child = children[i]; - var type = child.getAttribute('ecmeta_ssr_type'); - var silent = child.getAttribute('ecmeta_silent') === 'true'; - - if (type && !silent) { - child.addEventListener(eventName, function (e) { - events[eventName]({ - type: eventName, - ssrType: type, - seriesIndex: getIndex(child, 'ecmeta_series_index'), - dataIndex: getIndex(child, 'ecmeta_data_index'), - event: e - }); - }); - } - }; - - for (var i = 0; i < children.length; i++) { - _loop_2(i); - } - } - }; - - for (var eventName in events) { - _loop_1(eventName); + var listeners = options.on || {}; + var _loop_1 = function (rawEvtName) { + var eventName = rawEvtName; + if (!listeners.hasOwnProperty(eventName)) { + return "continue"; + } + var listener = listeners[eventName]; + if (!isFunction(listener)) { + return "continue"; } + svgRoot.addEventListener(eventName, function (event) { + var targetEl = event.target; + if (!targetEl || !isFunction(targetEl.getAttribute)) { + return; + } + var type = targetEl.getAttribute('ecmeta_ssr_type'); + var silent = targetEl.getAttribute('ecmeta_silent') === 'true'; + if (!type || silent) { + return; + } + listener({ + type: eventName, + ssrType: type, + seriesIndex: getIndex(targetEl, 'ecmeta_series_index'), + dataIndex: getIndex(targetEl, 'ecmeta_data_index'), + event: event + }); + }); + }; + for (var rawEvtName in listeners) { + _loop_1(rawEvtName); } } + function isFunction(value) { + return typeof value === 'function'; + } exports.hydrate = hydrate; diff --git a/ssr/client/dist/index.js.map b/ssr/client/dist/index.js.map index e4fabbce7b..6d39a9c583 100644 --- a/ssr/client/dist/index.js.map +++ b/ssr/client/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../lib/index.js"],"sourcesContent":["\n/**\n * AUTO-GENERATED FILE. DO NOT MODIFY.\n */\n\n/*\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements. See the NOTICE file\n* distributed with this work for additional information\n* regarding copyright ownership. The ASF licenses this file\n* to you under the Apache License, Version 2.0 (the\n* \"License\"); you may not use this file except in compliance\n* with the License. You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied. See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*/\nexport function hydrate(dom, options) {\n var svgRoot = dom.querySelector('svg');\n\n if (!svgRoot) {\n console.error('No SVG element found in the DOM.');\n return;\n }\n\n var children = svgRoot.children;\n\n function getIndex(child, attr) {\n var index = child.getAttribute(attr);\n\n if (index) {\n return parseInt(index, 10);\n } else {\n return null;\n }\n }\n\n var events = options.on;\n\n if (events) {\n var _loop_1 = function (eventName) {\n if (typeof events[eventName] === 'function') {\n var _loop_2 = function (i) {\n var child = children[i];\n var type = child.getAttribute('ecmeta_ssr_type');\n var silent = child.getAttribute('ecmeta_silent') === 'true';\n\n if (type && !silent) {\n child.addEventListener(eventName, function (e) {\n events[eventName]({\n type: eventName,\n ssrType: type,\n seriesIndex: getIndex(child, 'ecmeta_series_index'),\n dataIndex: getIndex(child, 'ecmeta_data_index'),\n event: e\n });\n });\n }\n };\n\n for (var i = 0; i < children.length; i++) {\n _loop_2(i);\n }\n }\n };\n\n for (var eventName in events) {\n _loop_1(eventName);\n }\n }\n}"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;EACA;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE;EACtC,EAAE,IAAI,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AACzC;EACA,EAAE,IAAI,CAAC,OAAO,EAAE;EAChB,IAAI,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;EACtD,IAAI,OAAO;EACX,GAAG;AACH;EACA,EAAE,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;AAClC;EACA,EAAE,SAAS,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE;EACjC,IAAI,IAAI,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;AACzC;EACA,IAAI,IAAI,KAAK,EAAE;EACf,MAAM,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;EACjC,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,GAAG;AACH;EACA,EAAE,IAAI,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;AAC1B;EACA,EAAE,IAAI,MAAM,EAAE;EACd,IAAI,IAAI,OAAO,GAAG,UAAU,SAAS,EAAE;EACvC,MAAM,IAAI,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE;EACnD,QAAQ,IAAI,OAAO,GAAG,UAAU,CAAC,EAAE;EACnC,UAAU,IAAI,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAClC,UAAU,IAAI,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;EAC3D,UAAU,IAAI,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC;AACtE;EACA,UAAU,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;EAC/B,YAAY,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;EAC3D,cAAc,MAAM,CAAC,SAAS,CAAC,CAAC;EAChC,gBAAgB,IAAI,EAAE,SAAS;EAC/B,gBAAgB,OAAO,EAAE,IAAI;EAC7B,gBAAgB,WAAW,EAAE,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;EACnE,gBAAgB,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;EAC/D,gBAAgB,KAAK,EAAE,CAAC;EACxB,eAAe,CAAC,CAAC;EACjB,aAAa,CAAC,CAAC;EACf,WAAW;EACX,SAAS,CAAC;AACV;EACA,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,UAAU,OAAO,CAAC,CAAC,CAAC,CAAC;EACrB,SAAS;EACT,OAAO;EACP,KAAK,CAAC;AACN;EACA,IAAI,KAAK,IAAI,SAAS,IAAI,MAAM,EAAE;EAClC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;EACzB,KAAK;EACL,GAAG;EACH;;;;;;"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../lib/index.js"],"sourcesContent":["\n/**\n * AUTO-GENERATED FILE. DO NOT MODIFY.\n */\n\n/*\n* Licensed to the Apache Software Foundation (ASF) under one\n* or more contributor license agreements. See the NOTICE file\n* distributed with this work for additional information\n* regarding copyright ownership. The ASF licenses this file\n* to you under the Apache License, Version 2.0 (the\n* \"License\"); you may not use this file except in compliance\n* with the License. You may obtain a copy of the License at\n*\n* http://www.apache.org/licenses/LICENSE-2.0\n*\n* Unless required by applicable law or agreed to in writing,\n* software distributed under the License is distributed on an\n* \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n* KIND, either express or implied. See the License for the\n* specific language governing permissions and limitations\n* under the License.\n*/\nexport function hydrate(dom, options) {\n var svgRoot = dom.querySelector('svg');\n if (!svgRoot) {\n console.error('No SVG element found in the DOM.');\n return;\n }\n // const children = svgRoot.children;\n function getIndex(child, attr) {\n var index = child.getAttribute(attr);\n if (index) {\n return parseInt(index, 10);\n } else {\n return undefined;\n }\n }\n var listeners = options.on || {};\n var _loop_1 = function (rawEvtName) {\n var eventName = rawEvtName;\n if (!listeners.hasOwnProperty(eventName)) {\n return \"continue\";\n }\n var listener = listeners[eventName];\n if (!isFunction(listener)) {\n return \"continue\";\n }\n svgRoot.addEventListener(eventName, function (event) {\n var targetEl = event.target;\n if (!targetEl || !isFunction(targetEl.getAttribute)) {\n return;\n }\n var type = targetEl.getAttribute('ecmeta_ssr_type');\n var silent = targetEl.getAttribute('ecmeta_silent') === 'true';\n if (!type || silent) {\n return;\n }\n listener({\n type: eventName,\n ssrType: type,\n seriesIndex: getIndex(targetEl, 'ecmeta_series_index'),\n dataIndex: getIndex(targetEl, 'ecmeta_data_index'),\n event: event\n });\n });\n };\n for (var rawEvtName in listeners) {\n _loop_1(rawEvtName);\n }\n}\nfunction isFunction(value) {\n return typeof value === 'function';\n}"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;EACA;EACA;EACA;AACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACO,SAAS,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE;EACtC,EAAE,IAAI,OAAO,GAAG,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;EACzC,EAAE,IAAI,CAAC,OAAO,EAAE;EAChB,IAAI,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;EACtD,IAAI,OAAO;EACX,GAAG;EACH;EACA,EAAE,SAAS,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE;EACjC,IAAI,IAAI,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;EACzC,IAAI,IAAI,KAAK,EAAE;EACf,MAAM,OAAO,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;EACjC,KAAK,MAAM;EACX,MAAM,OAAO,SAAS,CAAC;EACvB,KAAK;EACL,GAAG;EACH,EAAE,IAAI,SAAS,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC;EACnC,EAAE,IAAI,OAAO,GAAG,UAAU,UAAU,EAAE;EACtC,IAAI,IAAI,SAAS,GAAG,UAAU,CAAC;EAC/B,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE;EAC9C,MAAM,OAAO,UAAU,CAAC;EACxB,KAAK;EACL,IAAI,IAAI,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;EACxC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;EAC/B,MAAM,OAAO,UAAU,CAAC;EACxB,KAAK;EACL,IAAI,OAAO,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,KAAK,EAAE;EACzD,MAAM,IAAI,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC;EAClC,MAAM,IAAI,CAAC,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE;EAC3D,QAAQ,OAAO;EACf,OAAO;EACP,MAAM,IAAI,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;EAC1D,MAAM,IAAI,MAAM,GAAG,QAAQ,CAAC,YAAY,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC;EACrE,MAAM,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE;EAC3B,QAAQ,OAAO;EACf,OAAO;EACP,MAAM,QAAQ,CAAC;EACf,QAAQ,IAAI,EAAE,SAAS;EACvB,QAAQ,OAAO,EAAE,IAAI;EACrB,QAAQ,WAAW,EAAE,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;EAC9D,QAAQ,SAAS,EAAE,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;EAC1D,QAAQ,KAAK,EAAE,KAAK;EACpB,OAAO,CAAC,CAAC;EACT,KAAK,CAAC,CAAC;EACP,GAAG,CAAC;EACJ,EAAE,KAAK,IAAI,UAAU,IAAI,SAAS,EAAE;EACpC,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;EACxB,GAAG;EACH,CAAC;EACD,SAAS,UAAU,CAAC,KAAK,EAAE;EAC3B,EAAE,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC;EACrC;;;;;;"} \ No newline at end of file diff --git a/ssr/client/src/.eslintrc.yaml b/ssr/client/src/.eslintrc.yaml new file mode 100644 index 0000000000..4f97f861fd --- /dev/null +++ b/ssr/client/src/.eslintrc.yaml @@ -0,0 +1,48 @@ + +# 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. + +# Note: +# If eslint does not work in VSCode, please check: +# (1) Whether "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser" +# are npm installed locally. Should better in the same version. +# (2) Whether "VSCode ESlint extension" is installed. +# (3) If the project folder is not the root folder of your working space, please +# config the "VSCode ESlint extension" in "settings": +# ```json +# "eslint.workingDirectories": [{"mode": "auto"}] +# ``` +# Note that it should be "workingDirectories" rather than "WorkingDirectories". + +parser: "@typescript-eslint/parser" +parserOptions: + ecmaVersion: 6 + sourceType: module + ecmaFeatures: + modules: true + project: "tsconfig.json" +plugins: ["@typescript-eslint"] +env: + es6: false +globals: + jQuery: false + Promise: false + console: true + setTimeout: true + clearTimeout: true + __DEV__: true +extends: '../../../.eslintrc-common.yaml' diff --git a/ssr/client/src/index.ts b/ssr/client/src/index.ts index d56a1e323d..09c3d2af83 100644 --- a/ssr/client/src/index.ts +++ b/ssr/client/src/index.ts @@ -17,58 +17,78 @@ * under the License. */ -export interface ECSSRClientEventParams {} +// FIXME: use only one definition with +// {SSRItemType} from '../../../src/util/innerStore'; +type SSRItemType = 'legend' | 'chart'; + +export interface ECSSRClientEventParams { + type: ECSSREvent; + ssrType: SSRItemType; + seriesIndex?: number; + dataIndex?: number; + event: Event; +} export interface ECSSRClientOptions { on?: { - mouseover?: (params: ECSSRClientEventParams) => void, - mouseout?: (params: ECSSRClientEventParams) => void, - click?: (params: ECSSRClientEventParams) => void + mouseover?: (params: ECSSRClientEventParams) => void; + mouseout?: (params: ECSSRClientEventParams) => void; + click?: (params: ECSSRClientEventParams) => void; } } export type ECSSREvent = 'mouseover' | 'mouseout' | 'click'; -export function hydrate(dom: HTMLElement, options: ECSSRClientOptions) { +export function hydrate(dom: HTMLElement, options: ECSSRClientOptions): void { const svgRoot = dom.querySelector('svg'); if (!svgRoot) { console.error('No SVG element found in the DOM.'); return; } - const children = svgRoot.children; - - function getIndex(child: Element, attr: string) { + function getIndex(child: Element, attr: string): number | undefined { const index = child.getAttribute(attr); if (index) { return parseInt(index, 10); } else { - return null; + return undefined; } } - const events = options.on; - if (events) { - for (let eventName in events) { - if (typeof events[eventName as ECSSREvent] === 'function') { - for (let i = 0; i < children.length; i++) { - const child = children[i]; - const type = child.getAttribute('ecmeta_ssr_type'); - const silent = child.getAttribute('ecmeta_silent') === 'true'; - if (type && !silent) { - child.addEventListener(eventName, e => { - (events[eventName as ECSSREvent] as Function)({ - type: eventName, - ssrType: type, - seriesIndex: getIndex(child, 'ecmeta_series_index'), - dataIndex: getIndex(child, 'ecmeta_data_index'), - event: e, - }); - }); - } - } - } + const listeners = options.on || {}; + for (const rawEvtName in listeners) { + if (!listeners.hasOwnProperty(rawEvtName)) { + continue; + } + const eventName = rawEvtName as ECSSREvent; + const listener = listeners[eventName as ECSSREvent]; + if (!isFunction(listener)) { + continue; } + + svgRoot.addEventListener(eventName, event => { + const targetEl = event.target as Element; + if (!targetEl || !isFunction(targetEl.getAttribute)) { + return; + } + const type = targetEl.getAttribute('ecmeta_ssr_type'); + const silent = targetEl.getAttribute('ecmeta_silent') === 'true'; + if (!type || silent) { + return; + } + listener({ + type: eventName, + ssrType: type as SSRItemType, + seriesIndex: getIndex(targetEl, 'ecmeta_series_index'), + dataIndex: getIndex(targetEl, 'ecmeta_data_index'), + event + }); + }); + } } + +function isFunction(value: any): value is Function { + return typeof value === 'function'; +} diff --git a/test/ssr.html b/test/ssr.html index 7516f7cbcb..1ddc04974f 100644 --- a/test/ssr.html +++ b/test/ssr.html @@ -71,25 +71,25 @@

Big data render time

height: 300, renderer: 'svg', ssr: true - }) + }); const width = serverChart.getWidth(); const height = serverChart.getHeight(); const seriesData = [{ - type: 'bar', - name: 'a', - data: [31, 43, 23, 54, 65, 23, 43] - }, { - type: 'bar', - name: 'b', - data: [63, 53, 73, 23, 43, 23, 43] - }, { - type: 'bar', - name: 'silent', - data: [32, 55, 31, 65, 54, 43, 65], - silent: true - }]; + type: 'bar', + name: 'a', + data: [31, 43, 23, 54, 65, 23, 43] + }, { + type: 'bar', + name: 'b', + data: [63, 53, 73, 23, 43, 23, 43] + }, { + type: 'bar', + name: 'silent', + data: [32, 55, 31, 65, 54, 43, 65], + silent: true + }]; const option = { legend: { @@ -115,7 +115,7 @@

Big data render time

function update() { main.innerHTML = serverChart.renderToSVGString(); - const clientChart = ssrClient.hydrate(main, { + ssrClient.hydrate(main, { on: { mouseover: (params) => { // console.log(params); @@ -197,7 +197,8 @@

Big data render time

const main = document.getElementById('big-data'); console.time('renderToSVGString'); - main.innerHTML = serverChart.renderToSVGString(); + const html = serverChart.renderToSVGString(); + main.innerHTML = html; console.timeEnd('renderToSVGString'); const size = main.innerHTML.length; console.log('SVG size:', size > 1e6 ? (size / 1e6).toFixed(1) + 'M' : (size / 1e3).toFixed(1) + 'K'); diff --git a/tsconfig.json b/tsconfig.json index e44ef3ac08..3d7d3c377b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,6 +23,7 @@ "include": [ "src/**/*.ts", "extension-src/**/*.ts", + "ssr/client/**/*.ts", "test/lib/myTransform/src/**/*.ts" ] } \ No newline at end of file