欢迎来到气球塔防6 BWIKI!
除特殊说明外,本站内容采用CC BY-NC-SA 4.0协议。
欢迎各位到留言板留言或者加入QQ群:950568164

全站通知:

Widget:StatTableGenerator

来自气球塔防6WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

数据表格展示方法,当需要生成数据表格时置于生成代码的前面

<script>
// 这里必须用var!
var generateTable = generateTable || ((ogData, statDOM, meta = {}) => {
    const damageTypeImg = [
        'https://patchwiki.biligame.com/images/btd6/thumb/e/e8/eo0xj3r6uwys4ky19e902unp7x9ioaa.png/35px-Lead.png', // Lead.png
        'https://patchwiki.biligame.com/images/btd6/thumb/7/71/f8gyamnsucswpqm8d04vq0ee5h1j3h1.png/36px-Black.png', // Black.png
        'https://patchwiki.biligame.com/images/btd6/thumb/8/80/10acd2f6xy6ft9rk45cdw4kmvzzakqc.png/36px-White.png', // White.png
        'https://patchwiki.biligame.com/images/btd6/thumb/3/31/dvnysknnubsic5od5p75rbvjr2llc8x.png/35px-Purple.png', // Purple.png
        'https://patchwiki.biligame.com/images/btd6/thumb/b/b6/tfiqjee9us2ft2k72cf9pmolxkuwepy.png/37px-PinkIce.png', // PinkIce.png
    ]

    const doNotCollapseKey = ['射弹', '攻击']

    /**
     * 通用字段值处理
     * @param {HTMLTableRowElement} row
     * @param {string} key
     * @param {*} value
     */
    function generalKey2Row(row, key, value, collapse = true) {
        const keyCell = document.createElement('th');
        if (meta.thClass) keyCell.classList.add(meta.thClass);
        keyCell.innerHTML = key;
        row.appendChild(keyCell);

        const valueCell = document.createElement('td');

        if (key === '额外伤害' || key === '额外穿透消耗') {
            valueCell.appendChild(generateKeywordValueTable(value));
        } else if (key === '忽略项' || key == '移除状态') {
            valueCell.appendChild(generateUl(value));
        } else if (key === '伤害类型') {
            valueCell.append(...generateDamageType(value))
        } else if (typeof value === 'object' && value !== null) {
            valueCell.appendChild(generate(value, true, collapse));
        } else {
            valueCell.innerHTML = value;
        }

        row.appendChild(valueCell);
    }

    /**
     * 伤害类型解析
     * @param {number} t 伤害类型
     * @returns {Array<HTMLImageElement>} 图片元素
     */
    function generateDamageType(t) {
        const doms = []
        for (let i = 0; i < damageTypeImg.length; i++) {
            if (t & (1 << i)) {
                let img = document.createElement('img')
                img.src = damageTypeImg[i]
                img.style.height = '30px'
                doms.push(img)
            }
        }
        if (doms.length > 0) {
            return doms
        }
        const b = document.createElement('b')
        b.innerText = 'N/A'
        return [b]
    }

    /**
     * 生成无序列表
     * @param {string[]} arr 
     * @returns {HTMLUListElement} 生成的无序列表
     */
    function generateUl(arr) {
        const ul = document.createElement('ul');

        for (let i = 0; i < arr.length; i++) {
            const li = document.createElement('li');
            li.innerHTML = arr[i];
            ul.appendChild(li);
        }
        return ul
    }

    /**
     * 生成keyword-value表格
     * @param {Array<{keyword,value}>} kvs keyword-value数组
     * @returns {HTMLTableElement} 生成的表格
     */
    function generateKeywordValueTable(mods) {
        const table = document.createElement('table');
        table.style.whiteSpace = 'nowrap',
            table.classList.add('wikitable');
        table.classList.add('towerstat-table');
        if (meta.tdClass) table.classList.add(meta.tdClass);
        table.classList.add('nested-table');
        const tbody = document.createElement('tbody');

        for (let i = 0; i < mods.length; i++) {
            const row = document.createElement('tr');
            const keyCell = document.createElement('th');
            if (meta.thClass) keyCell.classList.add(meta.thClass);
            keyCell.innerHTML = mods[i].keyword;
            const valueCell = document.createElement('td');
            valueCell.innerHTML = mods[i].value;

            row.appendChild(keyCell);
            row.appendChild(valueCell);
            tbody.appendChild(row);
        }

        table.appendChild(tbody);
        return table;
    }

    /**
     * 递归生成表格
     * @param {Object|Array} data - 要转换为表格的数据
     * @param {boolean} isNested - 是否为嵌套表格
     * @returns {HTMLTableElement} 生成的表格元素
     */
    let generate = (data, isNested = true, collapse = true) => {
        const table = document.createElement('table');
        table.style.whiteSpace = 'nowrap',
            table.classList.add('wikitable');
        table.classList.add('towerstat-table');
        if (meta.tdClass) table.classList.add(meta.tdClass);
        if (isNested) {
            table.classList.add('nested-table');
        }

        // 如果是数组
        if (Array.isArray(data)) {
            let tbody = document.createElement('tbody');
            //tbody.style.display = 'none';

            for (let i = 0; i < data.length; i++) {
                let item = data[i];
                const row = document.createElement('tr');
                const cell = document.createElement('td');

                // 如果数组项是对象或数组,递归生成表格
                if (typeof item === 'object' && item !== null) {
                    cell.appendChild(generate(item, true, collapse));
                } else {
                    cell.innerHTML = item;
                }

                row.appendChild(cell);
                tbody.appendChild(row);
            }

            table.appendChild(tbody);
        }
        // 如果是对象
        else if (typeof data === 'object' && data !== null) {
            const tbody = document.createElement('tbody');

            // 遍历对象的每个属性
            for (const key in data) {
                // 处理name字段
                if (key === 'name') {
                    const caption = document.createElement('caption');
                    caption.innerHTML = data.name;
                    caption.style.color = meta.thClass?.includes('paragon') ? '#FFF' : '#0645ad';
                    caption.style.minWidth = '150px';

                    if (isNested && collapse) {
                        caption.classList.add('collapsed');
                        tbody.style.display = 'none'
                    }
                    table.appendChild(caption);

                    // 绑定点击事件,实现显示/隐藏功能
                    caption.onclick = function (tbodyEl) {
                        return function () {
                            // 切换折叠状态类
                            this.classList.toggle('collapsed');
                            // 切换tbody显示/隐藏
                            if (tbodyEl.style.display === 'none') {
                                tbodyEl.style.display = '';
                            } else {
                                tbodyEl.style.display = 'none';
                            }
                        };
                    }(tbody);
                    continue;
                }

                // 处理behaviors字段 - 直接跳过不显示
                if (key === 'behaviors') {
                    console.error('不应该有behaviors!!!!');
                    continue;
                }

                // 处理note字段
                if (key.toLowerCase() === 'notes') {
                    const row = document.createElement('tr');
                    const notesCell = document.createElement('td');
                    notesCell.colSpan = 2;

                    notesCell.appendChild(generateUl(data[key]));
                    row.appendChild(notesCell);
                    tbody.appendChild(row);
                    continue;
                }

                // 处理meta/emission/traveling的字段,直接原地插入值中的所有字段
                if (key.split('.')[0] === 'meta' || key === 'emission' || key === 'traveling') {
                    const metaData = data[key];
                    // 遍历meta对象的所有属性
                    for (let metaKey in metaData) {
                        const row = document.createElement('tr');
                        generalKey2Row(row, metaKey, metaData[metaKey], !doNotCollapseKey.includes(key))
                        tbody.appendChild(row);
                    }
                    continue;
                }

                // 处理普通字段
                const row = document.createElement('tr');
                generalKey2Row(row, key, data[key], !doNotCollapseKey.includes(key));
                tbody.appendChild(row);
            }

            table.appendChild(tbody);
        }

        return table;
    }

    try {
        statDOM.appendChild(generate(ogData, false))
    } catch (e) {
        console.error(e)
    }
})</script>