从XML源动态设置条形图值 [英] Dynamically setting bar graph values from a XML source

查看:83
本文介绍了从XML源动态设置条形图值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

昨天,我使用jQuery解析了一些RSS到菜单中的一些很棒的帮助: Parse RSS提要与JS ,并受此启发,我想用类似的东西来控制网站上的一些图表栏。

一些背景:


我们的目标是在我们的即将到来的技术评论在
a网页上,这意味着您将产品分配给绝对分数(让b $ b表示67),然后最高分可以随着新产品和
更好的产品投放市场而移动。这样,您仍然可以从
阅读去年的评论,并将评分用于
的某些内容,因为67的评分现在是针对今年的
max-score来衡量的。希望它是有道理的。

无论如何,我们的CMS只允许javascript嵌入到新闻条目中,所以我无法存储我们的评论在SQL中使用分数或使用PHP,并且我正在考虑使用XML(不是最优的,但应该可以)。然后每个评论将包含一定数量的结果,包括前面提到的最终评分(以及一些中间子评分)。我需要插入一段JS代码,从XML文件中提取特定评论的分数,并插入绘制条的HTML代码。

我有一个JSfiddle,它包含了XML,它有图表(尽管是硬编码),并且使用上一个问题中的jQuery代码,我可以提取结果,但代码循环遍历所有XML,我真的不知道如何挑选我需要的具体评论数量,也不知道如何根据最高分进行衡量,所以它现在只是打印所有内容,并根据最高分为100来计算分数。 t将这些值绑定到我的图表上,所以测试版本只是将结果打印在ul / li中。



链接到JSFiddle

所以基本上我需要一些我可以调用的代码我的HTML符合

  ShowScores (testno)

这会将所有内容写入第一个

 < div class =row> ..< / row>包含条的

,其中条的%-width将被计算为分配的分数除以最高分数:


  • 每个项目有3个分配分数:scorePicture,scoreFeature,scoreUI和1个计算总分(加权平均值)

  • 全球最高分数存在于3个分数中的每一个:topscorePicture,topscoreFeature,topscoreUI



吸吮JS,我已经花了5个小时到达这一点,我不知道如何从例如一个 testscore.xml 文件,然后提取我需要的jQuery - 我可能还需要一些帮助,使我的HTML加载脚本,即如何在之后调用它。 关于jQuery的文档涉及加载XML中的所有内容,而不仅仅是一个特定的节点?

所有帮助表示赞赏。



我对某些伪代码的想法是一个脚本,当从我的HTML文档中调用会做类似于
$ b $ pre $函数(reviewNo)
var max1 =从XML $ load maxscore1
var max2 =从XML加载maxscore2
var max3 =从XML加载maxscore3

var score1 =加载assignedscore1 for reviewNo from XML
var score2 =加载assignedscore2 for reviewNo from XML
var score3 = load assignedscore2 for reviewNo from XML

计算栏1,栏2和栏3的宽度并保存为变量math.round()
写入HTML DIV代码并用从
之上的计算值来替代条的宽度


解决方案

好吧,所以我想到了jQuery不会给我我需要的东西,所以我转向普通的JS加载XML

  function loadXMLDoc(filename) 
{
if(window.XMLHttpRequest)
{
xhttp = new XMLHttpRequest();
}
else //代码为IE5和IE6
{
xhttp = new ActiveXObject(Microsoft.XMLHTTP);
}
xhttp.open(GET,filename,false);
xhttp.send();
return xhttp.responseXML;
}

然后,我使用HTML中的代码:

 < script> 
//应该加载哪个测试否
var testNo = 1;

//载入XML
xmlDoc = loadXMLDoc(testscores.xml);

//提取图片的最高分数
tsp = xmlDoc.getElementsByTagName(topscorePicture)[0];
topspvalue = tsp.childNodes [0];

//提取特征的最高分数
tsf = xmlDoc.getElementsByTagName(topscoreFeature)[0];
topsfvalue = tsf.childNodes [0];

//提取UI
的最高分数tsui = xmlDoc.getElementsByTagName(topscoreUI)[0];
topsuivalue = tsui.childNodes [0];

//提取特定测试编号的图片分数。
sp = xmlDoc.getElementsByTagName(scorePicture)[testNo];
spvalue = sp.childNodes [0];

//提取特定测试编号的特征分数。
sf = xmlDoc.getElementsByTagName(scoreFeature)[testNo];
sfvalue = sf.childNodes [0];

//提取特定测试编号的UI分数。
sui = xmlDoc.getElementsByTagName(scoreUI)[testNo];
suivalue = sui.childNodes [0];

//计算当前分数
scorePicture = Math.round(Number(spvalue.nodeValue)/ Number(topspvalue.nodeValue)* 100);
scoreFeature = Math.round(Number(sfvalue.nodeValue)/ Number(topsfvalue.nodeValue)* 100);
scoreUI = Math.round(Number(suivalue.nodeValue)/ Number(topsuivalue.nodeValue)* 100);
scoreTotal = Math.round(0.5 * scorePicture + 0.25 * scoreFeature + 0.25 * scoreUI);

//构造HTML
HTMLchunkStart =< div style = \float:Right; text-align:right;宽度:40px; font-weight:500; padding-left:20px; color:#666; \>< i class = \fa fa-picture-o \>< / i>< / div>< div class = \progress\ style = \background-color:#E2E2E2\\>;
pictureBar =< div class = \progress-bar\role = \progressbar\aria-valuenow = \+ Number(spvalue.nodeValue)+\ aria-valuemin = \0 \aria-valuemax = \+ Number(topspvalue.nodeValue)+\style = \width:+ scorePicture +%+; \ > 中+ scorePicture + %< / DIV>中;
HTMLchunk1 =< / div>< div style = \float:Right; text-align:right;宽度:40px; font-weight:500; padding-left:20px; color:#666; \>< i class = \fa fa-cogs \>< / i>< / div>< div class = \\progress \style = \ 背景色:#E2E2E2\ >中;
featureBar =< div class = \progress-bar\role = \progressbar\aria-valuenow = \+ Number(sfvalue.nodeValue)+\ aria-valuemin = \0 \aria-valuemax = \+ Number(topsfvalue.nodeValue)+\style = \width:+ scoreFeature +%+;\ > 中+ scoreFeature + %< / DIV>中;
HTMLchunk2 =< / div>< div style = \float:Right; text-align:right;宽度:40px; font-weight:500; padding-left:20px; color:#666; \>< i class = \fa fa-user \>< / i>< / div>< div class = \\progress \style = \ 背景色:#E2E2E2\ >中;
UIbar =< div class = \progress-bar\role = \progressbar\aria-valuenow = \+ Number(suivalue.nodeValue)+\ aria-valuemin = \0\aria-valuemax = \+ Number(topsuivalue.nodeValue)+\style = \width:+ scoreUI +%+;\ > 中+ scoreUI + %< / DIV>中;
HTMLchunk3 =< / div>< div style = \padding-top:3px; float:Right; text-align:right;宽度:40px; font-weight:500; padding-left:20px; color:#666; \>< i class = \fa fa-star \>< / i>< / div>< div class = \progress progress-lg\\ \\style = \background-color:#E2E2E2; height:30px; \>;
totalBar =< div class = \progress-bar progress-bar-info\role = \progressbar\aria-valuenow = \+ scoreTotal +\aria -valuemin = \0 \aria-valuemax = \100 \style = \width:+ scoreTotal +%+; padding-top:4px; \>+ scoreTotal + %< / DIV> 中;

//写入HTML
document.write(HTMLchunkStart + pictureBar + HTMLchunk1 + featureBar + HTMLchunk2 + UIbar + HTMLchunk3 + totalBar);
< / script>

目前我直接把它放在我的HTML中,但我想把它放在一个单独的文件中,只需通过例如调用代码即可

 < script> showScore(1)< / script> 

获取XML中的第二个条目。我非常接近,但我希望推动正确的方向,让我的代码变成一个可以接受单个输入的函数,这个输入将被用作testNo变量,然后返回所有的HTML代码I在我的document.write最后。



我也意识到我的JS可能不是最有效也不漂亮,所以任何关于清理的建议也是受欢迎的。

另一个想到的特点是根据分数改变条的颜色。目前的进度条类只是普通的蓝色,但我可以追加另一个类来改变颜色。在我看来,这可以通过创建一些颜色类来实现,然后依赖于%得分,相应的颜色类将被添加到HTML代码中。如果有人有关于如何做到这一点的想法,我也很感激一些意见。我会用开关从数组中选择类名或什么?


I got some great help parsing some RSS into a menu yesterday using jQuery Parse RSS feed with JS, and inspired by this I would like to use something similar to control some chart bars on a website.

Some background:

We are aiming to use a floating score in our upcoming tech reviews on a webpage, meaning that you assign a product an absolute score (lets say 67) and then the maximum score would be able to move as new and better products hit the market. This way you would still be able to read a review from last year and use the score for something meaningful, as the score of 67 is now measured against this years max-score. Hope it makes sense.

Anyhow, our CMS only permits javascript to be embedded in news entries, so I can't store our review scores in SQL or use php, and I was thinking of using XML instead (not optimal, but it should work). Each review would then contain a certain number of results including the beforementioned final score (and some intermediate sub-scores as well). I need to be able to insert a piece of JS code that extracts the scores for a specific review from the XML file and inserts the HTML code needed to draw the bars.

I have a JSfiddle set up, that contains the XML, it has the chart (hardcoded though), and using the jQuery code from my previous question I can sort of extract the results, but the code loops through all the XML and I don't really have a clue how to pick out the specific review number I need nor how to get things measured against the max-score, so it just prints everything right now and calculates a score based on a max-score of 100. I haven't tied the values to my chart yet, so the test version just prints the results in a ul/li.

Link to JSFiddle

So basically I need some sort of code that I can invoke from my HTML that goes along the lines of

ShowScores(testno)

that would write everything inside the first

<div class="row">..</row> 

containing the bars, where the %-width of the bars would be calculated as the score assigned divided by the maxscore:

  • Each item has 3 assigned scores: scorePicture, scoreFeature, scoreUI, and 1 calculated total score (weighted average)
  • A global max score exists for each of the 3 scores: topscorePicture, topscoreFeature, topscoreUI

As I suck at JS, I have spent 5 hours getting to this point, and I have no clue how to make things load from e.g. a testscore.xml file instead and then extract what I need with jQuery - and I probably also need some help making my HTML load the script i.e. how to invoke it afterwards. The documentation on jQuery is concerned with loading all content in the XML and not just a specific node?

All help is appreciated.

My own thoughts on some pseudo code would be a script that, when envoked from my HTML document would do something like

function(reviewNo)
var max1 = load maxscore1 from XML
var max2 = load maxscore2 from XML
var max3 = load maxscore3 from XML

var score1 = load assignedscore1 for reviewNo from XML
var score2 = load assignedscore2 for reviewNo from XML
var score3 = load assignedscore2 for reviewNo from XML

Calculate % width of bar 1, bar 2 and bar 3 and save as variables as math.round()
write HTML DIV code and subsitute the width of the bars with the calculated values from above

解决方案

Ok, so I figured that jQuery was not going to give me what I needed, so I turned to plain JS loading the XML with

function loadXMLDoc(filename)
{
if (window.XMLHttpRequest)
  {
  xhttp=new XMLHttpRequest();
  }
else // code for IE5 and IE6
  {
  xhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xhttp.open("GET",filename,false);
xhttp.send();
return xhttp.responseXML;
}

I then use the code in my HTML as:

<script>
    // Which test no should be loaded
    var testNo = 1;

    //Load the XML
    xmlDoc=loadXMLDoc("testscores.xml");

    //Extract the highest score for picture
    tsp=xmlDoc.getElementsByTagName("topscorePicture")[0];
    topspvalue= tsp.childNodes[0];

    //Extract highest score for features
    tsf=xmlDoc.getElementsByTagName("topscoreFeature")[0];
    topsfvalue= tsf.childNodes[0];

    //Extract highest score for UI
    tsui=xmlDoc.getElementsByTagName("topscoreUI")[0];
    topsuivalue= tsui.childNodes[0];

    //Extract  picture score for the specific test no.
    sp=xmlDoc.getElementsByTagName("scorePicture")[testNo];
    spvalue=sp.childNodes[0];

    //Extract Feature score for the specific test no.
    sf=xmlDoc.getElementsByTagName("scoreFeature")[testNo];
    sfvalue=sf.childNodes[0];

    //Extract UI score for the specific test no.
    sui=xmlDoc.getElementsByTagName("scoreUI")[testNo];
    suivalue=sui.childNodes[0];

    //Calculate current scores
    scorePicture = Math.round(Number(spvalue.nodeValue)/Number(topspvalue.nodeValue)*100);
    scoreFeature = Math.round(Number(sfvalue.nodeValue)/Number(topsfvalue.nodeValue)*100);
    scoreUI = Math.round(Number(suivalue.nodeValue)/Number(topsuivalue.nodeValue)*100);
    scoreTotal = Math.round(0.5*scorePicture + 0.25*scoreFeature + 0.25*scoreUI);

    //Construct HTML
    HTMLchunkStart = "<div style=\"float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-picture-o\"></i></div><div class=\"progress\" style=\"background-color:#E2E2E2\">";
    pictureBar = "<div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\""+Number(spvalue.nodeValue)+"\" aria-valuemin=\"0\" aria-valuemax=\""+Number(topspvalue.nodeValue)+"\" style=\"width:"+ scorePicture+"%"+";\">"+scorePicture+"%</div>";
    HTMLchunk1 =  "</div> <div style=\"float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-cogs\"></i></div><div class=\"progress\" style=\"background-color:#E2E2E2\">";
    featureBar = "<div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\""+Number(sfvalue.nodeValue)+"\" aria-valuemin=\"0\" aria-valuemax=\""+Number(topsfvalue.nodeValue)+"\" style=\"width:"+ scoreFeature+"%"+";\">"+scoreFeature+"%</div>";
    HTMLchunk2 = " </div><div style=\"float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-user\"></i></div><div class=\"progress\" style=\"background-color:#E2E2E2\">";
    UIbar= "<div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\""+Number(suivalue.nodeValue)+"\" aria-valuemin=\"0\" aria-valuemax=\""+Number(topsuivalue.nodeValue)+"\" style=\"width:"+ scoreUI+"%"+";\">"+scoreUI+"%</div>";
    HTMLchunk3 =  "</div> <div style=\"padding-top: 3px;float: Right; text-align: right; width: 40px; font-weight: 500; padding-left: 20px; color: #666;\"><i class=\"fa fa-star\"></i></div><div class=\"progress progress-lg\" style=\"background-color:#E2E2E2;height: 30px;\">"; 
    totalBar =  "<div class=\"progress-bar progress-bar-info\" role=\"progressbar\" aria-valuenow=\""+scoreTotal+"\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"width:"+ scoreTotal+"%"+";padding-top: 4px;\">"+scoreTotal+"%</div>";

    //Write the HTML
    document.write(HTMLchunkStart + pictureBar + HTMLchunk1+featureBar+HTMLchunk2+UIbar+HTMLchunk3+totalBar);
</script>

Currently I put this directly in my HTML, but I would like to put it in a separate file and simply call the code by e.g.

<script>showScore(1)</script>

To get the second entry in the XML. I am so close, but I would like a push in the right direction on how to make my code into a function that can accept a single input, which would be used as the "testNo" variable and then return all the HTML-code I have in my document.write at the end.

I also realise that my JS might not be the most efficient nor pretty, so any advice regarding clean-up is also welcome.

Another feature that comes to mind, would be the possibility to change the color of the bars according to the score. The current "progress-bar" class is just plain blue, but I could append another class to only change the colour. In my mind this would be possible by creating some classes for colours and then dependent on the % score the appropriate colour class would be added to the HTML code. If someone has an idea on how to do this I would also appreciate some input. Would I use a switch to pick the class names from an array or what?

这篇关于从XML源动态设置条形图值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆