/*
title: Custom Spiral Race
category: custom
titleCN: 自定义螺旋线竞速
difficulty: 11
*/


var _animationDuration = 5000;
var _animationDurationUpdate = 7000;
var _animationEasingUpdate = 'linear';
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 = [
    {fill: '#5470c6', text: '#2747a5'},
    {fill: '#91cc75', text: '#447f27'},
    {fill: '#fac858', text: '#a0761c'}
];

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)
        },
        extra: {
            widthRadius: widthRadius,
            startRadius: startRadius,
            endRadian: endRadian,
            transition: ['widthRadius', 'startRadius', 'endRadian']
        },
        style: {
            fill: color.fill
        },
        during: function (apiDuring) {
            apiDuring.setShape('points', makeShapePoints(
                params,
                apiDuring.getExtra('widthRadius'),
                apiDuring.getExtra('startRadius'),
                apiDuring.getExtra('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],
        transition: [],
        extra: {
            startRadius: startRadius,
            endRadian: endRadian,
            widthRadius: widthRadius,
            transition: ['startRadius', 'endRadian', 'widthRadius']
        },
        style: {
            text: makeText(endRadian),
            fill: color.text,
            stroke: '#fff',
            lineWidth: 3,
            fontSize: 16,
            align: 'center',
            verticalAlign: 'middle',
            rich: {
                round: { fontSize: 24 },
                percent: { fontSize: 18 }
            }
        },
        z2: 50,
        during: function (apiDuring) {
            var endRadian = apiDuring.getExtra('endRadian');
            var point = makeLabelPosition(
                params,
                apiDuring.getExtra('widthRadius'),
                apiDuring.getExtra('startRadius'),
                endRadian
            );
            apiDuring.setTransform('x', point[0]).setTransform('y', point[1]);
            apiDuring.setStyle('text', makeText(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
    ];
}

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
    }]
};


function next() {
    ++_currentDataIndex;
    myChart.setOption({
        dataset: {
            source: _datasourceList[_currentDataIndex]
        },
        radiusAxis: {
            max: getMaxRadius()
        }
    });

    if (_currentDataIndex < _datasourceList.length - 1) {
        setTimeout(next, _animationDurationUpdate);
    }
}

setTimeout(next, 1000);
