complete custom series during extra.
diff --git a/en/option/partial/zr-graphic.md b/en/option/partial/zr-graphic.md
index 9da1d5d..a9a37f2 100644
--- a/en/option/partial/zr-graphic.md
+++ b/en/option/partial/zr-graphic.md
@@ -1330,6 +1330,20 @@
 
 Whether the element is totally ignored (neither render nor listen events).
 
+{{ if: ${usageType} === 'customSeries' }}
+{{ use: partial-custom-series-during(
+    prefix = ${prefix}
+) }}
+{{ use: partial-custom-series-extra(
+    prefix = ${prefix},
+    optionPath = ${optionPath},
+    usageType = ${usageType},
+    hostName = ${hostName},
+    symbolVisit = ${symbolVisit},
+    symbolDeclare = ${symbolDeclare}
+) }}
+{{ /if }}
+
 {{ if: ${usageType} === 'graphicComponent' }}
 {{ use: partial-cursor(
     prefix = "##"
@@ -1797,3 +1811,105 @@
 [arc](~${optionPath}.${hostName}${symbolVisit}arc),
 [group](~${optionPath}.${hostName}${symbolVisit}group),
 
+
+
+{{ target: partial-custom-series-extra }}
+
+##${prefix} extra(Object)
+
+Users can define their own props in this `extra` field. See [during](option.html#series-custom.renderItem.return_rect.during) for the major usage of `extra`.
+
+{{ use: partial-graphic-cpt-sub-prop-transition(
+    prefix = ${prefix},
+    hostProp = 'extra',
+    optionPath = ${optionPath},
+    usageType = ${usageType},
+    hostName = ${hostName},
+    symbolVisit = ${symbolVisit},
+    symbolDeclare = ${symbolDeclare}
+) }}
+
+
+
+{{ target: partial-custom-series-during }}
+
+##${prefix} during(Function)
+
+`during` callback enable users to set props to an element in each animation frame.
+
+```js
+(duringAPI: CustomDuringAPI) => void
+
+interface CustomDuringAPI {
+    // Set transform prop value.
+    // Transform prop see `TransformProp`.
+    setTransform(key: TransformProp, val: unknown): void;
+    // Get transform prop value of the current animation frame.
+    getTransform(key: TransformProp): unknown;
+    // Set shape prop value.
+    // Shape prop is like `{ type: 'rect', shape: { xxxProp: xxxValue } }`.
+    setShape(key: string, val: unknown): void;
+    // Get shape prop value of the current animation frame.
+    getShape(key: string): unknown;
+    // Set style prop value.
+    // Style prop is like `{ type: 'rect', style: { xxxProp: xxxValue } }`.
+    setStyle(key: string, val: unknown): void;
+    // Get style prop value of the current animation frame.
+    getStyle(key: string): unknown;
+    // Set extra prop value.
+    // Extra prop is like `{ type: 'rect', extra: { xxxProp: xxxValue } }`.
+    setExtra(key: string, val: unknown): void;
+    // Get extra prop value of the current animation frame.
+    getExtra(key: string): unknown;
+}
+
+type TransformProp =
+    'x' | 'y' | 'scaleX' | 'scaleY' | 'originX' | 'originY' | 'rotation';
+```
+
+In most cases users do not need this `during` callback. For example, if some props are specified in [transition](option.html#series-custom.renderItem.return_rect.transition), echarts will make interpolation for these props internally and therefore have animation based on these props automatically. But if this kind of internal interpolation does not match the user requirements of animation, users can use this `during` callback to customize them.
+
+For example, if users are using [polygon](option.html#series-custom.renderItem.return_polygon) shape. The shape is described by [shape.points](option.html#series-custom.renderItem.return_polygon.shape.points), which is an points array like:
+```js
+{
+    type: 'polygon',
+    shape: {
+        points: [[12, 33], [15, 36], [19, 39], ...]
+    },
+    // ...
+}
+```
+If users specify them into [transition](option.html#series-custom.renderItem.return_polygon.transition) like:
+```js
+{
+    type: 'polygon',
+    shape: {
+        points: [[12, 33], [15, 36], [19, 39], ...],
+    },
+    transition: 'shape'
+    // ...
+}
+```
+Although the points will be interpolated, the consequent animation will be like that each point runs straight to the target position, which might do not match the user requirement if some kind of track like spiral is actually needed. In this case, users can use the `during` callback like that:
+```js
+{
+    type: 'polygon',
+    shape: {
+        points: calculatePoints(initialDegree),
+        transition: 'points'
+    },
+    extra: {
+        degree: nextDegree
+    },
+    // Make echarts interpolate `extra.degree` internally, based on which
+    // we calculate the `points` in each animation frame.
+    transition: 'extra',
+    during: function (duringAPI) {
+        var currentDegree = duringAPI.getExtra('degree');
+        duringAPI.setShape(calculatePoints(currentDegree));
+    }
+    // ...
+}
+```
+
+See this example [example](${galleryEditorPath}custom-spiral-race&edit=1&reset=1).
diff --git a/zh/option/partial/zr-graphic.md b/zh/option/partial/zr-graphic.md
index 27f280b..311c354 100644
--- a/zh/option/partial/zr-graphic.md
+++ b/zh/option/partial/zr-graphic.md
@@ -1315,6 +1315,20 @@
 
 节点是否完全被忽略(既不渲染,也不响应事件)。
 
+{{ if: ${usageType} === 'customSeries' }}
+{{ use: partial-custom-series-during(
+    prefix = ${prefix}
+) }}
+{{ use: partial-custom-series-extra(
+    prefix = ${prefix},
+    optionPath = ${optionPath},
+    usageType = ${usageType},
+    hostName = ${hostName},
+    symbolVisit = ${symbolVisit},
+    symbolDeclare = ${symbolDeclare}
+) }}
+{{ /if }}
+
 {{ if: ${usageType} === 'graphicComponent' }}
 {{ use: partial-cursor(
     prefix = "##"
@@ -1778,3 +1792,105 @@
 [arc](~${optionPath}.${hostName}${symbolVisit}arc),
 [group](~${optionPath}.${hostName}${symbolVisit}group),
 
+
+
+{{ target: partial-custom-series-extra }}
+
+##${prefix} extra(Object)
+
+用户可以在 `extra` 字段中定义自己的属性。`extra` 的往往会结合 [during](option.html#series-custom.renderItem.return_rect.during) 一起使用。
+
+{{ use: partial-graphic-cpt-sub-prop-transition(
+    prefix = ${prefix},
+    hostProp = 'extra',
+    optionPath = ${optionPath},
+    usageType = ${usageType},
+    hostName = ${hostName},
+    symbolVisit = ${symbolVisit},
+    symbolDeclare = ${symbolDeclare}
+) }}
+
+
+
+{{ target: partial-custom-series-during }}
+
+##${prefix} during(Function)
+
+在动画的每一帧里,用户可以使用 `during` 回调来设定节点的各种属性。
+
+```js
+(duringAPI: CustomDuringAPI) => void
+
+interface CustomDuringAPI {
+    // 设置 transform 属性值。
+    // transform 属性参见 `TransformProp`。
+    setTransform(key: TransformProp, val: unknown): void;
+    // 获得当前动画帧的 transform 属性值。
+    getTransform(key: TransformProp): unknown;
+    // 设置 shape 属性值。
+    // shape 属性形如:`{ type: 'rect', shape: { xxxProp: xxxValue } }`。
+    setShape(key: string, val: unknown): void;
+    // 获得当前动画帧的 shape 属性值。
+    getShape(key: string): unknown;
+    // 设置 style 属性值。
+    // style 属性形如:`{ type: 'rect', style: { xxxProp: xxxValue } }`。
+    setStyle(key: string, val: unknown): void;
+    // 获得当前动画帧的 style 属性值。
+    getStyle(key: string): unknown;
+    // 设置 extra 属性值。
+    // extra 属性形如:`{ type: 'rect', extra: { xxxProp: xxxValue } }`。
+    setExtra(key: string, val: unknown): void;
+    // 获得当前动画帧的 extra 属性值。
+    getExtra(key: string): unknown;
+}
+
+type TransformProp =
+    'x' | 'y' | 'scaleX' | 'scaleY' | 'originX' | 'originY' | 'rotation';
+```
+
+在绝大多数场景下,用户不需要这个 `during` 回调。因为,假如属性被设定到 [transition](option.html#series-custom.renderItem.return_rect.transition) 中后,echarts 会自动对它进行插值,并且基于这些插值形成动画。但是,如果这些插值形成的动画不满足用户需求,那么用户可以使用 `during` 回调来定制他们。
+
+例如,如果用户使用 [polygon](option.html#series-custom.renderItem.return_polygon) 画图形,图形的形状会由 [shape.points](option.html#series-custom.renderItem.return_polygon.shape.points) 来定义,形如:
+```js
+{
+    type: 'polygon',
+    shape: {
+        points: [[12, 33], [15, 36], [19, 39], ...]
+    },
+    // ...
+}
+```
+如果用户指定了 [transition](option.html#series-custom.renderItem.return_polygon.transition) 如:
+```js
+{
+    type: 'polygon',
+    shape: {
+        points: [[12, 33], [15, 36], [19, 39], ...],
+    },
+    transition: 'shape'
+    // ...
+}
+```
+尽管这些 `points` 会被 echarts 自动插值,但是这样形成的动画里,这些点会直线走向目标位置。假如用户需求是,这些点要按照某种特定的路径(如弧线、螺旋)来移动,则这就不满足了。所以在这种情况下,可以使用 `during` 回调如下:
+```js
+{
+    type: 'polygon',
+    shape: {
+        points: calculatePoints(initialDegree),
+        transition: 'points'
+    },
+    extra: {
+        degree: nextDegree
+    },
+    // 让 echarts 对 `extra.degree` 进行插值,然后基于
+    // `extra.degree` 来计算动画中每一帧时的 polygon 形状。
+    transition: 'extra',
+    during: function (duringAPI) {
+        var currentDegree = duringAPI.getExtra('degree');
+        duringAPI.setShape(calculatePoints(currentDegree));
+    }
+    // ...
+}
+```
+
+也参见这个 [例子](${galleryEditorPath}custom-spiral-race&edit=1&reset=1)。