<script>
/**
 * vs-Bar-cylinder 2022-10-08
 *
 * width 图表宽度 330
 * height 图表高度 280
 * barWidth 柱子高度 40
 * data 数据 []
 * topColors 顶部柱子颜色 ["#FBAB58", "#1FC2FC", "#669BFF", "#0150CF", '#bf7b15', "#f54747", "#909399", "#5a6272"] //默认提供7种颜色，超过7种请自定义
 * botColors 底部柱子颜色 ["#FDE364", "#6BFFF3", "#77BFFF", "#0EC3FF", "#E6A23C", "#f56c6c", "#e9e9eb", "#67c23a"] //默认提供7种颜色，超过7种请自定义
 * 
 * @chartClick 图表点击触发回调 返回params参数
 * 
 *  setEchartsRefresh echarts刷新 事件
 */
export default {
    name: "vs-bar-cylinder",
};
</script>
<script setup>
import {
    ref,
    reactive,
    inject,
    onMounted
} from "vue";
const echarts = inject("$echarts");

const props = defineProps({
    width: {
        type: Number,
        default: 330,
    },
    height: {
        type: Number,
        default: 280,
    },
    barWidth: {
        type: Number,
        default: 40,
    },
    data: {
        type: Array,
        default: () => [
            { name: "事项一", value: 2233 },
            { name: "事项二", value: 6325 },
            { name: "事项三", value: 4096 },
            { name: "事项四", value: 5066 },
        ]
    },
    topColors: {
        type: Array,
        default: () => ["#FBAB58", "#1FC2FC", "#669BFF", "#0150CF", '#bf7b15', "#f54747", "#909399", "#5a6272"]
    },
    botColors: {
        type: Array,
        default: () => ["#FDE364", "#6BFFF3", "#77BFFF", "#0EC3FF", "#E6A23C", "#f56c6c", "#e9e9eb", "#67c23a"]
    }
});


const style = reactive({
    width: props.width + 'px',
    height: props.height + 'px',
})

const emit = defineEmits(["chartClick"]);

const echartRef = ref(null)

let _echarts = null;
const init = function () {
    if (_echarts !== null) {
        _echarts.dispose();
        _echarts = null
    }
    _echarts = echarts.init(echartRef.value);
    const color = "#fff";
    let xAxisData = [];
    let seriesData = [];
    let topData = [];
    let botData = [];
    let sum = 0;

    const rich = {
        a: {
            fontSize: 12,
            color: "#FFFFFF",
        }
    };
    props.topColors.forEach((item, index) => {
        rich[index] = {
            fontSize: 16,
            color: item,
            fontWeight: "bold",
        }

    });

    props.data.map((item) => {
        xAxisData.push(item.name);
        seriesData.push(item.value);
        sum += item.value;
    });
    props.data.map((it) => {
        topData.push(sum);
        botData.push(1);
    });
    let option = {
        tooltip: {
            trigger: "axis",
            axisPointer: {
                type: "shadow",
            },
            formatter: function (params, ticket, callback) {
                const item = params[2];
                return item.name + " : " + item.value;
            },
        },
        grid: {
            top: "5%",
            left: "3%",
            right: "3%",
            bottom: "5%",
            containLabel: true,
        },

        xAxis: {
            data: xAxisData,
            axisTick: {
                show: false,
            },
            axisLine: {
                show: false,
                lineStyle: {
                    color: color,
                    opacity: color == "#fff" ? 0.3 : 1,
                },
            },
            axisLabel: {
                show: true,
                margin: 10,
                interval: 0,
                textStyle: {
                    color: color,
                    lineHeight: 18,
                    rich: rich,
                },
                formatter: function (val, index) {
                    var strs = val.split("");
                    var str = "";
                    for (var i = 0, s; (s = strs[i++]);) {
                        str += s;
                        if (!(i % 7)) str += "\n";
                    }

                    return (
                        "{a| " + str + "}" + "\n" + "{" + index + "|" + props.data[index].value + "}"
                    );
                },
            },
            interval: 0,
        },
        yAxis: {
            nameTextStyle: {
                color: color,
                fontSize: 12,
            },
            splitLine: {
                show: color == "#fff" ? false : true,
                lineStyle: {
                    color: color,
                    opacity: 0.1,
                },
            },
            axisTick: {
                show: false,
            },
            axisLine: {
                show: false,
            },
            axisLabel: {
                show: false,
                textStyle: {
                    fontSize: 12,
                    color: color,
                },
            },
            splitNumber: 3,
        },
        series: [
            {
                name: "柱顶部",
                type: "pictorialBar",
                symbolSize: [props.barWidth, 10],
                symbolOffset: [0, -5],
                z: 16,
                itemStyle: {
                    normal: {
                        color: function (params) {
                            return props.topColors[params.dataIndex];
                        },
                    },
                },
                label: {
                    show: true,
                    position: "top",
                    fontSize: 14,
                    fontWeight: "bold",
                    color: '#fff',
                    formatter: function (params, index) {
                        return ((params.value / sum) * 100).toFixed(1) + "%";
                    },
                },
                symbolPosition: "end",
                data: seriesData,
            },
            {
                name: "柱底部",
                type: "pictorialBar",
                symbolSize: [props.barWidth, 10],
                symbolOffset: [0, 5],
                z: 11,
                itemStyle: {
                    normal: {
                        color: function (params) {
                            return props.botColors[params.dataIndex];
                        },
                    },
                },
                data: botData,
            },
            {
                type: "bar",
                itemStyle: {
                    normal: {
                        color: function (params) {
                            return props.botColors[params.dataIndex];
                        },
                        opacity: 0.4,
                    },
                },
                z: 11,
                silent: true,
                barWidth: props.barWidth,
                barGap: "-100%", // Make series be overlap
                data: seriesData,
            },
            {
                name: "最上层立体圆",
                type: "pictorialBar",
                symbolSize: [props.barWidth, 10],
                symbolOffset: [0, -5],
                z: 13,
                itemStyle: {
                    normal: {
                        color: color == "#fff" ? "#595D78" : "#E5E5E5",
                    },
                },
                symbolPosition: "end",
                data: topData,
            },
            {
                //上部立体柱
                stack: "1",
                type: "bar",
                z: 9,
                itemStyle: {
                    normal: {
                        color: color == "#fff" ? "rgba(255,255,255,.1)" : "#F5F5F5",
                    },
                },
                silent: true,
                barWidth: props.barWidth,
                barGap: "-100%", // Make series be overlap
                data: topData,
            },
        ],
    };
    _echarts.setOption(option);

    _echarts.on('click', (params) => {
        emit("chartClick", params);
    })
}

onMounted(() => {
    init()
})

//图表刷新
const setEchartsRefresh = function () {
    init()
};

defineExpose({
    setEchartsRefresh
});
</script>

<template>
    <div :style="style" class="vsBarCylinder" ref="echartRef"></div>
</template>

<style  lang="scss" scope>
$main: var(--main);
$auxiliary: var(--auxiliary);
$light: var(--light);

.vsBarCylinder {}
</style>
