/*
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 = [
    { 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)
        },
        extra: {
            widthRadius: widthRadius,
            startRadius: startRadius,
            endRadian: endRadian,
            transition: ['widthRadius', 'startRadius', 'endRadian']
        },
        style: {
            lineWidth: 1,
            fill: color.inner,
            stroke: color.border
        },
        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.inner,
            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);

