たぶんできました。
Plotly.js
plot.ly
現段階でわたしが選んだのはこれです。奥が深そうであり,かつ,こだわらなければシンプルに書ける。
なんといいもの。
Libralyファイルもたった一つです。大き目ではありますが,そこは機能の魅力に負けました。
HTAのコードだけ載せます。
<!doctype html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge" charset="utf-8"> <!--meta文で互換性--> <title>テストアンケート</title> <style type="text/css"> table{border-collapse: collapse;} table,tr,td{border: solid 2px black;} td.clsmondai{padding-left: 5px;font-weight: bold;background-color: black;color: white;width:400px} td.clskaito{padding-left: 20px;background-color: antiquewhite} </style> <script src="plotly-latest.min.js"></script> <script> var ForReading = 1; var ForWriting = 8; var p=[ [1,'クラス','select',['1A','1F','1L','2A','2F','2L','3A','3F','3L']], [2,'番号','select',renban(1,41)], [3,'好きな科目は','check',['国語','社会','数学','理科','英語']], [4,'この中で一番好きな食べ物はどれか。','radio',['りんご','バナナ','みかん','ごはん','おかし']], [5,'好きなペットは何か。(複数えらんでいい)','check',['犬','猫','ハムスター']], [6,'自分を動物に例えると。','text',''], [7,'この変なアンケートについて感想をどうぞ。','multi',''] ] var thisName=location.pathname thisName=thisName.slice(thisName.lastIndexOf("\\")+1,thisName.lastIndexOf(".")); var fso = new ActiveXObject("Scripting.FileSystemObject"); if (fso.FolderExists(".\\data")==false) fso.CreateFolder(".\\data"); var DataFile = ".\\data\\"+thisName+"_data.csv"; if (fso.FileExists(DataFile)==false){ var data = fso.OpenTextFile(DataFile, ForWriting,true); var tmp="user" for (var i=0;i<p.length;i++){tmp+=","+p[i][1]} tmp+=",Date" data.WriteLine(tmp); data.Close() } var User=new ActiveXObject("WScript.Network").UserName; //ベタ打ちここまで function init(){ resizeTo(500,600); makeForm() } function renban(s,e){ var arr=[] for (var i=s;i<=e;i++) arr.push(i) return arr } function makeForm(){ var tmp=[] tmp.push("<table>") for(var i=0;i<p.length;i++) tmp.push(makeElement(i)) tmp.push("</table>") document.getElementById("table").innerHTML=tmp.join("") } function makeElement(No){ var mondai=p[No][1] var name="No"+(No) var type=p[No][2] var arr=p[No][3] var html=[]; var tmp; switch(type){ case "select":tmp = makeSelectElement(name,"select",arr);break case "radio":tmp = makeSelectElement(name,"radio",arr);break case "check":tmp = makeSelectElement(name,"checkbox",arr);break case "text":tmp="<input type='text' name='" + name + "' size='45' />";break case "multi":tmp="<textarea name='" + name +"' rows='5' cols='46' ></textarea>";break } html.push("<tr><td class='clsmondai'>" + (No+1) + " " + mondai + "</td></tr>") html.push("<tr><td class='clskaito'>") html.push(tmp+"</td>") return html.join("") } function makeSelectElement(name,type,arr){ switch(type){ case "select": var tmp=[] tmp.push("<select name='" + name +"'>") for(var i=0;i<arr.length;i++){tmp.push("<option value='" + arr[i]+"'>"+arr[i]+"</option>")} tmp.push("</select>") element=tmp.join("") break case "radio": case "checkbox": //間違いじゃないよ var tmp=[] for(var i=0;i<arr.length;i++){ tmp.push("<input type='"+ type +"' name='" + name + "' value='" + arr[i] +"'>"+arr[i]+"<br>") } element=tmp.join("") break } return element } // データ収集部分 function result(){ var html=[] html.push(User+",") for (var i=0;i<p.length;i++){ html.push(getData("No"+i,p[i][2])+",") } html.push(Date()) return html.join("") } function PostData(str){ var fso = new ActiveXObject("Scripting.FileSystemObject"); var data = fso.OpenTextFile(DataFile, ForWriting); data.WriteLine(result()); data.Close(); makeGraph() } function getData(name,type){ switch(type){ case "radio": case "check": return getCheck(name); break; case "text": case "multi": case "select": return document.getElementsByName(name)[0].value.replace(/\r?\n/g,"_"); break; } } function getCheck(name){ var CHECK=document.getElementsByName(name) var tmp="" for(var i=0;i<CHECK.length;i++){ if(CHECK[i].checked) tmp+="_" +CHECK[i].value } return tmp.substring(1) } function makeGraph(){ var fso = new ActiveXObject("Scripting.FileSystemObject") var data = fso.OpenTextFile(DataFile, ForReading) var data= data.ReadAll() var rowCount=data.split("\n").length var res=[] res.push("<table>") var graphNo=0 var graphvalues=[] var graphlabels=[] var graphtype=[] for (var i=0;i<p.length;i++){ res.push("<tr><td class='clsmondai'>"+p[i][1]+"</td></tr>") switch(p[i][2]){ case "select": case "radio": case "check": var tmpArray = [] var count={} for (var j=1;j<rowCount-1;j++){ var tmp=data.split("\n")[j].split(",")[i+1] if (!tmp==""){ var tmp2=tmp.split("_") for (var k=0;k<tmp2.length;k++) { var key=tmp2[k] count[key]=(count[key])? count[key]+1 : 1; } } } for (var key in count){ tmpArray.push([key,count[key]]) } var tmp3=[] var tmp4=[] for (var k=0;k<tmpArray.length;k++){ tmp3.push(tmpArray[k][0]) tmp4.push(tmpArray[k][1]) } graphlabels[graphNo]=tmp3 graphvalues[graphNo]=tmp4 graphtype[graphNo]= (p[i][2]=='radio') ? 'pie' : 'bar' res.push("<tr><td><div id='graph"+graphNo+"'></div></td></tr>") graphNo++ break case "text": case "multi": res.push("<tr><td>") for (var j=1;j<rowCount;j++){ tmp=data.split("\n")[j].split(",")[i+1] if (!tmp=="") res.push(tmp+"<br>") } res.push("</td></tr>") break } } res.push("</table>") res.push('<input type="button" href="#" value="グラフ更新" onClick="makeGraph()"/>') document.body.innerHTML=res.join("") for (var i=0;i<graphvalues.length;i++) { drawGraph(graphvalues[i],graphlabels[i],graphtype[i],'graph'+i) } } function drawGraph(gvalues,glabels,gtype,gdiv){ if (gtype=='pie'){ var data = [{ values: gvalues, labels: glabels, type: 'pie' }]; } else { var data = [{ x: glabels, y: gvalues, type: 'bar' }]; } var layout = { height: 400, width: 388 }; Plotly.newPlot(gdiv, data, layout); } </script> </head> <body onload="init()"> <form id="formFld"> <div id="table"></div> <input type="button" href="#" value="送信する" onClick="PostData()"/> <input type="button" href="#" value="グラフ表示" onClick="makeGraph()"/> </form> </body> </html>
グラフを書いているところは
function drawGraph(gvalues,glabels,gtype,gdiv){ if (gtype=='pie'){ var data = [{ values: gvalues, labels: glabels, type: 'pie' }]; } else { var data = [{ x: glabels, y: gvalues, type: 'bar' }]; } var layout = { height: 400, width: 388 }; Plotly.newPlot(gdiv, data, layout); }
ここだけなんです。gvalues,glabelsは配列を与えています。
驚異的なシンプルさです。
これにより作られるグラフはこんな感じ
とても満足しています。canvasでjavascriptだけで書く方法もネットで探せばありましたが,
libralyも使えるべきだと思い,使う方向で模索しました。
私も慣れないうちは手間取ったので,今はライブラリのファイルを同じフォルダに入れている,という想定のコードになっています。
職場で使うならフルパスで与えておいて,どこにhtaファイルをコピーしても使えるようにするのがよさそうですね。
ライブラリファイルは
plot.ly
ここで落とせます。
最初はグラフライブラリの殆どが動かずとても困りましたが,最終的には全部動くようになりました。
結局知らないせいで視野や選択肢が狭くなっていただけだったようです。
今までhtaで動かないなぁと思っていたことも,互換設定のmeta記述で動くのかもしれません。
いろんな意味で今回のがんばりは今後につながりそうです。この三連休ひたすらやってたので,時間は費やしたけど
集中的に取り組んで,だいぶ変わりました。
vba vbs Jscript javascript
ここら辺がわかればたぶん本職じゃないので,ずっと戦えるはず。
ほんとにそう思ってるのでしっかりやろう。
HTAのタイマー非常に使いやすくて重宝しているので,いろんなものをHTAに作り直してみたいものです。
あとは,今回JavaScriptの配列の中に配列がある場合について,うまく制御できずにかなり時間を費やしたので,
その辺をいろいろと試したい。
デバッグ環境が欲しい。VBEditor並みとまではいかなくても,なんとかしたいな・・。
Dreamweaverを使いこなせていないだけのようでもありますが・・(;´∀`)