D3.js 簡介D3 的全稱是(Data-Driven Documents),顧名思義可以知道是一個被數據驅動的文檔。聽名字有點抽象,說簡單一點,其實就是一個 JavaScript 的函數庫,使用它主要是用來做數據可視化的。 D3的特點是通過JavaScript代碼實現svg圖標。 D3圖表和Thi ...
D3.js 簡介
D3 的全稱是(Data-Driven Documents),顧名思義可以知道是一個被數據驅動的文檔。聽名字有點抽象,說簡單一點,其實就是一個 JavaScript 的函數庫,使用它主要是用來做數據可視化的。
D3的特點是通過JavaScript代碼實現svg圖標。
D3圖表和ThingJS結合方法
有ThingJS平臺目前只有線上開發的方式,故需要通過html5的postMessage 消息機制來實現圖標和ThingJS中的3D場景交互。
D3圖表實現
首先用D3代碼畫一個餅圖。
代碼如下:
var data = [ ['叉車', 11964], ['轎車', 18799], ['警車', 51966], ['皮卡', 35876], ]; var width = 400, height = 400; //div--svg--g--pie--text //SVG var svg = d3.select("#container") .append("svg") .attr("width", width) .attr("height", height) svg.append("g") .append("text") .text('車輛銷售餅圖') .attr("class", "subTitle") .attr("x", 6) .attr("y", 18); //g var g = svg.append("g") .attr("transform", "translate(200,200)") var arc_generator = d3.svg.arc() .innerRadius(100) .outerRadius(200); var angle_data = d3.layout.pie() .value(function (d) { return d[1]; }) var color = d3.scale.category10(); //pie g.selectAll("path") .data(angle_data(data)) .enter() .append("path") .attr("d", arc_generator) .style("fill", function (d, i) { return color(i); }) //text g.selectAll("text") .data(angle_data(data)) .enter() .append("text") .text(function (d) { return d.data[0]; }) .attr("transform", function (d) { return "translate(" + arc_generator.centroid(d) + ")"; }) .attr("text-anchor", "middle");
圖表的效果如下圖:
ThingJS 3D場景實現
然後在ThingJS平臺搭建一個車輛的場景如下圖:
D3圖表和ThingJS通訊
var iframeDom = document.getElementById('I0'); //pie g.selectAll("path") .data(angle_data(data)) .enter() .append("path") .attr("d", arc_generator) .style("fill", function (d, i) { return color(i); }) .on("mouseover", function (d, i) { //console.log(d); console.log(i); iframeDom.contentWindow.postMessage(i, '*'); }) .on("mouseout", function (d, i) { console.log(-1); iframeDom.contentWindow.postMessage(-1, '*'); });
ThingJS接收到消息對3d對象勾邊
// 接收iframe頁面傳送的數據 window.addEventListener('message', function (e) { var data = e.data; if (data == -1) { var selector = app.query('*'); selector.style.outlineColor = null; } else { var selector = app.query('#1' + data); selector.style.outlineColor = '#ff0000'; } })
最後完整代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body style="margin: 0px"> <div id="container" style="position:absolute; z-index: 2; margin: 15px"></div> <iframe id='I0' style="position:absolute; width: 100%; height: 100%;" src='https://www.thingjs.com/guide/sampleindex.html?m=oLX7p04daC2OdoZCbP6VihD_0XCo/01E401B901B0201E801BD01A6.js?n=7027'></iframe> <script src='js/d3.v3.js'></script> <script> // var iframeDom = window.frames[0]; var iframeDom = document.getElementById('I0'); var data = [ ['叉車', 11964], ['轎車', 18799], ['警車', 51966], ['皮卡', 35876], ]; var width = 400, height = 400; //div--svg--g--pie--text //SVG var svg = d3.select("#container") .append("svg") .attr("width", width) .attr("height", height) svg.append("g") .append("text") .text('車輛銷售餅圖') .attr("class", "subTitle") .attr("x", 6) .attr("y", 18); //g var g = svg.append("g") .attr("transform", "translate(200,200)") var arc_generator = d3.svg.arc() .innerRadius(100) .outerRadius(200); var angle_data = d3.layout.pie() .value(function (d) { return d[1]; }) var color = d3.scale.category10(); //pie g.selectAll("path") .data(angle_data(data)) .enter() .append("path") .attr("d", arc_generator) .style("fill", function (d, i) { return color(i); }) .on("mouseover", function (d, i) { //console.log(d); console.log(i); iframeDom.contentWindow.postMessage(i, '*'); }) .on("mouseout", function (d, i) { console.log(-1); iframeDom.contentWindow.postMessage(-1, '*'); }); //text g.selectAll("text") .data(angle_data(data)) .enter() .append("text") .text(function (d) { return d.data[0]; }) .attr("transform", function (d) { return "translate(" + arc_generator.centroid(d) + ")"; }) .attr("text-anchor", "middle"); </script> </body> </html>
ThingJS平臺完整代碼:
var app = new THING.App({ // 場景地址 "url": "https://www.thingjs.com/./client/ThingJS/11606/20190126172532891305936", //背景設置 "skyBox": "BlueSky" }); // 接收iframe頁面傳送的數據 window.addEventListener('message', function (e) { var data = e.data; if (data == -1) { var selector = app.query('*'); selector.style.outlineColor = null; } else { var selector = app.query('#1' + data); selector.style.outlineColor = '#ff0000'; } })
最後效果如圖: