【问题标题】:How to update data on a page according to data from a CSV file instead of using fixed element data on the page?如何根据 CSV 文件中的数据更新页面上的数据,而不是使用页面上的固定元素数据?
【发布时间】:2021-11-28 12:56:07
【问题描述】:

在代码片段之后有我在 Visual Studio Code 中尝试的完整代码。

我将在下面留下的这个模型使用两个带有数据的 <pre> 元素,以便页面每 2 秒刷新一次页面数据,但我希望不使用带有值的元素,而是刷新页面每 2 秒使用一个名为 List_of_Games.csv 的文件中的现有数据

此文件中的数据每 1 分钟更新一次,它们具有与 <pre> 元素相同的 label,value,market,numbergame 模型。

我怎么能这样做?我无法为此绘制模型。


let csv1 = d3.csvParse(d3.select("#csv1").remove().text());
    let csv2 = d3.csvParse(d3.select("#csv2").remove().text());
    
    let csv = [csv1, csv2];
    let i = 0;

    
    var select_5 = d3.select("#Lista-de-Jogos-Lateral")
      .append("div")
      .attr("id","select-box-5")
      .style("width","100%")
      .style("max-height","574px");

    function update() {

        let data = csv[i++%2];
            
        let update_5 = select_5.selectAll(".matches")
            .data(data,d=>d.label);
        
        update_5.exit().remove();

        // Enter new divs:
        const enter = update_5.enter()
            .append("div")
            .attr("class","matches")
        
        // Append the children to entered divs:
        enter.append("form")
           .attr("action",d => d.market)
           .attr("target","_blank")
           .style("width","100%")
           .append("input")
           .attr("type","submit")
           .attr("target","_blank")
           .style("width","100%")
           .attr("value","Jogo Betfair");
           
        enter.append("form")
            .append("input")
            .attr("type","text")
            .attr("id",d => "barra-de-texto-para-grafico-" + d.numbergame)
            .style("width","100%")
            .attr("value", d=>d.label);
            
        enter.append("img")
            .attr("type","text")
            .attr("src","https://sitedeapostas-com.imgix.net/assets/local/Company/logos/betfair_logo_transp.png?auto=compress%2Cformat&fit=clip&q=75&w=263&s=c1691b4034fd0c4526d27ffe8b1e839c")
            .attr("name",d => "grafico-betfair-" + d.numbergame);
    }
  
  
  update();
    setInterval(update,2000);
{
    box-sizing: border-box;
    }
    .matches {
    text-align:center;
    float: left;
    width: 355px;
    border: 1px solid white;
    border-collapse: collapse;
    }
    .column {
    text-align:center;
    float: left;
    width: 355px;
    border: 1px solid white;
    border-collapse: collapse;
    }
    .grid {
    float: left;
    width: 1431px;
    }
    .row:after {
    content: "";
    display: table;
    clear: both;
    }
    .button {
    background-color: #33ccff;
    color: black;
    font-weight: bold;
    }
    input[type=submit] {
    background-color: #33ccff;
    color: black;
    font-weight: bold;
    }
    html {
    overflow: scroll;
    overflow-x: hidden;
    }
    ::-webkit-scrollbar {
    width: 0px; /* remove scrollbar space /
    background: transparent; / optional: just make scrollbar invisible /
    }
    / optional: show position indicator in red */
    ::-webkit-scrollbar-thumb {
    background: #FF0000;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.1.1/d3.min.js"></script>
    <div style="color:white;font-weight:bold;overflow:hidden;overflow-y:scroll;" class="grid games" id="Lista-de-Jogos-Lateral">
    
    <pre id="csv1">label,value,market,numbergame
A,www.siteA.com,www.webA.com,1
B,www.siteB.com,www.webB.com,2
C,www.siteC.com,www.webC.com,3
D,www.siteD.com,www.webD.com,4</pre>
    <pre id="csv2">label,value,market,numbergame
A,www.siteA.com,www.webA.com,1
G,www.siteG.com,www.webG.com,2
C,www.siteC.com,www.webC.com,3
Z,www.siteZ.com,www.webZ.com,4
Y,www.siteY.com,www.webY.com,5</pre>
    

    
    </div>

我尝试在 Visual Studio Code 中以这种方式使用它,但没有得到积极的反馈:

<html>
    <head>
        <style>
            {
            box-sizing: border-box;
            }
            .matches {
            text-align:center;
            float: left;
            width: 355px;
            border: 1px solid white;
            border-collapse: collapse;
            }
            .column {
            text-align:center;
            float: left;
            width: 355px;
            border: 1px solid white;
            border-collapse: collapse;
            }
            .grid {
            float: left;
            width: 1431px;
            }
            .row:after {
            content: "";
            display: table;
            clear: both;
            }
            .button {
            background-color: #33ccff;
            color: black;
            font-weight: bold;
            }
            input[type=submit] {
            background-color: #33ccff;
            color: black;
            font-weight: bold;
            }
            html {
            overflow: scroll;
            overflow-x: hidden;
            }
            ::-webkit-scrollbar {
            width: 0px; /* remove scrollbar space /
            background: transparent; / optional: just make scrollbar invisible /
            }
            / optional: show position indicator in red */
            ::-webkit-scrollbar-thumb {
            background: #FF0000;
            }
        </style>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.1.1/d3.min.js"></script>
        <script src="https://d3js.org/d3.v4.js"></script>
        <script id="auto-update-images">
            let interval_images
            window.addEventListener('DOMContentLoaded', () => {
                interval_images = setInterval(refresh_images, 1000); // refresh every 1 sec
            })
            
            function refresh_images() {
                if (!document.images) return;
                const totalimages = document.querySelectorAll("img").length - 1;
                const lastimages = parseInt(document.getElementsByTagName('img')[totalimages].getAttribute('name').replace("grafico-betfair-", "")) + 1;
                for (let i = 1; i < lastimages; i++) {
                    try {
                        document.images['grafico-betfair-' + i].src = document.getElementById('barra-de-texto-para-grafico-' + i).value;
                    } catch (e) {
                    }
                }
            }
        </script>
        <script id="random-number">
            function generateRandomIntegerInRange(min, max) {
                return Math.floor(Math.random() * (max - min + 1)) + min;
            }
        </script>
    </head>
    <body style="background-color:black;">
        <div style="color:white;font-weight:bold;overflow:hidden;overflow-y:scroll;" class="grid games" id="Lista-de-Jogos-Lateral">
            <script id="script-da-caixa-de-selecao-suspensa-5">
                var select_5 = d3.select("#Lista-de-Jogos-Lateral")
                .append("div")
                .attr("id","select-box-5")
                .style("width","100%")
                .style("max-height","574px");

                function update() {

                    let data = d3.csv("Lista_de_Jogos.csv");
                        
                    let update_5 = select_5.selectAll(".matches")
                        .data(data,d=>d.label);
                    
                    update_5.exit().remove();

                    // Enter new divs:
                    const enter = update_5.enter()
                        .append("div")
                        .attr("class","matches")
                    
                    // Append the children to entered divs:
                    enter.append("form")
                    .attr("action",d => d.market)
                    .attr("target","_blank")
                    .style("width","100%")
                    .append("input")
                    .attr("type","submit")
                    .attr("target","_blank")
                    .style("width","100%")
                    .attr("value","Jogo Betfair");
                    
                    enter.append("form")
                        .append("input")
                        .attr("type","text")
                        .attr("id",d => "barra-de-texto-para-grafico-" + d.numbergame)
                        .style("width","100%")
                        .attr("value", d=>d.label);
                        
                    enter.append("img")
                        .attr("type","text")
                        .attr("src","https://sitedeapostas-com.imgix.net/assets/local/Company/logos/betfair_logo_transp.png?auto=compress%2Cformat&fit=clip&q=75&w=263&s=c1691b4034fd0c4526d27ffe8b1e839c")
                        .attr("name",d => "grafico-betfair-" + d.numbergame);
                }
                
                update();
                    setInterval(update,2000);
            </script>
        </div>
    </body>
</html>

【问题讨论】:

  • 将解析操作移到你的更新函数中,否则你只会读取一次文件并每2秒更新一次你的DOM,但你读取的内容将保持不变。
  • 嗨@pazitos10 我尝试使用fetch("Lista_de_Jogos.csv") 加载文件,但是在读取数据时会产生错误,即使在函数内部我也无法将CSV 转换为值来工作
  • 常规 fetch 可能对您的用例没有用处。你试过d3-fetch吗?它允许您获取和解析 csv 文件以将其与 d3 一起使用。
  • 我尝试更改为let data = d3.csv("Lista_de_Jogos.csv");,但页面返回时没有创建任何值
  • 您是否在开发者控制台中收到任何错误消息?也许网络选项卡?我指的是 404 错误或类似的错误,表明该文件不在路径指示的位置,或者您为其设置了错误的路径,假设是本地文件。

标签: javascript html csv d3.js


【解决方案1】:

我已对您的代码进行了一些调整以使其正常工作。

  • 首先,我将所有脚本标签移到&lt;body&gt;标签的末尾,并按顺序放置。
  • 其次,我添加了d3-fetch.js作为依赖项,并删除了重复的d3.js
  • 第三,我禁用了所有自动更新代码,以测试代码并避免发疯。

当我在不使用 Web 服务器的情况下使用浏览器打开 HTML 文件时,对文件的请求失败,因此代码不起作用。 我在 VSCode 中安装了Live Server,它立即开始工作,能够读取文件并将元素附加到正文。

我遇到的另一个错误是Uncaught TypeError: document.getElementsByTagName(...)[totalimages] is undefined,因为它可以读取数据。一旦我可以打开文件,该错误就消失了。

<html>
    <head>
        <style>
            body {
            box-sizing: border-box;
            }
            .matches {
            text-align:center;
            float: left;
            width: 355px;
            border: 1px solid white;
            border-collapse: collapse;
            }
            .column {
            text-align:center;
            float: left;
            width: 355px;
            border: 1px solid white;
            border-collapse: collapse;
            }
            .grid {
            float: left;
            width: 1431px;
            }
            .row:after {
            content: "";
            display: table;
            clear: both;
            }
            .button {
            background-color: #33ccff;
            color: black;
            font-weight: bold;
            }
            input[type=submit] {
            background-color: #33ccff;
            color: black;
            font-weight: bold;
            }
            html {
            overflow: scroll;
            overflow-x: hidden;
            }
            ::-webkit-scrollbar {
            width: 0px; /* remove scrollbar space /
            background: transparent; / optional: just make scrollbar invisible /
            }
            / optional: show position indicator in red */
            ::-webkit-scrollbar-thumb {
            background: #FF0000;
            }
        </style>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.1.1/d3.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/d3-fetch@3"></script>
    </head>
    <body style="background-color:black;">
        <div style="color:white;font-weight:bold;overflow:hidden;overflow-y:scroll;" class="grid games" id="Lista-de-Jogos-Lateral">
        </div>
    
        <script id="script-da-caixa-de-selecao-suspensa-5">
            var select_5 = d3.select("#Lista-de-Jogos-Lateral")
            .append("div")
            .attr("id","select-box-5")
            .style("width","100%")
            .style("max-height","574px");

            async function update() {

                let data = await d3.csv("./Lista_de_Jogos.csv");
                console.log("Data from CSV file: ", {data})

                let update_5 = select_5.selectAll(".matches")
                    .data(data,d=>d.label);
                
                update_5.exit().remove();

                // Enter new divs:
                const enter = update_5.enter()
                    .append("div")
                    .attr("class","matches")
                
                // Append the children to entered divs:
                enter.append("form")
                    .attr("action",d => d.market)
                    .attr("target","_blank")
                    .style("width","100%")
                    .append("input")
                    .attr("type","submit")
                    .attr("target","_blank")
                    .style("width","100%")
                    .attr("value","Jogo Betfair");
                
                enter.append("form")
                    .append("input")
                    .attr("type","text")
                    .attr("id",d => "barra-de-texto-para-grafico-" + d.numbergame)
                    .style("width","100%")
                    .attr("value", d=>d.label);
                    
                enter.append("img")
                    .attr("type","text")
                    .attr("src","https://sitedeapostas-com.imgix.net/assets/local/Company/logos/betfair_logo_transp.png?auto=compress%2Cformat&fit=clip&q=75&w=263&s=c1691b4034fd0c4526d27ffe8b1e839c")
                    .attr("name",d => "grafico-betfair-" + d.numbergame);
            }
            
            update();
            console.log("Auto CSV update is disabled!")
            //setInterval(update,2000);
        </script>
        <script id="auto-update-images">
            let interval_images
                window.addEventListener('DOMContentLoaded', () => {
                    console.log("Auto update images is disabled!")
                    interval_images = refresh_images(); //setInterval(refresh_images, 5000); // refresh every 5 sec
                })
                
            function refresh_images() {
                if (!document.images) return;
                const totalimages = document.querySelectorAll("img").length - 1;
                const lastimages = parseInt(document.getElementsByTagName('img')[totalimages].getAttribute('name').replace("grafico-betfair-", "")) + 1;
                for (let i = 1; i < lastimages; i++) {
                    try {
                        document.images['grafico-betfair-' + i].src = document.getElementById('barra-de-texto-para-grafico-' + i).value;
                    } catch (e) {
                    }
                }
            }
        </script>
        <script id="random-number">
            function generateRandomIntegerInRange(min, max) {
                return Math.floor(Math.random() * (max - min + 1)) + min;
            }
        </script>
    </body>
</html>

如果您尝试使用“运行代码 sn-p”按钮运行此代码,它将失败,因为它无权访问 csv 文件。不过,它应该适用于有效数据。 您的代码希望使用 csv 文件中的可用字段替换图像 URL,因此请确保您的数据具有这些字段。

【讨论】:

  • 注意:当我称你为野兽时,这是好的一面,好吗?哈哈。再次感谢您!
猜你喜欢
  • 2014-04-29
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 2016-03-03
  • 1970-01-01
  • 2017-11-05
相关资源
最近更新 更多