繁体   English   中英

无法从JSON文件读取数据并将其显示在Canvas上

[英]Trouble reading data from JSON file and displaying it on Canvas

背景

(是JS的新手,并且是第一次使用画布)

我正在尝试从https://analytics.usa.gov/读取JSON文件,并使用画布显示它。 我只想在下拉列表中填充前8条记录。

我成功地在计算机上本地获取了文件转储。 代码在这里( https://jsfiddle.net/uh8jamdo/

我正在尝试做的是:1)应该在下拉菜单中填充数据的页面标题2)当用户选择一个并单击提交时。 我要显示页面标题,该特定页面标题的URL和活动用户。

以下是我的尝试。 有人可以指导我吗? 我已经编写了显示画布,文本和更新数据的代码。

 window.onload = function() { var button = document.getElementById("previewButton"); button.onclick = previewHandler; } function previewHandler() { var canvas = document.getElementById("analytics"); var context = canvas.getContext("2d"); drawText(canvas, context); } // draws all the text, including the Analytics function drawText(canvas, context) { context.font = "50px serif"; context.fillStyle = "black"; context.font = "bold 1em sans-serif"; context.textAlign = "left"; context.fillText("No of People online on Govt Websites", 20, 40); // draw the analytics! selectObj = document.getElementById("site"); index = selectObj.selectedIndex; var site = selectObj[index].value; context.font = "italic 1.2em serif"; context.fillText(site, 30, 100); } function updateAnalytics(site) { var siteSelection = document.getElementById("site"); // add all data to the site dropdown for (var i = 0; i < site.length; i++) { site = site[i]; // create option var option = document.createElement("option"); option.text = site.text; // strip any quotes out of the site so they don't mess up our option option.value = site.text.replace("\\"", "'"); // add option to select siteSelection.options.add(option); } // make sure the top tweet is selected siteSelection.selectedIndex = 0; } 
 canvas { border: 1px solid black; } 
 <canvas width="600" height="200" id="analytics"> <p>You need canvas to see the Analytics Data</p> <p>This example requires a browser that supports the HTML5 Canvas feature.</p> </canvas> <p> <label for="site">Pick a Site</label> <select id="site"></select> </p> <p> <input type="button" id="previewButton" value="Preview"> </p> </form> </br> <script src="https://analytics.usa.gov/data/live/top-pages-realtime.json"> </script> 

您基本上已经有了它,但是有很多奇怪的事情,我认为我可以修改您的代码,并且您可以学习我所做的事情。 我发现了一些问题:

  • 无需将脚本硬编码到html文档中,我们可以通过XMLHttpRequest获取URL的内容。 您将遇到一些计时问题。
  • 这些天实际上没有必要使用formsubmit 现代Web设计通常将在客户端上维护一个有状态的对象,并将使用上述XMLHttpRequest东西与各种后端进行通信。 这样,我们不必每次从服务器返回响应时都重新绘制页面。 当用户单击“提交”时,您可以捕获该事件,但是需要遵循一个协议(从处理程序中返回false),以防止页面重新加载并破坏用户的选择。 用户将看不到您的画布,因为您每次都将重新加载新的画布。 他们也不会看到他们的选择,因为您将在每次提交后重置它。
  • 设置javascript值时,我们不需要带引号。 首先,因为这些事情通常会为您逃脱,但其次,因为在您的情况下,仅存储选择的索引实际上更容易。 您真的根本不需要价值。 如果将此修改后的值用作键,可能会导致问题。
  • 最小化全局变量的数量。 Javascript确实对闭包提供了很好的支持, 闭包是一种强大的编程构造,可让我们限制变量的可见性。 这将使在调试器中测试代码变得容易得多,因为所有内容都将集中在一个位置。 (更多的是样式而不是实际的问题)。
  • 如果打算重复使用画布,请确保将其清除。 连续调用fillText将破坏先前的文本。
  • 我们还有很多其他可以探索的东西,但是希望这可以帮助您入门。

另外,在不依靠外部库的情况下完成所有这些工作非常好,但是您也应该将它们检出-javascript可以做一些令人兴奋的事情。 我推荐D3.js

最后,这是经过修改的javascript,我相信它可以完成您指定的功能,并且考虑到了我的建议:

(您可以在此处使用jsfiddle进行游戏: https ://jsfiddle.net/dancingplatypus/L92fq305/6/)

var site_analytics = {
    run: function () {
        var ANALYTICS_SITE = 'https://analytics.usa.gov/data/live/top-pages-realtime.json';
        var elem_select = document.getElementById("site");
        var elem_title = document.getElementById("site_title");
        var elem_preview = document.getElementById("previewButton");
        var site_data = null;

        elem_preview.onclick = render_selection;
        elem_select.onchange = render_selection;

        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function () {
            console.log('heya');
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                site_data = JSON.parse(xmlhttp.responseText);
                sync_selector();
            }
        }
        xmlhttp.open("GET", ANALYTICS_SITE, true);
        xmlhttp.send();

        function sync_selector() {
            console.log('boyo');
            elem_select.innerHtml = null;
            if (site_data) {
                for (var loop = 0; loop < Math.min(8, site_data.data.length); loop++) {
                    var item = site_data.data[loop];
                    var option = document.createElement('option');
                    option.text = item.page_title;
                    option.value = loop;
                    elem_select.add(option);
                }
            }
            selected_index = (site_data.data.length > 0) ? 0 : null;
            render_selection();
        }

        function render_selection() {
            var index = elem_select.selectedIndex;
            var item = site_data ? site_data.data[index] : null;

            elem_title.innerText = item ? item.page_title : 'n/a';
            var canvas = document.getElementById("analytics");
            var context = canvas.getContext("2d");
            context.clearRect(0, 0, canvas.width, canvas.height);
            drawText(item, canvas, context);
        };

        // draws all the text, including the Analytics
        function drawText(item, canvas, context) {
            context.font = "50px serif";
            context.fillStyle = "black";
            context.font = "bold 1em sans-serif";
            context.textAlign = "left";
            context.fillText("No of People online on Govt Websites", 20, 40);

            // draw the analytics!
            context.font = "italic 1.2em serif";
            context.fillText(item ? item.active_visitors : '', 30, 100);
        }
    }
};

window.onload = function () {
    site_analytics.run();
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM