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

ovilia pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/echarts-custom-series.git

commit 9a3fe20f6bf0a6a2f9f59ce6f8e68d91b89180a3
Author: Ovilia <[email protected]>
AuthorDate: Thu Aug 14 10:56:23 2025 +0800

    chore: build barRange
---
 custom-series/barRange/README.md                   |  46 +++++---
 .../barRange/dist/{index.js => index.auto.js}      |  17 +--
 custom-series/barRange/dist/index.auto.min.js      |  22 ++++
 custom-series/barRange/dist/index.auto.min.js.map  |   1 +
 custom-series/barRange/dist/index.d.ts             |   5 +
 custom-series/barRange/dist/index.esm.min.mjs      |  20 ++++
 custom-series/barRange/dist/index.esm.min.mjs.map  |   1 +
 custom-series/barRange/dist/index.esm.mjs          |  83 ++++++++++++++
 custom-series/barRange/dist/index.js               |   4 +
 custom-series/barRange/dist/index.min.js           |   3 +-
 custom-series/barRange/dist/index.min.js.map       |   2 +-
 .../{violin => barRange}/examples/index.html       |  73 +++++--------
 custom-series/barRange/examples/ssr.js             |  81 ++++++++++++++
 custom-series/barRange/package-lock.json           |  42 +++++---
 custom-series/barRange/package.json                |  39 +++++--
 custom-series/barRange/rollup.config.js            |  38 -------
 custom-series/barRange/screenshots/barRange.svg    |  54 ++++++++++
 custom-series/barRange/src/index.ts                |   9 +-
 custom-series/barRange/test/index.html             |  59 ----------
 custom-series/violin/README.md                     |   2 +-
 custom-series/violin/dist/index.d.ts               |   5 +
 custom-series/violin/dist/index.esm.min.js.map     |   1 -
 .../dist/{index.esm.min.js => index.esm.min.mjs}   |   2 +-
 custom-series/violin/dist/index.esm.min.mjs.map    |   1 +
 .../violin/dist/{index.esm.js => index.esm.mjs}    |   0
 custom-series/violin/examples/index.html           |   1 -
 custom-series/violin/package-lock.json             |   4 +-
 custom-series/violin/package.json                  |  20 ++--
 custom-series/violin/src/index.ts                  |   7 +-
 scripts/build.js                                   |  76 +++++++------
 scripts/generate.js                                |   5 +-
 scripts/rollup.config.js                           | 119 ++++++++++++++++-----
 scripts/serve.js                                   |   4 +-
 scripts/template/README.md                         |  46 +++++---
 .../template}/examples/index.html                  |  57 ++--------
 scripts/template/examples/ssr.js                   |  67 ++++++++++++
 scripts/template/package.json                      |  46 ++++++--
 scripts/template/rollup.config.js                  |  38 -------
 scripts/template/src/index.ts                      |  16 +--
 scripts/template/test/index.html                   |  33 ------
 scripts/thumbnail.js                               | 118 ++++++++++----------
 41 files changed, 788 insertions(+), 479 deletions(-)

diff --git a/custom-series/barRange/README.md b/custom-series/barRange/README.md
index 53d95f7..aad08fe 100644
--- a/custom-series/barRange/README.md
+++ b/custom-series/barRange/README.md
@@ -1,37 +1,61 @@
-# barRange
+# @echarts-x/custom-barRange
 
 `barRange` is a custom series for [Apache 
ECharts](https://github.com/apache/echarts). It's typically used to display the 
range of data using bars.
 
-![barRange](../../screenshots/barRange.svg)
+![barRange](https://raw.githubusercontent.com/apache/echarts-custom-series/main/custom-series/bar-range/screenshots/barRange.svg)
+
+[Source 
Code](https://github.com/apache/echarts-custom-series/tree/main/custom-series/barRange)
 
 ## Usage
 
-Import the custom series JavaScript file and ECharts, then use `echarts.use` 
to install it.
+### Browser Environment
+
+For browser usage, use the auto-registration version that automatically 
installs the custom series when loaded:
 
 ```html
 <script src="./node_modules/echarts/dist/echarts.js"></script>
-<script src="./dist/index.js"></script>
+<script 
src="./node_modules/@echarts-x/custom-bar-range/dist/index.auto.js"></script>
 <script>
-  echarts.use(window.barRangeCustomSeriesInstaller);
+  // No need to call echarts.use(), automatically registered
   const chart = echarts.init(...);
   // ...
 </script>
 ```
 
-Or, if using module bundler, install the package from npm and import it.
+### UMD (Universal Module Definition)
+
+For environments that need manual registration or when using AMD/CommonJS 
loaders:
+
+```js
+// CommonJS
+const echarts = require('echarts');
+const barRangeInstaller = require('@echarts-x/custom-bar-range');
+echarts.use(barRangeInstaller);
+const chart = echarts.init(...);
+// ...
+
+// AMD
+require(['echarts', '@echarts-x/custom-bar-range'], function(echarts, 
barRangeInstaller) {
+  echarts.use(barRangeInstaller);
+});
+```
+
+### ESM (ES Modules)
+
+For modern module bundlers or native ES module environments:
 
 ```bash
-npm install @echarts/custom-bar-range
+npm install @echarts-x/custom-bar-range
 ```
 
 ```js
-import echarts from 'echarts';
-import barRangeCustomSeriesInstaller from '@echarts/custom-bar-range';
+import * as echarts from 'echarts';
+import barRangeCustomSeriesInstaller from '@echarts-x/custom-bar-range';
 
 echarts.use(barRangeCustomSeriesInstaller);
 ```
 
-See [test](./test/index.html) for more details.
+See [examples](./examples) for more details.
 
 ## API
 
@@ -69,5 +93,3 @@ encode: {
     tooltip: [1, 2]
 }
 ```
-
-See [test](./test/index.html) for more details.
diff --git a/custom-series/barRange/dist/index.js 
b/custom-series/barRange/dist/index.auto.js
similarity index 88%
copy from custom-series/barRange/dist/index.js
copy to custom-series/barRange/dist/index.auto.js
index 77c2567..3b81752 100644
--- a/custom-series/barRange/dist/index.js
+++ b/custom-series/barRange/dist/index.auto.js
@@ -16,11 +16,9 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-(function (global, factory) {
-    typeof exports === 'object' && typeof module !== 'undefined' ? 
module.exports = factory() :
-    typeof define === 'function' && define.amd ? define(factory) :
-    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, 
global.barRangeCustomSeriesInstaller = factory());
-})(this, (function () { 'use strict';
+
+this.barRangeCustomSeriesInstaller = (function () {
+    'use strict';
 
     var renderItem = function (params, api) {
         var x = api.value(0);
@@ -30,6 +28,9 @@
         var coordEnd = api.coord([x, valueEnd]);
         var bandWidth = api.coord([1, 0])[0] - api.coord([0, 0])[0];
         var barWidthRaw = params.itemPayload.barWidth;
+        if (barWidthRaw == null) {
+            barWidthRaw = '70%';
+        }
         var barWidth = typeof barWidthRaw === 'string' && 
barWidthRaw.endsWith('%')
             ? (parseFloat(barWidthRaw) / 100) * bandWidth
             : barWidthRaw;
@@ -84,4 +85,8 @@
 
     return index;
 
-}));
+})();
+// Automatically register the custom series
+if (typeof window !== 'undefined' && window.echarts) {
+  window.echarts.use(window.barRangeCustomSeriesInstaller);
+}
diff --git a/custom-series/barRange/dist/index.auto.min.js 
b/custom-series/barRange/dist/index.auto.min.js
new file mode 100644
index 0000000..85641e1
--- /dev/null
+++ b/custom-series/barRange/dist/index.auto.min.js
@@ -0,0 +1,22 @@
+/*
+* 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.
+*/
+this.barRangeCustomSeriesInstaller=function(){"use strict";var 
t=function(t,e){var 
r=e.value(0),i=e.value(1),l=e.coord([r,i]),n=e.value(2),o=e.coord([r,n]),a=e.coord([1,0])[0]-e.coord([0,0])[0],s=t.itemPayload.barWidth;null==s&&(s="70%");var
 d="string"==typeof 
s&&s.endsWith("%")?parseFloat(s)/100*a:s,u=t.itemPayload.borderRadius||0,c={type:"rect",shape:{x:l[0]-d/2,y:l[1],width:d,height:o[1]-l[1],r:u},style:{fill:e.visual("color")}},y=t.itemPayload.margin,g=null==y?10:y;return{type:"group
 [...]
+// Automatically register the custom series
+"undefined"!=typeof 
window&&window.echarts&&window.echarts.use(window.barRangeCustomSeriesInstaller);
+//# sourceMappingURL=index.auto.min.js.map
diff --git a/custom-series/barRange/dist/index.auto.min.js.map 
b/custom-series/barRange/dist/index.auto.min.js.map
new file mode 100644
index 0000000..e9e68d2
--- /dev/null
+++ b/custom-series/barRange/dist/index.auto.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.auto.min.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
\ No newline at end of file
diff --git a/custom-series/barRange/dist/index.d.ts 
b/custom-series/barRange/dist/index.d.ts
new file mode 100644
index 0000000..a8e7d81
--- /dev/null
+++ b/custom-series/barRange/dist/index.d.ts
@@ -0,0 +1,5 @@
+// Tricky: use1 and use2 are incompatible.
+import type {use as use1} from 'echarts/core';
+import type {use as use2} from 'echarts';
+declare const _default: Parameters<typeof use1>[0] & Parameters<typeof 
use2>[0];
+export default _default;
diff --git a/custom-series/barRange/dist/index.esm.min.mjs 
b/custom-series/barRange/dist/index.esm.min.mjs
new file mode 100644
index 0000000..e70d263
--- /dev/null
+++ b/custom-series/barRange/dist/index.esm.min.mjs
@@ -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.
+*/
+var renderItem=function(t,e){var 
r=e.value(0),l=e.value(1),i=e.coord([r,l]),a=e.value(2),o=e.coord([r,a]),n=e.coord([1,0])[0]-e.coord([0,0])[0],d=t.itemPayload.barWidth;null==d&&(d="70%");var
 s="string"==typeof 
d&&d.endsWith("%")?parseFloat(d)/100*n:d,x=t.itemPayload.borderRadius||0,y={type:"rect",shape:{x:i[0]-s/2,y:i[1],width:s,height:o[1]-i[1],r:x},style:{fill:e.visual("color")}},c=t.itemPayload.margin,u=null==c?10:c;return{type:"group",children:[y,{type:"text",x:o[0],y:o[1]-u,style:{
 [...]
+//# sourceMappingURL=index.esm.min.mjs.map
diff --git a/custom-series/barRange/dist/index.esm.min.mjs.map 
b/custom-series/barRange/dist/index.esm.min.mjs.map
new file mode 100644
index 0000000..671f88a
--- /dev/null
+++ b/custom-series/barRange/dist/index.esm.min.mjs.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.esm.min.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
\ No newline at end of file
diff --git a/custom-series/barRange/dist/index.esm.mjs 
b/custom-series/barRange/dist/index.esm.mjs
new file mode 100644
index 0000000..2906c21
--- /dev/null
+++ b/custom-series/barRange/dist/index.esm.mjs
@@ -0,0 +1,83 @@
+/*
+* 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.
+*/
+
+var renderItem = function (params, api) {
+    var x = api.value(0);
+    var valueStart = api.value(1);
+    var coordStart = api.coord([x, valueStart]);
+    var valueEnd = api.value(2);
+    var coordEnd = api.coord([x, valueEnd]);
+    var bandWidth = api.coord([1, 0])[0] - api.coord([0, 0])[0];
+    var barWidthRaw = params.itemPayload.barWidth;
+    if (barWidthRaw == null) {
+        barWidthRaw = '70%';
+    }
+    var barWidth = typeof barWidthRaw === 'string' && barWidthRaw.endsWith('%')
+        ? (parseFloat(barWidthRaw) / 100) * bandWidth
+        : barWidthRaw;
+    var borderRadius = params.itemPayload.borderRadius || 0;
+    var bar = {
+        type: 'rect',
+        shape: {
+            x: coordStart[0] - barWidth / 2,
+            y: coordStart[1],
+            width: barWidth,
+            height: coordEnd[1] - coordStart[1],
+            r: borderRadius,
+        },
+        style: {
+            fill: api.visual('color'),
+        },
+    };
+    var marginRaw = params.itemPayload.margin;
+    var margin = marginRaw == null ? 10 : marginRaw;
+    var textTop = {
+        type: 'text',
+        x: coordEnd[0],
+        y: coordEnd[1] - margin,
+        style: {
+            text: valueEnd.toString() + '℃',
+            textAlign: 'center',
+            textVerticalAlign: 'bottom',
+            fill: '#333',
+        },
+    };
+    var textBottom = {
+        type: 'text',
+        x: coordStart[0],
+        y: coordStart[1] + margin,
+        style: {
+            text: valueStart.toString() + '℃',
+            textAlign: 'center',
+            textVerticalAlign: 'top',
+            fill: '#333',
+        },
+    };
+    return {
+        type: 'group',
+        children: [bar, textTop, textBottom],
+    };
+};
+var index = {
+    install: function (registers) {
+        registers.registerCustomSeries('barRange', renderItem);
+    },
+};
+
+export { index as default };
diff --git a/custom-series/barRange/dist/index.js 
b/custom-series/barRange/dist/index.js
index 77c2567..2dc3fbe 100644
--- a/custom-series/barRange/dist/index.js
+++ b/custom-series/barRange/dist/index.js
@@ -16,6 +16,7 @@
 * specific language governing permissions and limitations
 * under the License.
 */
+
 (function (global, factory) {
     typeof exports === 'object' && typeof module !== 'undefined' ? 
module.exports = factory() :
     typeof define === 'function' && define.amd ? define(factory) :
@@ -30,6 +31,9 @@
         var coordEnd = api.coord([x, valueEnd]);
         var bandWidth = api.coord([1, 0])[0] - api.coord([0, 0])[0];
         var barWidthRaw = params.itemPayload.barWidth;
+        if (barWidthRaw == null) {
+            barWidthRaw = '70%';
+        }
         var barWidth = typeof barWidthRaw === 'string' && 
barWidthRaw.endsWith('%')
             ? (parseFloat(barWidthRaw) / 100) * bandWidth
             : barWidthRaw;
diff --git a/custom-series/barRange/dist/index.min.js 
b/custom-series/barRange/dist/index.min.js
index f6115b6..61e77cd 100644
--- a/custom-series/barRange/dist/index.min.js
+++ b/custom-series/barRange/dist/index.min.js
@@ -16,4 +16,5 @@
 * specific language governing permissions and limitations
 * under the License.
 */
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof 
module?module.exports=t():"function"==typeof 
define&&define.amd?define(t):(e="undefined"!=typeof 
globalThis?globalThis:e||self).barRangeCustomSeriesInstaller=t()}(this,(function(){"use
 strict";var e=function(e,t){var 
i=t.value(0),o=t.value(1),l=t.coord([i,o]),r=t.value(2),n=t.coord([i,r]),a=t.coord([1,0])[0]-t.coord([0,0])[0],s=e.itemPayload.barWidth,d="string"==typeof
 s&&s.endsWith("%")?parseFloat(s)/100*a:s,u=e.itemPayload.bo [...]
\ No newline at end of file
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof 
module?module.exports=t():"function"==typeof 
define&&define.amd?define(t):(e="undefined"!=typeof 
globalThis?globalThis:e||self).barRangeCustomSeriesInstaller=t()}(this,(function(){"use
 strict";var e=function(e,t){var 
i=t.value(0),l=t.value(1),o=t.coord([i,l]),r=t.value(2),n=t.coord([i,r]),a=t.coord([1,0])[0]-t.coord([0,0])[0],s=e.itemPayload.barWidth;null==s&&(s="70%");var
 d="string"==typeof s&&s.endsWith("%")?parseFloat(s)/100 [...]
+//# sourceMappingURL=index.min.js.map
diff --git a/custom-series/barRange/dist/index.min.js.map 
b/custom-series/barRange/dist/index.min.js.map
index 22c0ce6..f63dfe5 100644
--- a/custom-series/barRange/dist/index.min.js.map
+++ b/custom-series/barRange/dist/index.min.js.map
@@ -1 +1 @@
-{"version":3,"names":["global","factory","exports","module","define","amd","globalThis","self","barRangeCustomSeriesInstaller","this","renderItem","params","api","x","value","valueStart","coordStart","coord","valueEnd","coordEnd","bandWidth","barWidthRaw","itemPayload","barWidth","endsWith","parseFloat","borderRadius","bar","type","shape","y","width","height","r","style","fill","visual","marginRaw","margin","children","text","toString","textAlign","textVerticalAlign","install","registers
 [...]
\ No newline at end of file
+{"version":3,"file":"index.min.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
\ No newline at end of file
diff --git a/custom-series/violin/examples/index.html 
b/custom-series/barRange/examples/index.html
similarity index 57%
copy from custom-series/violin/examples/index.html
copy to custom-series/barRange/examples/index.html
index 78ef3fd..93b5434 100644
--- a/custom-series/violin/examples/index.html
+++ b/custom-series/barRange/examples/index.html
@@ -33,59 +33,44 @@
     <script src="../node_modules/echarts/dist/echarts.js"></script>
     <script src="../dist/index.auto.js"></script>
     <script>
-      const chart = echarts.init(document.getElementById('main'), null, {
-        renderer: 'svg',
-      });
+      echarts.use(window.barRangeCustomSeriesInstaller);
+      const chart = echarts.init(document.getElementById('main'));
 
-      const xData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
-      const dataSource = [['Day', 'value']];
-      for (let i = 0; i < xData.length; ++i) {
-        const dataCount = 10 * Math.round(Math.random() * 5) + 5;
-        for (let j = 0; j < dataCount; ++j) {
-          const value = Math.tan(i) / 2 + 3 * Math.random() + 2;
-          dataSource.push([xData[i], value]);
-        }
-      }
+      const data = [
+        [0, 26.7, 32.5],
+        [1, 25.3, 32.4],
+        [2, 24.6, 32.7],
+        [3, 26.8, 35.8],
+        [4, 26.2, 33.1],
+        [5, 24.9, 31.4],
+        [6, 25.3, 32.9],
+      ];
 
       option = {
-        animation: 0,
-        tooltip: {
-          show: true,
-        },
         xAxis: {
+          data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
           type: 'category',
-          data: xData,
-          jitter: 100,
-          jitterOverlap: false,
         },
-        yAxis: {},
-        dataset: {
-          source: dataSource,
+        yAxis: {
+          type: 'value',
         },
-        series: [
-          {
-            type: 'custom',
-            renderItem: 'violin',
-            colorBy: 'item',
-            silent: true,
-            itemPayload: {
-              symbolSize: 4,
-              areaOpacity: 0.6,
-              bandWidthScale: 1.5,
-              // binCount: 20
-            },
+        tooltip: {
+          show: true,
+        },
+        series: {
+          type: 'custom',
+          renderItem: 'barRange',
+          data,
+          itemPayload: {
+            barWidth: 10,
+            borderRadius: 5,
           },
-          {
-            type: 'scatter',
-            encode: {
-              x: 0,
-              y: 1,
-            },
-            colorBy: 'item',
-            silent: true,
-            symbolSize: 6,
+          encode: {
+            x: 0,
+            y: [1, 2],
+            tooltip: [1, 2],
           },
-        ],
+        },
       };
 
       chart.setOption(option);
diff --git a/custom-series/barRange/examples/ssr.js 
b/custom-series/barRange/examples/ssr.js
new file mode 100644
index 0000000..1135386
--- /dev/null
+++ b/custom-series/barRange/examples/ssr.js
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+const echarts = require('echarts');
+const barRangeInstaller = require('../dist/index.js');
+
+echarts.use(barRangeInstaller);
+
+const chart = echarts.init(null, null, {
+  renderer: 'svg',
+  ssr: true,
+  width: 600,
+  height: 400,
+});
+
+// Set up seeded random for consistent thumbnails
+const seedrandom = require('seedrandom');
+const myRandom = new seedrandom('echarts-random');
+Math.random = function () {
+  return myRandom();
+};
+
+const data = [
+  [0, 26.7, 32.5],
+  [1, 25.3, 32.4],
+  [2, 24.6, 32.7],
+  [3, 26.8, 35.8],
+  [4, 26.2, 33.1],
+  [5, 24.9, 31.4],
+  [6, 25.3, 32.9],
+];
+
+option = {
+  xAxis: {
+    data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+    type: 'category',
+  },
+  yAxis: {
+    type: 'value',
+  },
+  tooltip: {
+    show: true,
+  },
+  series: {
+    type: 'custom',
+    renderItem: 'barRange',
+    data,
+    itemPayload: {
+      barWidth: 10,
+      borderRadius: 5,
+    },
+    encode: {
+      x: 0,
+      y: [1, 2],
+      tooltip: [1, 2],
+    },
+  },
+};
+
+chart.setOption(option);
+
+const svg = chart.renderToSVGString();
+console.log(svg);
+
+chart.dispose();
diff --git a/custom-series/barRange/package-lock.json 
b/custom-series/barRange/package-lock.json
index 0f960a5..3731728 100644
--- a/custom-series/barRange/package-lock.json
+++ b/custom-series/barRange/package-lock.json
@@ -1,39 +1,45 @@
 {
-  "name": "echarts-barRange",
-  "version": "0.0.1",
+  "name": "@echarts-x/custom-bar-range",
+  "version": "1.0.0-beta.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
-      "name": "echarts-barRange",
-      "version": "0.0.1",
+      "name": "@echarts-x/custom-bar-range",
+      "version": "1.0.0-beta.0",
       "license": "Apache-2.0",
-      "dependencies": {
-        "echarts": "github:apache/echarts#v6"
-      },
       "devDependencies": {
+        "echarts": "^6.0.0",
         "typescript": "^5.5.4"
+      },
+      "peerDependencies": {
+        "echarts": "^6.0.0"
       }
     },
     "node_modules/echarts": {
-      "version": "5.5.1",
-      "resolved": 
"git+ssh://[email protected]/apache/echarts.git#ce7c12287320aca047a9104cb0b42be5a366fbfc",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-6.0.0.tgz";,
+      "integrity": 
"sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==",
+      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "tslib": "2.3.0",
-        "zrender": "5.6.0"
+        "zrender": "6.0.0"
       }
     },
     "node_modules/tslib": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz";,
-      "integrity": 
"sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+      "integrity": 
"sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+      "dev": true,
+      "license": "0BSD"
     },
     "node_modules/typescript": {
-      "version": "5.6.2",
-      "resolved": 
"https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz";,
-      "integrity": 
"sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
+      "version": "5.9.2",
+      "resolved": 
"https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz";,
+      "integrity": 
"sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
       "dev": true,
+      "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -43,9 +49,11 @@
       }
     },
     "node_modules/zrender": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz";,
-      "integrity": 
"sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-6.0.0.tgz";,
+      "integrity": 
"sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==",
+      "dev": true,
+      "license": "BSD-3-Clause",
       "dependencies": {
         "tslib": "2.3.0"
       }
diff --git a/custom-series/barRange/package.json 
b/custom-series/barRange/package.json
index cf8fc35..796b71b 100644
--- a/custom-series/barRange/package.json
+++ b/custom-series/barRange/package.json
@@ -1,20 +1,43 @@
 {
-  "name": "@echarts/custom-bar-range",
-  "version": "0.0.1",
-  "description": "Custom bar range series for Apache ECharts",
+  "name": "@echarts-x/custom-bar-range",
+  "version": "1.0.0-beta.0",
+  "description": "Custom barRange series for Apache ECharts",
   "main": "dist/index.js",
-  "scripts": {
-    "build": "tsc"
+  "module": "dist/index.esm.mjs",
+  "exports": {
+    ".": {
+      "types": "./dist/index.d.ts",
+      "import": "./dist/index.esm.mjs",
+      "require": "./dist/index.js"
+    }
   },
-  "keywords": [],
+  "types": "dist/index.d.ts",
+  "keywords": [
+    "echarts",
+    "apache-echarts",
+    "data-visualization",
+    "chart",
+    "dataviz"
+  ],
   "author": "",
   "license": "Apache-2.0",
-  "dependencies": {
-    "echarts": "github:apache/echarts#v6"
+  "homepage": 
"https://github.com/apache/echarts-custom-series/tree/main/custom-series/violin";,
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/apache/echarts-custom-series.git";
+  },
+  "scripts": {
+    "test:browser": "npx http-server . -p 8088 -o examples/index.html",
+    "test:ssr": "node examples/ssr.js",
+    "test": "npm run test:ssr"
   },
   "devDependencies": {
+    "echarts": "^6.0.0",
     "typescript": "^5.5.4"
   },
+  "peerDependencies": {
+    "echarts": "^6.0.0"
+  },
   "files": [
     "dist",
     "README.md"
diff --git a/custom-series/barRange/rollup.config.js 
b/custom-series/barRange/rollup.config.js
deleted file mode 100644
index 750ec52..0000000
--- a/custom-series/barRange/rollup.config.js
+++ /dev/null
@@ -1,38 +0,0 @@
-module.exports = {
-  input: 'lib/index.js',
-  output: {
-    file: 'dist/index.js',
-    format: 'umd',
-    name: 'barRangeCustomSeriesInstaller',
-    extend: true,
-    globals: {
-      window: 'window',
-    },
-  },
-  plugins: [
-    {
-      name: 'add-license',
-      renderChunk(code) {
-        return `/*
-* 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.
-*/
-${code}`;
-      },
-    },
-  ],
-};
diff --git a/custom-series/barRange/screenshots/barRange.svg 
b/custom-series/barRange/screenshots/barRange.svg
new file mode 100644
index 0000000..3bdd932
--- /dev/null
+++ b/custom-series/barRange/screenshots/barRange.svg
@@ -0,0 +1,54 @@
+<svg width="600" height="400" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; version="1.1" baseProfile="full" 
viewBox="0 0 600 400">
+<rect width="600" height="400" x="0" y="0" fill="none"></rect>
+<path d="M90 320.5L540 320.5" fill="none" pointer-events="visible" 
stroke="#dbdee4" class="zr0-cls-0"></path>
+<path d="M90 256.5L540 256.5" fill="none" pointer-events="visible" 
stroke="#dbdee4" class="zr0-cls-0"></path>
+<path d="M90 192.5L540 192.5" fill="none" pointer-events="visible" 
stroke="#dbdee4" class="zr0-cls-0"></path>
+<path d="M90 129.5L540 129.5" fill="none" pointer-events="visible" 
stroke="#dbdee4" class="zr0-cls-0"></path>
+<path d="M90 65.5L540 65.5" fill="none" pointer-events="visible" 
stroke="#dbdee4" class="zr0-cls-0"></path>
+<path d="M90 320.5L540 320.5" fill="none" pointer-events="visible" 
stroke="#54555a" stroke-linecap="round" class="zr0-cls-0"></path>
+<text dominant-baseline="central" text-anchor="end" 
style="font-size:12px;font-family:sans-serif;" transform="translate(82 320)" 
fill="#54555a">0</text>
+<text dominant-baseline="central" text-anchor="end" 
style="font-size:12px;font-family:sans-serif;" transform="translate(82 256.25)" 
fill="#54555a">10</text>
+<text dominant-baseline="central" text-anchor="end" 
style="font-size:12px;font-family:sans-serif;" transform="translate(82 192.5)" 
fill="#54555a">20</text>
+<text dominant-baseline="central" text-anchor="end" 
style="font-size:12px;font-family:sans-serif;" transform="translate(82 128.75)" 
fill="#54555a">30</text>
+<text dominant-baseline="central" text-anchor="end" 
style="font-size:12px;font-family:sans-serif;" transform="translate(82 65)" 
fill="#54555a">40</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" 
transform="translate(122.1429 328)" fill="#54555a">Sun</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" 
transform="translate(186.4286 328)" fill="#54555a">Mon</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" 
transform="translate(250.7143 328)" fill="#54555a">Tue</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" transform="translate(315 
328)" fill="#54555a">Wed</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" 
transform="translate(379.2857 328)" fill="#54555a">Thu</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" 
transform="translate(443.5714 328)" fill="#54555a">Fri</text>
+<text dominant-baseline="central" text-anchor="middle" 
style="font-size:12px;font-family:sans-serif;" y="6" 
transform="translate(507.8571 328)" fill="#54555a">Sat</text>
+<path d="M122.1 112.8A5 5 0 0 1 127.1 117.8L127.1 144.8A5 5 0 0 1 122.1 
149.8A5 5 0 0 1 117.1 144.8L117.1 117.8A5 5 0 0 1 122.1 112.8" fill="#5070dd" 
ecmeta_series_index="0" ecmeta_data_index="0" ecmeta_ssr_type="chart" 
class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(122.1429 102.8125)" 
fill="#333">32.5℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(122.1429 159.7875)" 
fill="#333">26.7℃</text>
+<path d="M186.4 113.5A5 5 0 0 1 191.4 118.5L191.4 153.7A5 5 0 0 1 186.4 
158.7A5 5 0 0 1 181.4 153.7L181.4 118.5A5 5 0 0 1 186.4 113.5" fill="#5070dd" 
ecmeta_series_index="0" ecmeta_data_index="1" ecmeta_ssr_type="chart" 
class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(186.4286 103.45)" 
fill="#333">32.4℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(186.4286 168.7125)" 
fill="#333">25.3℃</text>
+<path d="M250.7 111.5A5 5 0 0 1 255.7 116.5L255.7 158.2A5 5 0 0 1 250.7 
163.2A5 5 0 0 1 245.7 158.2L245.7 116.5A5 5 0 0 1 250.7 111.5" fill="#5070dd" 
ecmeta_series_index="0" ecmeta_data_index="2" ecmeta_ssr_type="chart" 
class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(250.7143 101.5375)" 
fill="#333">32.7℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(250.7143 173.175)" 
fill="#333">24.6℃</text>
+<path d="M315 91.8A5 5 0 0 1 320 96.8L320 144.1A5 5 0 0 1 315 149.1A5 5 0 0 1 
310 144.1L310 96.8A5 5 0 0 1 315 91.8" fill="#5070dd" ecmeta_series_index="0" 
ecmeta_data_index="3" ecmeta_ssr_type="chart" class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(315 81.775)" fill="#333">35.8℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(315 159.15)" fill="#333">26.8℃</text>
+<path d="M379.3 109A5 5 0 0 1 384.3 114L384.3 148A5 5 0 0 1 379.3 153A5 5 0 0 
1 374.3 148L374.3 114A5 5 0 0 1 379.3 109" fill="#5070dd" 
ecmeta_series_index="0" ecmeta_data_index="4" ecmeta_ssr_type="chart" 
class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(379.2857 98.9875)" 
fill="#333">33.1℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(379.2857 162.975)" 
fill="#333">26.2℃</text>
+<path d="M443.6 119.8A5 5 0 0 1 448.6 124.8L448.6 156.3A5 5 0 0 1 443.6 
161.3A5 5 0 0 1 438.6 156.3L438.6 124.8A5 5 0 0 1 443.6 119.8" fill="#5070dd" 
ecmeta_series_index="0" ecmeta_data_index="5" ecmeta_ssr_type="chart" 
class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(443.5714 109.825)" 
fill="#333">31.4℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(443.5714 171.2625)" 
fill="#333">24.9℃</text>
+<path d="M507.9 110.3L507.9 110.3A5 5 0 0 1 512.9 115.3L512.9 153.7A5 5 0 0 1 
507.9 158.7L507.9 158.7A5 5 0 0 1 502.9 153.7L502.9 115.3A5 5 0 0 1 507.9 
110.3" fill="#5070dd" ecmeta_series_index="0" ecmeta_data_index="6" 
ecmeta_ssr_type="chart" class="zr0-cls-1"></path>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="-6" transform="translate(507.8571 100.2625)" 
fill="#333">32.9℃</text>
+<text dominant-baseline="central" text-anchor="middle" style="font: 12px 
sans-serif" y="6" transform="translate(507.8571 168.7125)" 
fill="#333">25.3℃</text>
+<style ><![CDATA[
+.zr0-cls-0:hover {
+pointer-events:none;
+}
+.zr0-cls-1:hover {
+cursor:pointer;
+fill:rgba(88,123,243,1);
+}
+
+]]>
+
+</style>
+</svg>
\ No newline at end of file
diff --git a/custom-series/barRange/src/index.ts 
b/custom-series/barRange/src/index.ts
index 9ba2c3f..c45be8d 100644
--- a/custom-series/barRange/src/index.ts
+++ b/custom-series/barRange/src/index.ts
@@ -17,12 +17,15 @@
  * under the License.
  */
 
-import echarts from 'echarts';
+import * as echarts from 'echarts';
 import type {
   CustomRootElementOption,
   CustomSeriesRenderItem,
 } from 'echarts/types/src/chart/custom/CustomSeries.d.ts';
-import type { EChartsExtensionInstallRegisters } from 
'echarts/src/extension.ts';
+import type {
+  EChartsExtensionInstallRegisters,
+  EChartsExtension,
+} from 'echarts/types/src/extension.d.ts';
 
 const renderItem = (
   params: echarts.CustomSeriesRenderItemParams,
@@ -98,4 +101,4 @@ export default {
       renderItem as unknown as CustomSeriesRenderItem
     );
   },
-};
+} as EChartsExtension;
diff --git a/custom-series/barRange/test/index.html 
b/custom-series/barRange/test/index.html
deleted file mode 100644
index eb76bc1..0000000
--- a/custom-series/barRange/test/index.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Apache ECharts Custom Series Test</title>
-</head>
-
-<body>
-    <div id="main" style="width: 1000px;height:400px;border:1px solid 
#ccc"></div>
-
-    <script src="../node_modules/echarts/dist/echarts.js"></script>
-    <script src="../dist/index.js"></script>
-    <script>
-        echarts.use(window.barRangeCustomSeriesInstaller);
-        const chart = echarts.init(document.getElementById('main'));
-        const data = [
-            [0, 26.7, 32.5],
-            [1, 25.3, 32.4],
-            [2, 24.6, 32.7],
-            [3, 26.8, 35.8],
-            [4, 26.2, 33.1],
-            [5, 24.9, 31.4],
-            [6, 25.3, 32.9],
-        ];
-
-        option = {
-            xAxis: {
-                data: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
-                type: 'category'
-            },
-            yAxis: {
-                type: 'value'
-            },
-            tooltip: {
-                show: true
-            },
-            series: {
-                type: 'custom',
-                renderItem: 'barRange',
-                data,
-                itemPayload: {
-                    barWidth: 10,
-                    borderRadius: 5
-                },
-                encode: {
-                    x: 0,
-                    y: [1, 2],
-                    tooltip: [1, 2]
-                }
-            }
-        };
-
-        chart.setOption(option);
-    </script>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/custom-series/violin/README.md b/custom-series/violin/README.md
index 53d821c..16607f8 100644
--- a/custom-series/violin/README.md
+++ b/custom-series/violin/README.md
@@ -50,7 +50,7 @@ npm install @echarts-x/custom-violin
 
 ```js
 import * as echarts from 'echarts';
-import violinCustomSeriesInstaller from 
'@echarts-x/custom-violin/dist/index.esm.js';
+import violinCustomSeriesInstaller from '@echarts-x/custom-violin';
 
 echarts.use(violinCustomSeriesInstaller);
 ```
diff --git a/custom-series/violin/dist/index.d.ts 
b/custom-series/violin/dist/index.d.ts
new file mode 100644
index 0000000..a8e7d81
--- /dev/null
+++ b/custom-series/violin/dist/index.d.ts
@@ -0,0 +1,5 @@
+// Tricky: use1 and use2 are incompatible.
+import type {use as use1} from 'echarts/core';
+import type {use as use2} from 'echarts';
+declare const _default: Parameters<typeof use1>[0] & Parameters<typeof 
use2>[0];
+export default _default;
diff --git a/custom-series/violin/dist/index.esm.min.js.map 
b/custom-series/violin/dist/index.esm.min.js.map
deleted file mode 100644
index 1864c0d..0000000
--- a/custom-series/violin/dist/index.esm.min.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"file":"index.esm.min.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
\ No newline at end of file
diff --git a/custom-series/violin/dist/index.esm.min.js 
b/custom-series/violin/dist/index.esm.min.mjs
similarity index 98%
rename from custom-series/violin/dist/index.esm.min.js
rename to custom-series/violin/dist/index.esm.min.mjs
index 39fd859..6896eba 100644
--- a/custom-series/violin/dist/index.esm.min.js
+++ b/custom-series/violin/dist/index.esm.min.mjs
@@ -17,4 +17,4 @@
 * under the License.
 */
 function epanechnikovKernel(e){return Math.abs(e)<=1?.75*(1-e*e):0}function 
kernelDensityEstimator(e,n,t){return function(a){for(var 
i=0,r=0;r<t.length;r++)i+=e((a-t[r])/n);return i/(t.length*n)}}var 
renderItem=function(e,n){var 
t={};if(null==e.context.violins){e.context.violins=[],t=e.context.violins;for(var
 a=e.dataInsideLength,i=0;i<a;++i){var 
r=n.value(0,i);null==t[r]&&(t[r]={firstDataIndex:i,data:[]}),t[r].data.push(n.value(1,i))}}else
 t=e.context.violins;e.itemPayload.symbolSize;va [...]
-//# sourceMappingURL=index.esm.min.js.map
+//# sourceMappingURL=index.esm.min.mjs.map
diff --git a/custom-series/violin/dist/index.esm.min.mjs.map 
b/custom-series/violin/dist/index.esm.min.mjs.map
new file mode 100644
index 0000000..671f88a
--- /dev/null
+++ b/custom-series/violin/dist/index.esm.min.mjs.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.esm.min.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;"}
\ No newline at end of file
diff --git a/custom-series/violin/dist/index.esm.js 
b/custom-series/violin/dist/index.esm.mjs
similarity index 100%
rename from custom-series/violin/dist/index.esm.js
rename to custom-series/violin/dist/index.esm.mjs
diff --git a/custom-series/violin/examples/index.html 
b/custom-series/violin/examples/index.html
index 78ef3fd..4ed7a32 100644
--- a/custom-series/violin/examples/index.html
+++ b/custom-series/violin/examples/index.html
@@ -48,7 +48,6 @@
       }
 
       option = {
-        animation: 0,
         tooltip: {
           show: true,
         },
diff --git a/custom-series/violin/package-lock.json 
b/custom-series/violin/package-lock.json
index f0fc677..bf55c33 100644
--- a/custom-series/violin/package-lock.json
+++ b/custom-series/violin/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "@echarts-x/custom-violin",
-  "version": "1.0.1-beta.0",
+  "version": "1.0.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "@echarts-x/custom-violin",
-      "version": "1.0.1-beta.0",
+      "version": "1.0.0",
       "license": "Apache-2.0",
       "devDependencies": {
         "echarts": "^6.0.0",
diff --git a/custom-series/violin/package.json 
b/custom-series/violin/package.json
index b441d55..9105848 100644
--- a/custom-series/violin/package.json
+++ b/custom-series/violin/package.json
@@ -3,7 +3,15 @@
   "version": "1.0.0",
   "description": "Custom violin series for Apache ECharts",
   "main": "dist/index.js",
-  "module": "dist/index.esm.js",
+  "module": "dist/index.esm.mjs",
+  "exports": {
+    ".": {
+      "types": "./dist/index.d.ts",
+      "import": "./dist/index.esm.mjs",
+      "require": "./dist/index.js"
+    }
+  },
+  "types": "dist/index.d.ts",
   "keywords": [
     "echarts",
     "apache-echarts",
@@ -16,12 +24,11 @@
   "homepage": 
"https://github.com/apache/echarts-custom-series/tree/main/custom-series/violin";,
   "repository": {
     "type": "git",
-    "url": "https://github.com/apache/echarts-custom-series.git";,
-    "directory": "custom-series/violin"
+    "url": "git+https://github.com/apache/echarts-custom-series.git";
   },
   "scripts": {
-    "test:browser": "npx http-server test -p 8080 -o",
-    "test:ssr": "node test/ssr.js",
+    "test:browser": "npx http-server . -p 8088 -o examples/index.html",
+    "test:ssr": "node examples/ssr.js",
     "test": "npm run test:ssr"
   },
   "devDependencies": {
@@ -33,8 +40,7 @@
   },
   "files": [
     "dist",
-    "README.md",
-    "screenshots"
+    "README.md"
   ],
   "publishConfig": {
     "access": "public"
diff --git a/custom-series/violin/src/index.ts 
b/custom-series/violin/src/index.ts
index fa12abd..4c7ff7b 100644
--- a/custom-series/violin/src/index.ts
+++ b/custom-series/violin/src/index.ts
@@ -23,7 +23,10 @@ import type {
   CustomRootElementOption,
   CustomSeriesRenderItem,
 } from 'echarts/types/src/chart/custom/CustomSeries.d.ts';
-import type { EChartsExtensionInstallRegisters } from 
'echarts/types/src/extension.js';
+import type {
+  EChartsExtensionInstallRegisters,
+  EChartsExtension,
+} from 'echarts/types/src/extension.d.ts';
 
 function epanechnikovKernel(u: number) {
   return Math.abs(u) <= 1 ? 0.75 * (1 - u * u) : 0;
@@ -138,4 +141,4 @@ export default {
       renderItem as unknown as CustomSeriesRenderItem
     );
   },
-};
+} as EChartsExtension;
diff --git a/scripts/build.js b/scripts/build.js
index ccfec77..9e63505 100644
--- a/scripts/build.js
+++ b/scripts/build.js
@@ -61,14 +61,16 @@ function buildCustomSeries(dirName) {
 
   compileTypeScript(seriesPath, dirName);
   bundleWithRollup(seriesPath, dirName);
-  minifyWithTerser(seriesPath, dirName);
 }
 
 function compileTypeScript(seriesPath, dirName) {
   const tscPath = path.join(__dirname, '../node_modules/.bin/tsc');
   // Remove dir of lib
   if (fs.existsSync(path.join(seriesPath, 'lib'))) {
-    fs.rmSync(path.join(seriesPath, 'lib'), { recursive: true, force: true });
+    fs.rmSync(path.join(seriesPath, 'lib'), {
+      recursive: true,
+      force: true,
+    });
   }
 
   try {
@@ -83,8 +85,6 @@ function compileTypeScript(seriesPath, dirName) {
         --sourceMap \
         --moduleResolution node \
         --esModuleInterop \
-        --declaration \
-        --declarationMap false \
         --importHelpers \
         --pretty \
         --ignoreDeprecations 5.0 \
@@ -106,7 +106,7 @@ function compileTypeScript(seriesPath, dirName) {
 
 function bundleWithRollup(seriesPath, dirName) {
   const rollupPath = path.join(__dirname, '../node_modules/.bin/rollup');
-  const configPath = path.join(__dirname, 'rollup.config.js'); // 使用统一的 
rollup.config.js
+  const configPath = path.join(__dirname, 'rollup.config.js');
   const distPath = path.join(seriesPath, 'dist');
 
   // Create dist directory if it doesn't exist
@@ -119,19 +119,46 @@ function bundleWithRollup(seriesPath, dirName) {
     const env = {
       ...process.env,
       CUSTOM_SERIES_NAME: dirName,
-      CUSTOM_SERIES_PATH: seriesPath
+      CUSTOM_SERIES_PATH: seriesPath,
     };
 
-    execSync(
-      `${rollupPath} -c ${configPath}`,
-      { encoding: 'utf8', stdio: 'pipe', env, cwd: seriesPath }
-    );
-
-    console.log(`Rollup bundling completed for ${dirName}`);
+    execSync(`${rollupPath} -c ${configPath}`, {
+      encoding: 'utf8',
+      stdio: 'pipe',
+      env,
+      cwd: seriesPath,
+    });
 
-    // Check if the output file was created
-    if (!fs.existsSync(path.join(seriesPath, 'dist', 'index.js'))) {
-      console.error(`Error: Output file not created for ${dirName}`);
+    console.log(`Rollup bundling and minification completed for ${dirName}`);
+
+    // Create fixed type definition file in dist directory
+    const distTypesPath = path.join(seriesPath, 'dist', 'index.d.ts');
+    const fixedTypeDefinition = `// Tricky: use1 and use2 are incompatible.
+import type {use as use1} from 'echarts/core';
+import type {use as use2} from 'echarts';
+declare const _default: Parameters<typeof use1>[0] & Parameters<typeof 
use2>[0];
+export default _default;
+`;
+    fs.writeFileSync(distTypesPath, fixedTypeDefinition, 'utf8');
+    console.log(`Created fixed type definitions for ${dirName}`);
+
+    // Check if the output files were created
+    const expectedFiles = [
+      'index.js',
+      'index.min.js',
+      'index.auto.js',
+      'index.auto.min.js',
+      'index.esm.mjs',
+      'index.esm.min.mjs',
+      'index.d.ts',
+    ];
+
+    for (const file of expectedFiles) {
+      if (!fs.existsSync(path.join(seriesPath, 'dist', file))) {
+        console.warn(
+          chalk.yellow(`Warning: ${file} not created for ${dirName}`)
+        );
+      }
     }
   } catch (e) {
     console.error(`Error bundling custom series ${dirName}:`);
@@ -141,25 +168,6 @@ function bundleWithRollup(seriesPath, dirName) {
   }
 }
 
-function minifyWithTerser(seriesPath, dirName) {
-  const terserPath = path.join(__dirname, '../node_modules/.bin/terser');
-  try {
-    execSync(
-      `${terserPath} ${seriesPath}/dist/index.js \
-          --compress \
-          --mangle \
-          --ecma 3 \
-          --comments all \
-          --source-map \
-          --output ${seriesPath}/dist/index.min.js`
-    );
-    console.log(`Minified custom series ${dirName} using Terser`);
-  } catch (e) {
-    console.error(`Error minifying custom series ${dirName}:`);
-    console.error(e.message);
-  }
-}
-
 /**
  * `npm run build` to build all
  * `npm run build <series-name>` to build one custom series
diff --git a/scripts/generate.js b/scripts/generate.js
index 6300a25..b33ed65 100644
--- a/scripts/generate.js
+++ b/scripts/generate.js
@@ -81,7 +81,10 @@ function replaceCustomSeriesName(filePath, name, 
kebabCaseName) {
       kebabCaseName
     );
     const pascalCase = name.charAt(0).toUpperCase() + name.slice(1);
-    newContent = newContent.replace(/\$CUSTOM_SERIES_PASCAL_NAME\$/g, 
pascalCase);
+    newContent = newContent.replace(
+      /\$CUSTOM_SERIES_PASCAL_NAME\$/g,
+      pascalCase
+    );
     fs.writeFileSync(filePath, newContent);
   }
 }
diff --git a/scripts/rollup.config.js b/scripts/rollup.config.js
index d198e5c..0aaf27b 100644
--- a/scripts/rollup.config.js
+++ b/scripts/rollup.config.js
@@ -1,25 +1,24 @@
 /*
-* 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.
-*/
+ * 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.
+ */
 
 const path = require('path');
 
-// 从环境变量获取自定义系列名称和路径
 const seriesName = process.env.CUSTOM_SERIES_NAME || 'customSeries';
 const seriesPath = process.env.CUSTOM_SERIES_PATH || '.';
 
@@ -46,7 +45,7 @@ const licenseHeader = `/*
 
 const baseConfig = {
   input: path.join(seriesPath, 'lib/index.js'),
-  plugins: []
+  plugins: [],
 };
 
 const autoRegisterFooter = `
@@ -70,8 +69,37 @@ const autoRegisterPlugin = {
   },
 };
 
+const terserPlugin = {
+  name: 'terser-minify',
+  async renderChunk(code, chunk, options) {
+    if (options.file && options.file.includes('.min.')) {
+      // 动态导入 terser 避免初始化问题
+      const { minify } = require('terser');
+      const result = await minify(code, {
+        compress: {
+          ecma: 3,
+          drop_console: false,
+          drop_debugger: true,
+          pure_funcs: ['console.log'],
+        },
+        mangle: true,
+        format: {
+          comments: 'all',
+          ecma: 3,
+        },
+        sourceMap: true,
+      });
+      return {
+        code: result.code,
+        map: result.map,
+      };
+    }
+    return null;
+  },
+};
+
 module.exports = [
-  // UMD version - 需要手动注册
+  // UMD version
   {
     ...baseConfig,
     output: {
@@ -86,11 +114,27 @@ module.exports = [
     plugins: [licensePlugin],
   },
 
-  // Browser IIFE version - 自动注册
+  // UMD minified version
   {
     ...baseConfig,
     output: {
-      file: path.join(seriesPath, 'dist/index.browser.js'),
+      file: path.join(seriesPath, 'dist/index.min.js'),
+      format: 'umd',
+      name: `${seriesName}CustomSeriesInstaller`,
+      extend: true,
+      globals: {
+        window: 'window',
+      },
+      sourcemap: true,
+    },
+    plugins: [licensePlugin, terserPlugin],
+  },
+
+  // Browser version - automatically registers
+  {
+    ...baseConfig,
+    output: {
+      file: path.join(seriesPath, 'dist/index.auto.js'),
       format: 'iife',
       name: `${seriesName}CustomSeriesInstaller`,
       extend: true,
@@ -101,23 +145,40 @@ module.exports = [
     plugins: [autoRegisterPlugin],
   },
 
-  // ES Module version - 需要手动注册
+  // Browser minified version - automatically registers
   {
     ...baseConfig,
     output: {
-      file: path.join(seriesPath, 'dist/index.esm.js'),
+      file: path.join(seriesPath, 'dist/index.auto.min.js'),
+      format: 'iife',
+      name: `${seriesName}CustomSeriesInstaller`,
+      extend: true,
+      globals: {
+        window: 'window',
+      },
+      sourcemap: true,
+    },
+    plugins: [autoRegisterPlugin, terserPlugin],
+  },
+
+  // ES Module version
+  {
+    ...baseConfig,
+    output: {
+      file: path.join(seriesPath, 'dist/index.esm.mjs'),
       format: 'esm',
     },
     plugins: [licensePlugin],
   },
 
-  // CommonJS version - 需要手动注册
+  // ES Module minified version
   {
     ...baseConfig,
     output: {
-      file: path.join(seriesPath, 'dist/index.cjs.js'),
-      format: 'cjs',
+      file: path.join(seriesPath, 'dist/index.esm.min.mjs'),
+      format: 'esm',
+      sourcemap: true,
     },
-    plugins: [licensePlugin],
-  }
+    plugins: [licensePlugin, terserPlugin],
+  },
 ];
diff --git a/scripts/serve.js b/scripts/serve.js
index 8ecc906..03a113d 100644
--- a/scripts/serve.js
+++ b/scripts/serve.js
@@ -69,7 +69,7 @@ function startServer() {
     return;
   }
 
-  const port = 8081;
+  const port = 8087;
   const serverProcess = exec(`http-server ${seriesPath} -p ${port}`);
 
   // Add file watcher
@@ -90,7 +90,7 @@ function startServer() {
           : process.platform === 'win32'
           ? 'start'
           : 'xdg-open';
-      const url = `http://localhost:${port}/test/index.html`;
+      const url = `http://localhost:${port}/examples/index.html`;
       exec(`${open} ${url}`, (error) => {
         if (error) {
           console.error(chalk.red(`Failed to open browser: ${error}`));
diff --git a/scripts/template/README.md b/scripts/template/README.md
index 5696ed4..440ea00 100644
--- a/scripts/template/README.md
+++ b/scripts/template/README.md
@@ -1,37 +1,61 @@
-# $CUSTOM_SERIES_NAME$
+# @echarts-x/custom-$CUSTOM_SERIES_NAME$
 
 `$CUSTOM_SERIES_NAME$` is a custom series for [Apache 
ECharts](https://github.com/apache/echarts). It's typically used to ...
 
-![$CUSTOM_SERIES_NAME$](../../screenshots/$CUSTOM_SERIES_NAME$.svg)
+![$CUSTOM_SERIES_NAME$](https://raw.githubusercontent.com/apache/echarts-custom-series/main/custom-series/$CUSTOM_SERIES_KEBAB_NAME$/screenshots/$CUSTOM_SERIES_NAME$.svg)
+
+[Source 
Code](https://github.com/apache/echarts-custom-series/tree/main/custom-series/$CUSTOM_SERIES_NAME$)
 
 ## Usage
 
-Import the custom series JavaScript file and ECharts, then use `echarts.use` 
to install it.
+### Browser Environment
+
+For browser usage, use the auto-registration version that automatically 
installs the custom series when loaded:
 
 ```html
 <script src="./node_modules/echarts/dist/echarts.js"></script>
-<script src="./dist/index.js"></script>
+<script 
src="./node_modules/@echarts-x/custom-$CUSTOM_SERIES_KEBAB_NAME$/dist/index.auto.js"></script>
 <script>
-  echarts.use(window.$CUSTOM_SERIES_NAME$CustomSeriesInstaller);
+  // No need to call echarts.use(), automatically registered
   const chart = echarts.init(...);
   // ...
 </script>
 ```
 
-Or, if using module bundler, install the package from npm and import it.
+### UMD (Universal Module Definition)
+
+For environments that need manual registration or when using AMD/CommonJS 
loaders:
+
+```js
+// CommonJS
+const echarts = require('echarts');
+const $CUSTOM_SERIES_NAME$Installer = 
require('@echarts-x/custom-$CUSTOM_SERIES_KEBAB_NAME$');
+echarts.use($CUSTOM_SERIES_NAME$Installer);
+const chart = echarts.init(...);
+// ...
+
+// AMD
+require(['echarts', '@echarts-x/custom-$CUSTOM_SERIES_KEBAB_NAME$'], 
function(echarts, $CUSTOM_SERIES_NAME$Installer) {
+  echarts.use($CUSTOM_SERIES_NAME$Installer);
+});
+```
+
+### ESM (ES Modules)
+
+For modern module bundlers or native ES module environments:
 
 ```bash
-npm install @echarts/custom-$CUSTOM_SERIES_KEBAB_NAME$
+npm install @echarts-x/custom-$CUSTOM_SERIES_KEBAB_NAME$
 ```
 
 ```js
-import echarts from 'echarts';
-import $CUSTOM_SERIES_NAME$CustomSeriesInstaller from 
'@echarts/custom-$CUSTOM_SERIES_KEBAB_NAME$';
+import * as echarts from 'echarts';
+import $CUSTOM_SERIES_NAME$CustomSeriesInstaller from 
'@echarts-x/custom-$CUSTOM_SERIES_KEBAB_NAME$';
 
 echarts.use($CUSTOM_SERIES_NAME$CustomSeriesInstaller);
 ```
 
-See [test](./test/index.html) for more details.
+See [examples](./examples) for more details.
 
 ## API
 
@@ -61,5 +85,3 @@ encode: {
     tooltip: 2
 }
 ```
-
-See [test](./test/index.html) for more details.
diff --git a/custom-series/violin/examples/index.html 
b/scripts/template/examples/index.html
similarity index 52%
copy from custom-series/violin/examples/index.html
copy to scripts/template/examples/index.html
index 78ef3fd..573b600 100644
--- a/custom-series/violin/examples/index.html
+++ b/scripts/template/examples/index.html
@@ -33,59 +33,16 @@
     <script src="../node_modules/echarts/dist/echarts.js"></script>
     <script src="../dist/index.auto.js"></script>
     <script>
-      const chart = echarts.init(document.getElementById('main'), null, {
-        renderer: 'svg',
-      });
-
-      const xData = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
-      const dataSource = [['Day', 'value']];
-      for (let i = 0; i < xData.length; ++i) {
-        const dataCount = 10 * Math.round(Math.random() * 5) + 5;
-        for (let j = 0; j < dataCount; ++j) {
-          const value = Math.tan(i) / 2 + 3 * Math.random() + 2;
-          dataSource.push([xData[i], value]);
-        }
-      }
+      echarts.use(window.$CUSTOM_SERIES_NAME$CustomSeriesInstaller);
+      const chart = echarts.init(document.getElementById('main'));
 
       option = {
-        animation: 0,
-        tooltip: {
-          show: true,
-        },
-        xAxis: {
-          type: 'category',
-          data: xData,
-          jitter: 100,
-          jitterOverlap: false,
-        },
-        yAxis: {},
-        dataset: {
-          source: dataSource,
+        series: {
+          type: 'custom',
+          renderItem: '$CUSTOM_SERIES_NAME$',
+          coordinateSystem: 'none',
+          itemPayload: {},
         },
-        series: [
-          {
-            type: 'custom',
-            renderItem: 'violin',
-            colorBy: 'item',
-            silent: true,
-            itemPayload: {
-              symbolSize: 4,
-              areaOpacity: 0.6,
-              bandWidthScale: 1.5,
-              // binCount: 20
-            },
-          },
-          {
-            type: 'scatter',
-            encode: {
-              x: 0,
-              y: 1,
-            },
-            colorBy: 'item',
-            silent: true,
-            symbolSize: 6,
-          },
-        ],
       };
 
       chart.setOption(option);
diff --git a/scripts/template/examples/ssr.js b/scripts/template/examples/ssr.js
new file mode 100644
index 0000000..0d2d7a3
--- /dev/null
+++ b/scripts/template/examples/ssr.js
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+const echarts = require('echarts');
+const $CUSTOM_SERIES_NAME$Installer = require('../dist/index.js');
+
+echarts.use($CUSTOM_SERIES_NAME$Installer);
+
+const chart = echarts.init(null, null, {
+  renderer: 'svg',
+  ssr: true,
+  width: 600,
+  height: 400,
+});
+
+// Set up seeded random for consistent thumbnails
+const seedrandom = require('seedrandom');
+const myRandom = new seedrandom('echarts-random');
+Math.random = function () {
+  return myRandom();
+};
+
+// Sample data generation - customize this for your specific chart type
+const sampleData = [];
+// TODO: Generate appropriate sample data for $CUSTOM_SERIES_NAME$
+
+const option = {
+  animation: false,
+  tooltip: {
+    show: false,
+  },
+  // TODO: Configure axes and other options specific to $CUSTOM_SERIES_NAME$
+  series: [
+    {
+      type: 'custom',
+      renderItem: '$CUSTOM_SERIES_NAME$',
+      data: sampleData,
+      silent: true,
+      itemPayload: {
+        // TODO: Add specific itemPayload properties for $CUSTOM_SERIES_NAME$
+      },
+    },
+  ],
+};
+
+chart.setOption(option);
+
+const svg = chart.renderToSVGString();
+console.log(svg);
+
+chart.dispose();
diff --git a/scripts/template/package.json b/scripts/template/package.json
index 0f5343e..547ed7e 100644
--- a/scripts/template/package.json
+++ b/scripts/template/package.json
@@ -1,18 +1,48 @@
 {
-  "name": "@echarts/custom-template",
-  "version": "0.0.1-beta.1",
-  "description": "",
+  "name": "@echarts-x/custom-$CUSTOM_SERIES_NAME$",
+  "version": "1.0.0-beta.0",
+  "description": "Custom $CUSTOM_SERIES_NAME$ series for Apache ECharts",
   "main": "dist/index.js",
-  "scripts": {
-    "build": "tsc"
+  "module": "dist/index.esm.mjs",
+  "exports": {
+    ".": {
+      "types": "./dist/index.d.ts",
+      "import": "./dist/index.esm.mjs",
+      "require": "./dist/index.js"
+    }
   },
-  "keywords": [],
+  "types": "dist/index.d.ts",
+  "keywords": [
+    "echarts",
+    "apache-echarts",
+    "data-visualization",
+    "chart",
+    "dataviz"
+  ],
   "author": "",
   "license": "Apache-2.0",
-  "dependencies": {
-    "echarts": "github:apache/echarts#v6"
+  "homepage": 
"https://github.com/apache/echarts-custom-series/tree/main/custom-series/violin";,
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/apache/echarts-custom-series.git";
+  },
+  "scripts": {
+    "test:browser": "npx http-server . -p 8088 -o examples/index.html",
+    "test:ssr": "node examples/ssr.js",
+    "test": "npm run test:ssr"
   },
   "devDependencies": {
+    "echarts": "^6.0.0",
     "typescript": "^5.5.4"
+  },
+  "peerDependencies": {
+    "echarts": "^6.0.0"
+  },
+  "files": [
+    "dist",
+    "README.md"
+  ],
+  "publishConfig": {
+    "access": "public"
   }
 }
diff --git a/scripts/template/rollup.config.js 
b/scripts/template/rollup.config.js
deleted file mode 100644
index 44ccfb5..0000000
--- a/scripts/template/rollup.config.js
+++ /dev/null
@@ -1,38 +0,0 @@
-module.exports = {
-  input: 'lib/index.js',
-  output: {
-    file: 'dist/index.js',
-    format: 'umd',
-    name: '$CUSTOM_SERIES_NAME$CustomSeriesInstaller',
-    extend: true,
-    globals: {
-      window: 'window',
-    },
-  },
-  plugins: [
-    {
-      name: 'add-license',
-      renderChunk(code) {
-        return `/*
-* 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.
-*/
-${code}`;
-      },
-    },
-  ],
-};
diff --git a/scripts/template/src/index.ts b/scripts/template/src/index.ts
index fa5ee96..38a2e3e 100644
--- a/scripts/template/src/index.ts
+++ b/scripts/template/src/index.ts
@@ -17,22 +17,24 @@
  * under the License.
  */
 
-import echarts from 'echarts';
+import * as echarts from 'echarts';
 import type {
   CustomRootElementOption,
   CustomSeriesRenderItem,
 } from 'echarts/types/src/chart/custom/CustomSeries.d.ts';
-import type { EChartsExtensionInstallRegisters } from 
'echarts/src/extension.ts';
-
-type $CUSTOM_SERIES_PASCAL_NAME$ItemPayload = {
+import type {
+  EChartsExtensionInstallRegisters,
+  EChartsExtension,
+} from 'echarts/types/src/extension.d.ts';
 
-};
+type $CUSTOM_SERIES_PASCAL_NAME$ItemPayload = {};
 
 const renderItem = (
   params: echarts.CustomSeriesRenderItemParams,
   api: echarts.CustomSeriesRenderItemAPI
 ) => {
-  const itemPayload = params.itemPayload as 
$CUSTOM_SERIES_PASCAL_NAME$ItemPayload;
+  const itemPayload =
+    params.itemPayload as $CUSTOM_SERIES_PASCAL_NAME$ItemPayload;
 
   const cnt = params.dataInsideLength;
   if (params.dataIndex === cnt - 1) {
@@ -51,4 +53,4 @@ export default {
       renderItem as unknown as CustomSeriesRenderItem
     );
   },
-};
+} as EChartsExtension;
diff --git a/scripts/template/test/index.html b/scripts/template/test/index.html
deleted file mode 100644
index 72a6fb1..0000000
--- a/scripts/template/test/index.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Apache ECharts Custom Series Test</title>
-</head>
-
-<body>
-    <div id="main" style="width: 1000px;height:400px;border:1px solid 
#ccc"></div>
-
-    <script src="../node_modules/echarts/dist/echarts.js"></script>
-    <script src="../dist/index.js"></script>
-    <script>
-        echarts.use(window.$CUSTOM_SERIES_NAME$CustomSeriesInstaller);
-        const chart = echarts.init(document.getElementById('main'));
-
-        option = {
-            series: {
-                type: 'custom',
-                renderItem: '$CUSTOM_SERIES_NAME$',
-                coordinateSystem: 'none',
-                itemPayload: {
-                }
-            }
-        };
-
-        chart.setOption(option);
-    </script>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/scripts/thumbnail.js b/scripts/thumbnail.js
index 9ef2223..49406e5 100644
--- a/scripts/thumbnail.js
+++ b/scripts/thumbnail.js
@@ -19,85 +19,81 @@
 
 const fs = require('fs');
 const path = require('path');
-const echarts = require('echarts');
 const chalk = require('chalk');
-const seedrandom = require('seedrandom');
-
-/** Use seed to make sure each time data is the same when making thumbnails */
-let myRandom = new seedrandom('echarts-random');
-// Fixed random generator
-Math.random = function () {
-  const val = myRandom();
-  return val;
-};
 
 /**
  * Generate a thumbnail for the custom series using SVG SSR.
  */
 async function thumbnail(seriesName) {
   const seriesPath = path.join(__dirname, '..', 'custom-series', seriesName);
-  const testPath = path.join(seriesPath, 'test', 'index.html');
-  const outputPath = path.join('./screenshots', `${seriesName}.svg`);
+  const ssrPath = path.join(seriesPath, 'examples', 'ssr.js');
 
-  // Install the custom series
-  const customSeries = require(`../custom-series/${seriesName}`);
-  echarts.use(customSeries);
+  // Create screenshots directory inside the series folder
+  const screenshotsDir = path.join(seriesPath, 'screenshots');
+  if (!fs.existsSync(screenshotsDir)) {
+    fs.mkdirSync(screenshotsDir, { recursive: true });
+  }
 
-  let chart = echarts.init(null, null, {
-    renderer: 'svg',
-    ssr: true,
-    width: 600,
-    height: 400,
-  });
+  const outputPath = path.join(screenshotsDir, `${seriesName}.svg`);
 
-  // Load the js code from the content of the last <script></script>
-  // in 'test/index.html'
-  const html = fs.readFileSync(testPath, 'utf8');
-  const lastScriptStartIndex = html.lastIndexOf('<script>');
-  const lastScriptEndIndex = html.lastIndexOf('</script>');
-  const jsCode = html.substring(lastScriptStartIndex + 8, lastScriptEndIndex);
+  // Check if ssr.js exists
+  if (!fs.existsSync(ssrPath)) {
+    console.error(
+      chalk.red(`ssr.js not found for ${seriesName} at ${ssrPath}`)
+    );
+    return;
+  }
 
-  // Ignore the lines containing `echarts.use`, `echarts.init` and `.setOption`
-  // TODO: Not considered the case where there are multiple `chart.setOption`
-  // calls
-  const lines = jsCode.split('\n');
-  const code = lines
-    .filter(
-      (line) =>
-        !line.includes('echarts.use') &&
-        !line.includes('echarts.init') &&
-        !line.includes('chart.setOption')
-    )
-    .join('\n');
+  const { spawn } = require('child_process');
 
-  // Run the code
   try {
-    // Load d3 and d3-contour using dynamic import
-    const d3 = await import('d3');
-    const d3Contour = await import('d3-contour');
+    // Run the ssr.js file and capture its output
+    const child = spawn('node', [ssrPath], {
+      cwd: seriesPath,
+      stdio: ['pipe', 'pipe', 'pipe'],
+    });
 
-    // Assign d3 and d3Contour to the global object
-    globalThis.d3 = d3;
-    globalThis.d3Contour = d3Contour;
+    let svgOutput = '';
+    let errorOutput = '';
 
-    eval(code);
-    // To make sure text is readable in dark mode
-    option.backgroundColor = '#fff';
-    chart.setOption(option);
-  } catch (error) {
-    console.error(chalk.red(error.stack));
-    console.info(chalk.blue(code));
-    return;
-  }
+    child.stdout.on('data', (data) => {
+      svgOutput += data.toString();
+    });
+
+    child.stderr.on('data', (data) => {
+      errorOutput += data.toString();
+    });
+
+    child.on('close', (code) => {
+      if (code !== 0) {
+        console.error(
+          chalk.red(`ssr.js failed for ${seriesName} with code ${code}`)
+        );
+        if (errorOutput) {
+          console.error(chalk.red(errorOutput));
+        }
+        return;
+      }
 
-  const svg = chart.renderToSVGString();
+      // Extract SVG content from output (in case there are other console logs)
+      const svgMatch = svgOutput.match(/<svg[\s\S]*<\/svg>/);
+      if (!svgMatch) {
+        console.error(chalk.red(`No SVG output found for ${seriesName}`));
+        return;
+      }
 
-  chart.dispose();
-  chart = null;
-  option = null;
+      const svg = svgMatch[0];
 
-  // Save the SVG to file
-  fs.writeFileSync(outputPath, svg);
+      // Save the SVG to file
+      fs.writeFileSync(outputPath, svg);
+      console.log(
+        chalk.green(`Thumbnail generated for ${seriesName}: ${outputPath}`)
+      );
+    });
+  } catch (error) {
+    console.error(chalk.red(`Error running ssr.js for ${seriesName}:`));
+    console.error(chalk.red(error.stack));
+  }
 }
 
 const args = process.argv.slice(2);


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

Reply via email to