You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2020/06/02 17:54:38 UTC
[incubator-echarts] 08/10: chore: tweak and make better example for
tutorial.
This is an automated email from the ASF dual-hosted git repository.
sushuang pushed a commit to branch custom-series-enhance
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit d0315f25e9a4e6b8bcf86b76b2d5eb3e8a47c61d
Author: 100pah <su...@gmail.com>
AuthorDate: Thu May 21 22:43:10 2020 +0800
chore: tweak and make better example for tutorial.
---
src/chart/custom.ts | 9 +-
test/custom-feature.html | 483 ----------------------------------
test/custom-transition.html | 627 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 633 insertions(+), 486 deletions(-)
diff --git a/src/chart/custom.ts b/src/chart/custom.ts
index cfb9587..7af3ec0 100644
--- a/src/chart/custom.ts
+++ b/src/chart/custom.ts
@@ -286,7 +286,8 @@ const Z2_SPECIFIED_BIT = {
emphasis: 1
} as const;
-const tmpDuringElProps = { style: {} } as CustomDuringElProps;
+const tmpDuringStyle = {} as CustomDuringElProps['style'];
+const tmpDuringElProps = {} as CustomDuringElProps;
export type PrepareCustomInfo = (coordSys: CoordinateSystem) => {
coordSys: CustomSeriesRenderItemParamsCoordSys;
@@ -696,7 +697,9 @@ function elUpdateDuringAnimation(this: Element, key: string): void {
// PENDING:
// Do not expose other style in case that is not stable.
const isText = this.type === 'text';
- const textCurr = tmpDuringElProps.style.text = isText ? thisText.style.text : null;
+ // Always assign in case that user modify `.style`.
+ tmpDuringElProps.style = tmpDuringStyle;
+ const textCurr = tmpDuringStyle.text = isText ? thisText.style.text : null;
customDuring(tmpDuringElProps);
@@ -711,7 +714,7 @@ function elUpdateDuringAnimation(this: Element, key: string): void {
tmpDuringElProps.rotation !== rotationCurr && (this.rotation = tmpDuringElProps.rotation);
if (isText) {
- const currTmpStl = tmpDuringElProps.style;
+ const currTmpStl = tmpDuringElProps.style; // Allow user modify `.style`.
currTmpStl && currTmpStl.text !== textCurr && (thisText.style.text = currTmpStl.text, dirtyStyle = true);
}
diff --git a/test/custom-feature.html b/test/custom-feature.html
index dabf8b1..cee7c53 100644
--- a/test/custom-feature.html
+++ b/test/custom-feature.html
@@ -38,10 +38,6 @@ under the License.
<div id="main0"></div>
<div id="main2"></div>
<div id="main3"></div>
- <div id="init-animation-additive"></div>
- <!-- <div id="spiral"></div> -->
- <div id="spiral2"></div>
- <div id="texture-bar"></div>
<script>
@@ -368,485 +364,6 @@ under the License.
- <script>
-
- require(['echarts'], function (echarts) {
-
- var animationDuration = 5000;
- var animationDurationUpdate = 4000;
- var option = {
- xAxis: {},
- yAxis: {},
- dataZoom: [
- { type: 'slider' },
- { type: 'inside' }
- ],
- animationDuration: animationDuration,
- animationDurationUpdate: animationDurationUpdate,
- series: [{
- type: 'custom',
- renderItem: function (params, api) {
- return {
- type: 'group',
- position: api.coord([api.value(0), api.value(1)]),
- children: [{
- type: 'rect',
- shape: {
- x: -50,
- y: 50,
- width: 100,
- height: 150,
- r: 10
- },
- style: {
- fill: 'rgba(102,241,98,0.9)'
- }
- }, {
- type: 'circle',
- shape: {
- cx: -50,
- cy: 50,
- r: 30
- },
- style: {
- fill: 'blue'
- },
- textContent: {
- text: 'data',
- style: {
- fill: '#fff'
- }
- }
- }]
- };
- },
- data: [[121, 333], [29, 312]]
- }]
- };
-
- var chart = testHelper.create(echarts, 'init-animation-additive', {
- title: [
- 'Style merge:',
- '(1) dataZoom hide a data item, and then show it, ensure the fade in animation normal.',
- '(2) click button to setOption merge.'
- ],
- option: option,
- info: {
- animationDuration: animationDuration,
- animationDurationUpdate: animationDurationUpdate
- },
- buttons: [{
- text: 'merge style: border become blue, but background not changed',
- onclick: function () {
- chart.setOption({
- type: 'custom',
- renderItem: function (params, api) {
- return {
- type: 'group',
- children: [{
- type: 'rect',
- style: {
- stroke: 'red',
- lineWidth: 5
- }
- }]
- };
- }
- });
- }
- }]
- });
- });
-
- </script>
-
-
-
-
-<!--
-
- <script>
- require([
- 'echarts'/*, 'map/js/china' */
- ], function (echarts) {
- var animationDuration = 5000;
- var animationDurationUpdate = 4000;
- var angleLabel = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpius', 'Sagittarius', 'Capricornus', 'Aquarius', 'Pisces'];
- var angleRoundValue = angleLabel.length;
- var radiusOffset = 10;
- var angleStep = angleRoundValue / 90;
- var barWidthValue = 0.4;
- var radiusStep = 4;
- var colors = {
- 'A': { stroke: 'green', fill: 'rgba(0,152,0,0.6)' },
- 'B': { stroke: 'red', fill: 'rgba(152,0,0,0.6)' },
- 'C': { stroke: 'blue', fill: 'rgba(0,0, 152,0.6)' },
- };
- var allData = [[
- [[1, 3, 'A']],
- [[2, 6, 'B']],
- [[3, 9, 'C']],
- ], [
- [[1, 12, 'A']],
- [[2, 16, 'B']],
- [[3, 14, 'C']],
- ], [
- [[1, 17, 'A']],
- [[2, 22, 'B']],
- [[3, 19, 'C']],
- ]];
- var currentDataIndex = 0;
-
- function getMaxRadius() {
- var radius = 0;
- for (var j = 0; j < allData.length; j++) {
- var data = allData[j];
- for (var i = 0; i < data.length; i++) {
- radius = Math.max(radius, getSpiralValueRadius(data[i][0][0], data[i][0][1]));
- }
- }
- return Math.ceil(radius * 1.2);
- }
-
- function getSpiralValueRadius(valRadius, valAngle) {
- return valRadius + radiusStep * (valAngle / angleRoundValue);
- }
-
- function renderItem(params, api) {
- var valueRadius = api.value(0);
- var valueAngle = api.value(1);
- var points = [];
- for (var iAngleVal = 0, end = valueAngle + angleStep; iAngleVal < end; iAngleVal += angleStep) {
- iAngleVal > valueAngle && (iAngleVal = valueAngle);
- var iRadiusVal = getSpiralValueRadius(valueRadius - barWidthValue, iAngleVal);
- var point = api.coord([iRadiusVal, iAngleVal]).slice(0, 2);
- points.push(point);
- }
- for (var iAngleVal = valueAngle; iAngleVal > -angleStep; iAngleVal -= angleStep) {
- iAngleVal < 0 && (iAngleVal = 0);
- var iRadiusVal = getSpiralValueRadius(valueRadius + barWidthValue, iAngleVal);
- var point = api.coord([iRadiusVal, iAngleVal]).slice(0, 2);
- points.push(point);
- }
- var name = api.value(2);
- return {
- type: 'polygon',
- shape: { points: points },
- style: {
- lineWidth: 1,
- fill: colors[name].fill,
- stroke: colors[name].stroke
- }
- };
- }
-
- var option = {
- animationDuration: animationDuration,
- animationDurationUpdate: animationDurationUpdate,
- angleAxis: {
- type: 'value',
- // splitLine: { show: false },
- splitArea: {show: true},
- axisLabel: {
- formatter: function(val) {
- return angleLabel[val];
- },
- color: 'rgba(0,0,0,0.2)'
- },
- axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
- min: 0,
- max: angleRoundValue
- },
- radiusAxis: {
- type: 'value',
- splitLine: { show: false },
- axisLabel: { color: 'rgba(0,0,0,0.2)' },
- axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
- min: 0,
- max: getMaxRadius()
- },
- polar: {
- },
- tooltip: {},
- series: [{
- type: 'custom',
- name: 'A',
- coordinateSystem: 'polar',
- renderItem: renderItem,
- data: allData[currentDataIndex][0]
- }, {
- type: 'custom',
- name: 'B',
- coordinateSystem: 'polar',
- renderItem: renderItem,
- data: allData[currentDataIndex][1]
- }, {
- type: 'custom',
- name: 'C',
- coordinateSystem: 'polar',
- renderItem: renderItem,
- data: allData[currentDataIndex][2]
- }]
- };
-
- var chart = testHelper.create(echarts, 'spiral', {
- title: [
- 'animation: ',
- ],
- option: option,
- buttons: [{
- text: 'next',
- onclick: function () {
- currentDataIndex++;
- currentDataIndex >= allData.length && (currentDataIndex = 0);
- chart.setOption({
- series: [{
- data: allData[currentDataIndex][0]
- }, {
- data: allData[currentDataIndex][1]
- }, {
- data: allData[currentDataIndex][2]
- }]
- })
- }
- }, {
- text: 'enable animation',
- onclick: function () {
- chart.setOption({ animation: true });
- }
- }, {
- text: 'disable animation',
- onclick: function () {
- chart.setOption({ animation: false });
- }
- }]
- });
- });
- </script>
- -->
-
-
-
-
-
-
-
- <script>
- require([
- 'echarts'/*, 'map/js/china' */
- ], function (echarts) {
- var animationDuration = 5000;
- var animationDurationUpdate = 7000;
- var animationEasingUpdate = 'elasticOut';
- var angleLabel = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpius', 'Sagittarius', 'Capricornus', 'Aquarius', 'Pisces'];
- var angleRoundValue = angleLabel.length;
- var radiusOffset = 10;
- var angleStep = angleRoundValue / 90;
- var barWidthValue = 0.4;
- var radiusStep = 4;
-
- var colors = [
- { border: 'green', inner: 'rgba(0,152,0,0.6)' },
- { border: 'red', inner: 'rgba(152,0,0,0.6)' },
- { border: 'blue', inner: 'rgba(0,0, 152,0.6)' },
- ];
- var currentDataIndex = 0;
- var datasourceList = [
- [[3, 6, 9]],
- [[12, 16, 14]],
- [[17, 22, 19]],
- ];
- var barValOnRadiusList = [1, 2, 3];
-
- // PENDING:
- // The radius max should be fixed rather than change dynamically.
- // If need to support dynamic coord sys while animation:
- // (A) The `api.coord` should be able to accept a customized extent and
- // return value on the middle state.
- // or (B) Use "data interpolate".
- function getMaxRadius() {
- var radius = 0;
- for (var k = 0; k < barValOnRadiusList.length; k++) {
- for (var i = 0; i < datasourceList.length; i++) {
- var row = datasourceList[i][0];
- for (var j = 0; j < row.length; j++) {
- var valOnAngle = row[j];
- radius = Math.max(
- radius,
- getSpiralValueRadius(barValOnRadiusList[k], valOnAngle)
- );
- }
- }
- }
- return Math.ceil(radius * 1.2);
- }
-
- function getSpiralValueRadius(valOnRadius, valOnAngle) {
- return valOnRadius + radiusStep * (valOnAngle / angleRoundValue);
- }
-
- function addShapes(api, children, valOnRadius, valOnAngle, color) {
- addPolygon(api, children, valOnRadius, valOnAngle, color);
- addLabel(api, children, valOnRadius, valOnAngle, color);
- }
-
- function addPolygon(api, children, valOnRadius, valOnAngle, color) {
- children.push({
- type: 'polygon',
- shape: {
- points: makeShapePoints(api, valOnRadius, valOnAngle),
- valOnAngle: valOnAngle
- },
- style: {
- lineWidth: 1,
- fill: color.inner,
- stroke: color.border
- },
- during: function (elProps) {
- elProps.shape.points = makeShapePoints(
- api, valOnRadius, elProps.shape.valOnAngle
- );
- }
- });
- }
-
- function makeShapePoints(api, valOnRadius, valOnAngle) {
- var points = [];
- for (var iAngleVal = 0, end = valOnAngle + angleStep; iAngleVal < end; iAngleVal += angleStep) {
- iAngleVal > valOnAngle && (iAngleVal = valOnAngle);
- var iRadiusVal = getSpiralValueRadius(valOnRadius - barWidthValue, iAngleVal);
- var point = api.coord([iRadiusVal, iAngleVal]).slice(0, 2);
- points.push(point);
- }
- for (var iAngleVal = valOnAngle; iAngleVal > -angleStep; iAngleVal -= angleStep) {
- iAngleVal < 0 && (iAngleVal = 0);
- var iRadiusVal = getSpiralValueRadius(valOnRadius + barWidthValue, iAngleVal);
- var point = api.coord([iRadiusVal, iAngleVal]).slice(0, 2);
- points.push(point);
- }
- return points;
- }
-
- function addLabel(api, children, valOnRadius, valOnAngle, color) {
- var point = makeLabelPosition(api, valOnRadius, valOnAngle);
- children.push({
- type: 'text',
- x: point[0],
- y: point[1],
- shape: {
- valOnAngle: valOnAngle
- },
- style: {
- text: getText(valOnAngle),
- fill: color.inner,
- stroke: '#fff',
- lineWidth: 3,
- fontSize: 16,
- align: 'center',
- verticalAlign: 'middle'
- },
- z2: 50,
- during: function (elProps) {
- var iValOnAngle = elProps.shape.valOnAngle;
- var point = makeLabelPosition(api, valOnRadius, iValOnAngle);
- elProps.x = point[0];
- elProps.y = point[1];
- elProps.style.text = getText(iValOnAngle);
- }
- });
-
- function getText(iValOnAngle) {
- return (iValOnAngle / angleRoundValue * 100).toFixed(0) + '%'
- }
- }
-
- function makeLabelPosition(api, valOnRadius, valOnAngle) {
- var iRadiusVal = getSpiralValueRadius(valOnRadius, valOnAngle);
- return api.coord([iRadiusVal, valOnAngle + 1 / iRadiusVal / (2 * Math.PI) * angleRoundValue]);
- }
-
- function renderItem(params, api) {
- var children = [];
-
- addShapes(api, children, barValOnRadiusList[0], api.value(0), colors[0]);
- addShapes(api, children, barValOnRadiusList[1], api.value(1), colors[1]);
- addShapes(api, children, barValOnRadiusList[2], api.value(2), colors[2]);
-
- return {
- type: 'group',
- children: children
- };
- }
-
- var option = {
- // animation: false,
- animationDuration: animationDuration,
- animationDurationUpdate: animationDurationUpdate,
- animationEasingUpdate: animationEasingUpdate,
- dataset: {
- source: datasourceList[currentDataIndex]
- },
- angleAxis: {
- type: 'value',
- // splitLine: { show: false },
- splitArea: {show: true},
- axisLabel: {
- formatter: function(val) {
- return angleLabel[val];
- },
- color: 'rgba(0,0,0,0.2)'
- },
- axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
- min: 0,
- max: angleRoundValue
- },
- radiusAxis: {
- type: 'value',
- splitLine: { show: false },
- axisLabel: { color: 'rgba(0,0,0,0.2)' },
- axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
- min: 0,
- max: getMaxRadius()
- },
- polar: {},
- tooltip: {},
- series: [{
- type: 'custom',
- coordinateSystem: 'polar',
- renderItem: renderItem
- }]
- };
-
- var chart = testHelper.create(echarts, 'spiral2', {
- title: [
- 'polygon animation should be corrent. (coordSys extent is fixed)',
- ],
- option: option,
- buttons: [{
- text: 'next',
- onclick: function () {
- currentDataIndex++;
- currentDataIndex >= datasourceList.length && (currentDataIndex = 0);
- chart.setOption({
- dataset: {
- source: datasourceList[currentDataIndex]
- }
- });
- }
- }, {
- text: 'enable animation',
- onclick: function () {
- chart.setOption({ animation: true });
- }
- }, {
- text: 'disable animation',
- onclick: function () {
- chart.setOption({ animation: false });
- }
- }]
- });
- });
- </script>
diff --git a/test/custom-transition.html b/test/custom-transition.html
new file mode 100644
index 0000000..77a6aab
--- /dev/null
+++ b/test/custom-transition.html
@@ -0,0 +1,627 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <script src="lib/esl.js"></script>
+ <script src="lib/config.js"></script>
+ <script src="lib/jquery.min.js"></script>
+ <script src="lib/facePrint.js"></script>
+ <script src="lib/testHelper.js"></script>
+ <link rel="stylesheet" href="lib/reset.css" />
+ </head>
+ <body>
+ <style>
+ </style>
+
+
+ <div id="init-animation-additive"></div>
+ <div id="spiral-fixed-extent"></div>
+ <div id="spiral-dynamic-extent"></div>
+ <div id="texture-bar"></div>
+
+
+
+
+ <script>
+
+ require(['echarts'], function (echarts) {
+
+ var animationDuration = 5000;
+ var animationDurationUpdate = 4000;
+ var option = {
+ xAxis: {},
+ yAxis: {},
+ dataZoom: [
+ { type: 'slider' },
+ { type: 'inside' }
+ ],
+ animationDuration: animationDuration,
+ animationDurationUpdate: animationDurationUpdate,
+ series: [{
+ type: 'custom',
+ renderItem: function (params, api) {
+ return {
+ type: 'group',
+ position: api.coord([api.value(0), api.value(1)]),
+ children: [{
+ type: 'rect',
+ shape: {
+ x: -50,
+ y: 50,
+ width: 100,
+ height: 150,
+ r: 10
+ },
+ style: {
+ fill: 'rgba(102,241,98,0.9)'
+ }
+ }, {
+ type: 'circle',
+ shape: {
+ cx: -50,
+ cy: 50,
+ r: 30
+ },
+ style: {
+ fill: 'blue'
+ },
+ textContent: {
+ text: 'data',
+ style: {
+ fill: '#fff'
+ }
+ }
+ }]
+ };
+ },
+ data: [[121, 333], [29, 312]]
+ }]
+ };
+
+ var chart = testHelper.create(echarts, 'init-animation-additive', {
+ title: [
+ 'Style merge:',
+ '(1) dataZoom hide a data item, and then show it, ensure the fade in animation normal.',
+ '(2) click button to setOption merge.'
+ ],
+ option: option,
+ info: {
+ animationDuration: animationDuration,
+ animationDurationUpdate: animationDurationUpdate
+ },
+ buttons: [{
+ text: 'merge style: border become blue, but background not changed',
+ onclick: function () {
+ chart.setOption({
+ type: 'custom',
+ renderItem: function (params, api) {
+ return {
+ type: 'group',
+ children: [{
+ type: 'rect',
+ style: {
+ stroke: 'red',
+ lineWidth: 5
+ }
+ }]
+ };
+ }
+ });
+ }
+ }]
+ });
+ });
+
+ </script>
+
+
+
+
+
+
+
+ <script>
+ require([
+ 'echarts'
+ ], function (echarts) {
+ var _animationDuration = 5000;
+ var _animationDurationUpdate = 7000;
+ var _animationEasingUpdate = 'elasticOut';
+ var _angleLabel = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpius', 'Sagittarius', 'Capricornus', 'Aquarius', 'Pisces'];
+ var _valOnRoundAngle = _angleLabel.length;
+ var _valOnAngleStep = _valOnRoundAngle / 90;
+ var _barWidthValue = 0.4;
+ var _valOnRadiusStep = 4;
+
+ var _colors = [
+ { border: 'green', inner: 'rgba(0,152,0,0.6)' },
+ { border: 'red', inner: 'rgba(152,0,0,0.6)' },
+ { border: 'blue', inner: 'rgba(0,0, 152,0.6)' },
+ ];
+ var _currentDataIndex = 0;
+ var _datasourceList = [
+ [[3, 6, 9]],
+ [[12, 16, 14]],
+ [[17, 22, 19]],
+ ];
+ var _barValOnRadiusList = [1, 2, 3];
+
+ function getMaxRadius() {
+ var radius = 0;
+ for (var k = 0; k < _barValOnRadiusList.length; k++) {
+ for (var i = 0; i < _datasourceList.length; i++) {
+ var row = _datasourceList[i][0];
+ for (var j = 0; j < row.length; j++) {
+ var valOnAngle = row[j];
+ radius = Math.max(
+ radius,
+ getSpiralValueOnRadius(_barValOnRadiusList[k], valOnAngle)
+ );
+ }
+ }
+ }
+ return Math.ceil(radius * 1.2);
+ }
+
+ function getSpiralValueOnRadius(valOnRadius, valOnAngle) {
+ return valOnRadius + _valOnRadiusStep * (valOnAngle / _valOnRoundAngle);
+ }
+
+ function renderItem(params, api) {
+ var children = [];
+
+ addShapes(api, children, _barValOnRadiusList[0], api.value(0), _colors[0]);
+ addShapes(api, children, _barValOnRadiusList[1], api.value(1), _colors[1]);
+ addShapes(api, children, _barValOnRadiusList[2], api.value(2), _colors[2]);
+
+ return {
+ type: 'group',
+ children: children
+ };
+ }
+
+ function addShapes(api, children, valOnRadius, valOnAngle, color) {
+ addPolygon(api, children, valOnRadius, valOnAngle, color);
+ addLabel(api, children, valOnRadius, valOnAngle, color);
+ }
+
+ function addPolygon(api, children, valOnRadius, valOnAngle, color) {
+ children.push({
+ type: 'polygon',
+ shape: {
+ points: makeShapePoints(api, valOnRadius, valOnAngle),
+ valOnAngle: valOnAngle
+ },
+ style: {
+ lineWidth: 1,
+ fill: color.inner,
+ stroke: color.border
+ },
+ during: function (elProps) {
+ elProps.shape.points = makeShapePoints(
+ api, valOnRadius, elProps.shape.valOnAngle
+ );
+ }
+ });
+ }
+
+ function makeShapePoints(api, valOnRadius, valOnAngle) {
+ var points = [];
+ for (var iAngleVal = 0, end = valOnAngle + _valOnAngleStep; iAngleVal < end; iAngleVal += _valOnAngleStep) {
+ iAngleVal > valOnAngle && (iAngleVal = valOnAngle);
+ var iRadiusVal = getSpiralValueOnRadius(valOnRadius - _barWidthValue, iAngleVal);
+ var point = api.coord([iRadiusVal, iAngleVal]).slice(0, 2);
+ points.push(point);
+ }
+ for (var iAngleVal = valOnAngle; iAngleVal > -_valOnAngleStep; iAngleVal -= _valOnAngleStep) {
+ iAngleVal < 0 && (iAngleVal = 0);
+ var iRadiusVal = getSpiralValueOnRadius(valOnRadius + _barWidthValue, iAngleVal);
+ var point = api.coord([iRadiusVal, iAngleVal]).slice(0, 2);
+ points.push(point);
+ }
+ return points;
+ }
+
+ function addLabel(api, children, valOnRadius, valOnAngle, color) {
+ var point = makeLabelPosition(api, valOnRadius, valOnAngle);
+ children.push({
+ type: 'text',
+ x: point[0],
+ y: point[1],
+ shape: {
+ valOnAngle: valOnAngle
+ },
+ style: {
+ text: getText(valOnAngle),
+ fill: color.inner,
+ stroke: '#fff',
+ lineWidth: 3,
+ fontSize: 16,
+ align: 'center',
+ verticalAlign: 'middle'
+ },
+ z2: 50,
+ during: function (elProps) {
+ var iValOnAngle = elProps.shape.valOnAngle;
+ var point = makeLabelPosition(api, valOnRadius, iValOnAngle);
+ elProps.x = point[0];
+ elProps.y = point[1];
+ elProps.style.text = getText(iValOnAngle);
+ }
+ });
+
+ function getText(iValOnAngle) {
+ return (iValOnAngle / _valOnRoundAngle * 100).toFixed(0) + '%'
+ }
+ }
+
+ function makeLabelPosition(api, valOnRadius, valOnAngle) {
+ var iRadiusVal = getSpiralValueOnRadius(valOnRadius, valOnAngle);
+ return api.coord([iRadiusVal, valOnAngle + 1 / iRadiusVal / (2 * Math.PI) * _valOnRoundAngle]);
+ }
+
+ var option = {
+ // animation: false,
+ animationDuration: _animationDuration,
+ animationDurationUpdate: _animationDurationUpdate,
+ animationEasingUpdate: _animationEasingUpdate,
+ dataset: {
+ source: _datasourceList[_currentDataIndex]
+ },
+ angleAxis: {
+ type: 'value',
+ // splitLine: { show: false },
+ splitArea: {show: true},
+ axisLabel: {
+ formatter: function(val) {
+ return _angleLabel[val];
+ },
+ color: 'rgba(0,0,0,0.2)'
+ },
+ axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
+ min: 0,
+ max: _valOnRoundAngle
+ },
+ radiusAxis: {
+ type: 'value',
+ splitLine: { show: false },
+ axisLabel: { color: 'rgba(0,0,0,0.2)' },
+ axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
+ min: 0,
+ max: getMaxRadius()
+ },
+ polar: {},
+ series: [{
+ type: 'custom',
+ coordinateSystem: 'polar',
+ renderItem: renderItem
+ }]
+ };
+
+ var chart = testHelper.create(echarts, 'spiral-fixed-extent', {
+ title: [
+ 'Spiral race with fixed radius extent.',
+ 'Click **next**, polygon animation should be corrent.',
+ ],
+ option: option,
+ buttons: [{
+ text: 'next',
+ onclick: function () {
+ _currentDataIndex++;
+ _currentDataIndex >= _datasourceList.length && (_currentDataIndex = 0);
+ chart.setOption({
+ dataset: {
+ source: _datasourceList[_currentDataIndex]
+ }
+ });
+ }
+ }, {
+ text: 'enable animation',
+ onclick: function () {
+ chart.setOption({ animation: true });
+ }
+ }, {
+ text: 'disable animation',
+ onclick: function () {
+ chart.setOption({ animation: false });
+ }
+ }]
+ });
+ });
+ </script>
+
+
+
+
+
+
+
+
+
+ <script>
+ require([
+ 'echarts'
+ ], function (echarts) {
+ var _animationDuration = 5000;
+ var _animationDurationUpdate = 7000;
+ // var _animationEasingUpdate = 'elasticOut';
+ var _animationEasingUpdate = 'quadraticOut';
+ var _radianLabels = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpius', 'Sagittarius', 'Capricornus', 'Aquarius', 'Pisces'];
+ var _valOnRoundRadian = _radianLabels.length;
+ var _radianStep = Math.PI / 45;
+ var _barWidthValue = 0.4;
+ var _valOnRadiusStep = 4;
+ // angleAxis.startAngle is 90 by default.
+ var _startRadian = Math.PI / 2;
+
+ var _colors = [
+ { border: 'green', inner: 'rgba(0,152,0,0.6)' },
+ { border: 'red', inner: 'rgba(152,0,0,0.6)' },
+ { border: 'blue', inner: 'rgba(0,0, 152,0.6)' },
+ ];
+ var _currentDataIndex = 0;
+ var _datasourceList = [
+ [ [1, 3], [2, 6], [3, 9] ], // datasource 0
+ [ [1, 12], [2, 16], [3, 14] ], // datasource 1
+ [ [1, 17], [2, 22], [3, 19] ], // datasource 2
+ [ [1, 19], [2, 33], [3, 24] ],
+ [ [1, 24], [2, 42], [3, 29] ],
+ [ [1, 27], [2, 47], [3, 41] ],
+ [ [1, 36], [2, 52], [3, 52] ],
+ [ [1, 46], [2, 59], [3, 63] ],
+ [ [1, 60], [2, 63], [3, 69] ],
+ ];
+ var _barNamesByOrdinal = {1: 'A', 2: 'B', 3: 'C'};
+
+ function getMaxRadius() {
+ var radius = 0;
+ var datasource = _datasourceList[_currentDataIndex];
+ for (var j = 0; j < datasource.length; j++) {
+ var dataItem = datasource[j];
+ radius = Math.max(radius, getSpiralValueOnRadius(dataItem[0], dataItem[1]));
+ }
+ return Math.ceil(radius * 1.2);
+ }
+
+ function getSpiralValueOnRadius(valOnStartRadius, valOnEndAngle) {
+ return valOnStartRadius + _valOnRadiusStep * (valOnEndAngle / _valOnRoundRadian);
+ }
+ function getSpiralRadius(startRadius, endRadian, radiusStep) {
+ return startRadius + radiusStep * ((_startRadian - endRadian) / (Math.PI * 2));
+ }
+
+ function renderItem(params, api) {
+ var children = [];
+ var dataIdx = params.dataIndex;
+ addShapes(params, api, children, api.value(0), api.value(1), _colors[dataIdx]);
+
+ return {
+ type: 'group',
+ children: children
+ };
+ }
+
+ function addShapes(params, api, children, valOnStartRadius, valOnEndRadian, color) {
+ var coords = api.coord([valOnStartRadius, valOnEndRadian]);
+ var startRadius = coords[2];
+ var endRadian = coords[3];
+ var widthRadius = api.coord([_barWidthValue, 0])[2];
+ addPolygon(params, children, widthRadius, startRadius, endRadian, color);
+ addLabel(params, children, widthRadius, startRadius, endRadian, color);
+ }
+
+ function addPolygon(params, children, widthRadius, startRadius, endRadian, color) {
+ children.push({
+ type: 'polygon',
+ shape: {
+ points: makeShapePoints(params, widthRadius, startRadius, endRadian),
+ widthRadius: widthRadius,
+ startRadius: startRadius,
+ endRadian: endRadian
+ },
+ style: {
+ lineWidth: 1,
+ fill: color.inner,
+ stroke: color.border
+ },
+ during: function (elProps) {
+ var shp = elProps.shape;
+ shp.points = makeShapePoints(params, shp.widthRadius, shp.startRadius, shp.endRadian);
+ }
+ });
+ }
+
+ function makeShapePoints(params, widthRadius, startRadius, endRadian) {
+ var points = [];
+ var radiusStep = getRadiusStepByWidth(widthRadius);
+ // angleAxis.clockwise is true by default. So when rotate clickwisely, radian decreases.
+ for (
+ var iRadian = _startRadian, end = endRadian - _radianStep;
+ iRadian > end;
+ iRadian -= _radianStep
+ ) {
+ iRadian < endRadian && (iRadian = endRadian);
+ var iRadius = getSpiralRadius(startRadius - widthRadius, iRadian, radiusStep);
+ points.push(convertToPolarPoint(params, iRadius, iRadian));
+ }
+ for (
+ var iRadian = endRadian;
+ iRadian < _startRadian + _radianStep;
+ iRadian += _radianStep
+ ) {
+ iRadian > _startRadian && (iRadian = _startRadian);
+ var iRadius = getSpiralRadius(startRadius + widthRadius, iRadian, radiusStep);
+ points.push(convertToPolarPoint(params, iRadius, iRadian));
+ }
+ return points;
+ }
+
+ function getRadiusStepByWidth(widthRadius) {
+ return widthRadius / _barWidthValue * _valOnRadiusStep;
+ }
+
+ function addLabel(params, children, widthRadius, startRadius, endRadian, color) {
+ var point = makeLabelPosition(params, widthRadius, startRadius, endRadian);
+ children.push({
+ type: 'text',
+ x: point[0],
+ y: point[1],
+ shape: {
+ startRadius: startRadius,
+ endRadian: endRadian,
+ widthRadius: widthRadius
+ },
+ style: {
+ text: makeText(endRadian),
+ fill: color.inner,
+ stroke: '#fff',
+ lineWidth: 3,
+ fontSize: 12,
+ align: 'center',
+ verticalAlign: 'middle',
+ rich: {
+ round: { fontSize: 16 },
+ percent: { fontSize: 14 }
+ }
+ },
+ z2: 50,
+ during: function (elProps) {
+ var shp = elProps.shape;
+ var point = makeLabelPosition(params, shp.widthRadius, shp.startRadius, shp.endRadian);
+ elProps.x = point[0];
+ elProps.y = point[1];
+ elProps.style.text = makeText(shp.endRadian);
+ }
+ });
+
+ function makeText(endRadian) {
+ var radian = _startRadian - endRadian;
+ var PI2 = Math.PI * 2;
+ var round = Math.floor(radian / PI2);
+ var percent = (((radian / PI2) % 1) * 100).toFixed(1) + '%';
+ return 'Round {round|' + round + '}\n{percent|' + percent + '}';
+ }
+ }
+
+ function makeLabelPosition(params, widthRadius, startRadius, endRadian) {
+ var radiusStep = getRadiusStepByWidth(widthRadius);
+ var iRadius = getSpiralRadius(startRadius, endRadian, radiusStep);
+ return convertToPolarPoint(params, iRadius, endRadian - 10 / iRadius);
+ }
+
+ function convertToPolarPoint(renderItemParams, radius, radian) {
+ return [
+ Math.cos(radian) * radius + renderItemParams.coordSys.cx,
+ -Math.sin(radian) * radius + renderItemParams.coordSys.cy
+ ];
+ }
+
+ var option = {
+ animationDuration: _animationDuration,
+ animationDurationUpdate: _animationDurationUpdate,
+ animationEasingUpdate: _animationEasingUpdate,
+ dataset: {
+ source: _datasourceList[_currentDataIndex]
+ },
+ tooltip: {},
+ angleAxis: {
+ type: 'value',
+ splitArea: { show: true },
+ axisLabel: {
+ formatter: function(val) {
+ return _radianLabels[val];
+ },
+ color: 'rgba(0,0,0,0.2)'
+ },
+ axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
+ min: 0,
+ max: _valOnRoundRadian
+ },
+ radiusAxis: {
+ type: 'value',
+ interval: 1,
+ splitLine: { show: false },
+ axisLabel: {
+ color: 'rgba(0,0,0,0.6)',
+ formatter: function (value) {
+ return _barNamesByOrdinal[value] || '';
+ }
+ },
+ axisTick: { show: false },
+ axisLine: { lineStyle: { color: 'rgba(0,0,0,0.2)' } },
+ min: 0,
+ max: getMaxRadius()
+ },
+ polar: {},
+ series: [{
+ type: 'custom',
+ coordinateSystem: 'polar',
+ renderItem: renderItem
+ }]
+ };
+
+ var chart = testHelper.create(echarts, 'spiral-dynamic-extent', {
+ title: [
+ 'Spiral race with dynamic radius extent.',
+ 'Click **next**. Polygon animation should be corrent.',
+ ],
+ option: option,
+ buttons: [{
+ text: 'next',
+ onclick: function () {
+ _currentDataIndex++;
+ _currentDataIndex >= _datasourceList.length && (_currentDataIndex = 0);
+ chart.setOption({
+ dataset: {
+ source: _datasourceList[_currentDataIndex]
+ },
+ radiusAxis: {
+ max: getMaxRadius()
+ }
+ });
+ }
+ }, {
+ text: 'enable animation',
+ onclick: function () {
+ chart.setOption({ animation: true });
+ }
+ }, {
+ text: 'disable animation',
+ onclick: function () {
+ chart.setOption({ animation: false });
+ }
+ }]
+ });
+ });
+ </script>
+
+
+
+
+
+
+
+
+ </body>
+</html>
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org