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';
}
})
最终效果图:
