使用响应式布局的制表器渲染问题

如何解决使用响应式布局的制表器渲染问题

问题: 如果我坚持使用布局,那么几乎所有东西都可以工作:“ fitColumns”我尝试的任何其他操作似乎都会导致渲染(如果这是正确的术语)问题。我没有使用框架(在时间范围内过桥)。当页面完全加载后显示表格时,无论我选择哪种布局-它总是像“ fitColumns”一样开始显示。例如,如果我将其设置为“ fitDataFill”,它将加载并显示为“ fitColumns”。当我单击另一个选项卡并再次返回时 然后显示适合fitDataFill的数据。

修订:

大致步骤:

  • 加载一个特定的文件,其中包含有关要加载到表中的其余文件的元数据,这些表的名称,每个表中的列以及在列标题显示为浮点式帮助的文本
  • 加载其余数据并构建包含元数据的表配置对象
  • 为每个表添加特定于表的div,并将其附加到csv-tab-buttons div
  • 在新创建的div上构建表
  • 添加按钮,该按钮将切换通过css活动类和setTab函数显示哪个表

setTab函数包括两次重绘(可以肯定)。

如果您看到的代码类似于您在此处编写的代码,那么感谢您,我从他人那里收集了我写的大部分内容

制表器版本为4.8 使用Visual Studio Code创建代码,使用Live Server扩展在每次保存后重新加载页面 浏览器是Chrome版本85.0.4183.121(正式版本)(64位)

  • 我根据@mirza的建议进行了改写,以确保在构建表之前完全读取数据,并且每个表都独立存储,因此我不会每次都将同一表传递给setTab
  • fitColumns有效,但不允许我单独调整列的大小(可能是设计使然)
  • fitData似乎可以正常工作
  • fitDataFill和fitDataStretch在同一个表格的第一个渲染或后续渲染上不起作用,直到我单击并再次返回
  • 我试图通过调试器遵循tabulator.js中的逻辑,尽管我可以看到正在发生的事情,但是其中发生了太多的事情让我无法把握问题的可能所在

HTML:

    <!DOCTYPE html>
    <html lang="en">
    
        <head>
            <Meta charset="UTF-8" />
            <Meta name="viewport" content="width=device-width,initial-scale=1.0" />
            <Meta http-equiv="X-UA-Compatible" content="ie=edge" />
            <!-- CSS -->
            <link rel="stylesheet" href="./scripts/dist/css/tabulator.min.css">
            <link rel="stylesheet" href="./styles/style.css">
            <!-- Scripts -->
            <script type="text/javascript" src="./scripts/dist/js/tabulator.min.js"></script>
            <script type="text/javascript" src="./scripts/dist/js/papaparse.min.js"></script>
            <title>My Team</title>
        </head>
    
        <body>
            <!-- Wrapper -->
            <div class="wrapper">
                <section class="container">
                    <!-- Header -->
                    <header id="header" class="header">
                        <h1>Reporting</h1>
                    </header>
    
                    <!-- Tabs -->
                    <div id="csv-tab-buttons" class="tab">
                    </div>
    
                    <!-- Tables on each tab -->
                    <div id="csv-tabs">
                    </div>
    
                    <!-- Footer -->
                    <footer class="footer">
                        <p>My Team &copy; 2020</p>
                    </footer>
    
                </section>
            </div><!-- Wrapper Ends-->
            <script src="./scripts/dist/js/miscsv.min.js"></script>
        </body>
    </html>

修订的Javascript:

 //*******************************************************************************************************
// Global variables
//*******************************************************************************************************

var file = 'DS.PPTE.DB2.VIaraCF.VARLEGND.CSV'
var tables = []
var tableDivs = []
var tabConfig = {}

//*******************************************************************************************************
// Global functions
//*******************************************************************************************************

let onlyUnique = (value,index,self) => {
    return self.indexOf(value) === index
}

//*******************************************************************************************************
// Async functions
//*******************************************************************************************************

// Set the tab to whichever button was clicked
async function activateTab(target) {
    // hides all tabs
    document.querySelectorAll(".tabcontent").forEach(tabContent => tabContent.style.display = "none");
    // Remove the active class from all tab links
    document.querySelectorAll('.tablinks').forEach(tabLink => tabLink.className.replace("active",""));
    // Remove the active class from the active tab
    document.querySelectorAll(".active").forEach(activeTab => activeTab.classList.remove("active"))
    // Activate the selected tab
    document.querySelector(`#${target.textContent}`).style.display = "block"
    target.classList.add("active");
}

async function setTab(target) {
    console.log("Activate the tab")
    await activateTab(target)
    console.log("Redraw the table")
    // Redraw the table
    tableDivs[`${target.textContent}`].redraw(true);
}

// Read a CSV file
const readCSV = async (file) => {
    return new Promise(resolve => {
        Papa.parse(`data/${file}`,{
            header: true,download: true,skipEmptyLines: true,complete: results => {
                console.log(`${file} loaded - ${results.data.length} records.`)
                resolve(results)
            }
        })
    })
}

// Get all the data first
async function getData() {
    // Read the Meta data file with the data and table config
    let parseMeta = await readCSV(file)
    tabConfig = {
        // Get the names of the tables to present
        tabs: parseMeta.data.map((data) => data['TABLE-NAME']).filter(onlyUnique).sort(),// Find the file name for each table
        files: parseMeta.data.map((data) => `${data['TABLE-NAME']}-${data['CSV-FILE-NAME']}`).filter(onlyUnique)
            .map((entry) => {
                let tmpEntry = entry.split('-')
                return { table: `${tmpEntry[0]}`,file: `${tmpEntry[1]}` }
            }),// Save the float over help for each column by table name
        help: parseMeta.data.map((data) => {
            return { key: `${data['TABLE-NAME']}-${data['VARIABLE']}`,helpText: data['VAR-DESCRIPTION'] != '' ? data['VAR-DESCRIPTION'] : data['VARIABLE'] }
            }),data: tables,divs: tableDivs,}
    // Read in the files which contain the table data
    for (const tabName of tabConfig.tabs) {
        let file = tabConfig.files.filter(entry => entry.table == tabName)[0].file
        tables[tabName] = await readCSV(file)
        tableDivs[tabName] = `csv-table-${tabName}`
    }
}

// Master function to do everything in the right order
async function doAll() {
    // Get all the data and build the table config
    await getData()

    // Store the buttons and tabs anchor divs
    let buttonsDiv = document.getElementById("csv-tab-buttons")
    let tabsDiv = document.getElementById("csv-tabs")

    // Add the buttons and tables
    for ([idx,tabName] of tabConfig.tabs.entries()) {
        // Add tabs to hold the tables to the page
        const elemTabDiv = document.createElement('div')
        const elemTableDiv = document.createElement('div')
        elemTabDiv.id = tabName
        elemTabDiv.className = "tabcontent"
        elemTableDiv.id = `csv-table-${tabName}`
        elemTableDiv.className = "table"
        elemTabDiv.appendChild(elemTableDiv)
        tabsDiv.appendChild(elemTabDiv)

        // Define header context menu
        let headerMenu = [
            {
                label:"Hide Column",action:function(e,column){
                    column.hide()
                },},]
        // Create the table
        tableDivs[tabName] = new Tabulator(`#csv-table-${tabName}`,{
            data:tabConfig.data[tabName].data,layout:"fitData",responsiveLayout:"collapse",tooltips:true,pagination:"local",paginationSize:20,resizableColumns:true,movableColumns:true,resizableRows:true,autoColumns: true,autoColumnsDeFinitions: function(deFinitions) {
                deFinitions.forEach((column) => {
                    let helpText = tabConfig.help.find(key => key.key === `${tabName}-${column.field}`).help
                    // Add float over help based on column name
                    column.headerTooltip = helpText
                    column.headerMenu = headerMenu
                    column.headerFilter = true
                    column.headerSort = true
                    column.headerFilterLiveFilter = false
                })
                return deFinitions
            },renderStarted:function(){
                console.log("Render started")
            },renderComplete:function(){
                console.log("Render complete")
            },})
        // Add tab buttons to page
        const elemTabButton = document.createElement('button')
        elemTabButton.id = `button-${tabName}`
        if ( idx == 0 ) {
            elemTabButton.className = "tablinks active"
        } else {
            elemTabButton.className = "tablinks"
        }
        elemTabButton.onclick = function() { setTab(this) }
        elemTabButton.textContent = tabName
        buttonsDiv.appendChild(elemTabButton)
    }
    document.querySelector(".active").click();
}

doAll()



CSS:

:root {
    --shadow: 0 1px 5px rgba(104,104,0.8);
    --raisin: #262730;
    --vermillion: #d33f49;
    --cadet: #576c75;
    --navyboy: #8db2c2;
    --space-cadet: #363457;
    --baby-powder: #f0f4ef;
    --ice: rgb(245,247,253);
}

html {
    Box-sizing: border-Box;
    font-family: Arial,Helvetica,sans-serif;
    color: var(--dark);
}

body {
    background: var(--baby-powder);
    margin: 10px 10px;
    line-height: 1.4;
}

/* .wrapper {
    display: grid;
    grid-gap: 10px;
} */

.container {
    display: grid;
    grid-gap: 10px;
    grid-template-areas: 
        'header'
        'csv-tab-buttons'
        'footer';

    margin: auto;
    width: 98%;
    overflow: auto;
    padding: 1rem 1rem;
}

header {
    background: var(--raisin);
    color: var(--vermillion);
    font-size: 150%;
    line-height: 1;
    padding: 0.1rem;
    text-align: center;
    Box-shadow: var(--shadow);
}

.tab {
    background-color: var(--ice);
    Box-shadow: var(--shadow);
}

/* Style the buttons that are used to open the tab content */
.tab button {
    background-color: inherit;
    /* float: left; */
    border: none;
    outline: none;
    cursor: pointer;
    /* padding: 14px 16px; */
    padding: 1rem 1.1rem;
    transition: 0.3s;
}

/* Change background color of buttons on hover */
.tab button:hover {
    background-color: var(--cadet);
    color: var(--ice);
}

/* Create an active/current tablink class */
.tab button.active {
    background-color: var(--vermillion);
    color: var(--ice);
}

/* Style the tab content */
.tabcontent {
    /* overflow: hidden; */
    display: none;
    /* padding: 6px 12px; */
    /* border-top: none; */
}

/* Override Tabulator header background */
.tabulator-col-content {
    background-color: var(--ice);
}

.table {
    overflow: hidden;
    Box-shadow: var(--shadow);
}

.footer {
    background: var(--cadet);
    color: white;
    padding: 0rem 2rem;
    line-height: 1;
    Box-shadow: var(--shadow);
}

编辑: 我对所有顺序进行了一些更改,以便在调用 setTab 函数时可以将表对象保持在范围内,并且在单击选项卡按钮时可以发出重绘。第一次单击每个选项卡时,它似乎填充了数据的宽度。当我再次单击每个选项卡时,它将正确包裹将不在屏幕上的列换行到下一行。我在setTab例程中放置了多个表重绘,这对表的呈现没有影响。但是,它确实以某种方式更改了表的属性。我在调试器中观察到,tableWidth从第一次重绘之前的0更改为2734,在第二次重绘之后更改为2786,并保持在该值。如果我单击鼠标左键并再次返回,它会按预期包裹。

解决方法

如果在创建表时该元素不可见,则无法正确显示制表器表。

要正确渲染表格,必须在元素可见时重新绘制表格。

请参见Here

从网站上:

如果包含制表符的元素的大小发生了变化(并且您无法使用内置的自动调整大小功能),或者在其包含元素可见之前创建了表,则必须重新绘制该表才能确保行和列正确呈现。

您可以通过以下方式重绘表格

table.redraw();

table.redraw(true); //trigger full rerender including all data and rows

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?