分享
查看: 3172|回复: 0

[分享] 新手搭建3D可视化场景之使用图表进行数据交互

[复制链接]

新手搭建3D可视化场景之使用图表进行数据交互

发表于 2019-11-8 11:35:20 来自 分享 阅读模式 倒序浏览
zzv_icon3172 zzr_icon0 查看全部

       时光荏苒、转瞬即逝,国家富强使得人们迈入幸福的新生活,随着时代的发展,人们对于事物的处理方式也发生了改变,从书信交流到如今视频通话,人们日常生活中的交流方式也发生了改变,尤其是人们对于图像的接受能力远远大于文字,很多时候,几十上百字的归纳说明还没有一张图给人带来的直观,这种将文字变成表格,表格变成图表的过程却并不算漫长,随着互联网的蓬勃生长、对于千万条乃至数百亿条数据的处理之后,如何让管理者更加直观便捷的查看出大数据下隐藏的信息,这就不仅仅是文字能够表述的清楚,或者这样说,在如今这个时代,任何可以被节约下来的时间都不能去浪费,以至于表格逐渐代替了文字账本,在互联网中使用图表来展示数据也逐渐成为了主流趋势,当我们把目光放向物联网时,其实也是这样,随着互联网的壮大,物联网也在迅速崛起,而物联网可视化的万物可视也成为了当前的一大需求,将三维实景与数据结合起来也成为了可视化的一大亮点。

       物联网可视化是什么?可视化号称是物联网的最后一公里,那么,为什么会有这样的言论?物联网可视化通过3D实景模型,结合了各种传感技术、以互联网来传递数据,并且将数据传入到可视化应用中,变化成可直观查看的图表,如温度云图、信息报警、安防监控等等,将一系列的零散功能结合在一起,形成一个完整的可视化应用。这样不仅仅能够使用可视化应用来实现实时控制的功能,还能够让任何人员都能够看懂,并且还是非常直观、非常清晰的看懂,物联网可视化应用,不仅能完成使用者需要的功能,更是在此基础之上,强化了其“可视化”的能力,让使用者一览无“疑”。

       在物联网可视化领域,如何将图表数据与三维场景进行交互呢?

       使用ThingJS在线开发即可快速使用Echarts图表结合三维场景!进入到ThingJS网站的在线开发中去(https://www.thingjs.com/guide/?m=sample),使用QQ或者微信快速登录,找到官方示例中的界面(2D),点击“Echarts + 交互”,出现对应代码后点击运行(三角形图标),可以查看到图表和三维场景进行交互了,但是这四个图表都不是我想要的,我该如何去修改呢?

       别急,,慢慢看下来,你会发现,改图表非常的简单!

新手搭建3D可视化场景之使用图表进行数据交互

新手搭建3D可视化场景之使用图表进行数据交互

新手搭建3D可视化场景之使用图表进行数据交互


    如何修改图表样式?

       如何使用Echarts的图表替换掉我们的图表?其实非常的简单,进入到Echarts官网,点击实例,选择其中的例子,将该例子中的代码复制出来,修改其中的数据,后期结合可以通过Ajax获取参数来动态的修改我们图表中的数据。(这一章节我们主要讲解如何修改图表,将图表与三维场景相结合)将数据放入到ThingJS的代码中去,具体位置是找到ThingJS要被替换的图表,将“XXXOption"或者是“Option”中的数据全部替换掉。完成后可以点击保存并且运行,查看是否修改成功。注意:最好是将“XXXOption"的名字保留,仅改变“XXXOption"后面的数据,或者将“XXXOption"改成你想要的变量名,那么在调用“XXXOption"的位置,也需要全部替换掉。

新手搭建3D可视化场景之使用图表进行数据交互

新手搭建3D可视化场景之使用图表进行数据交互


新加入的Echarts实例的代码如下:

// 车位占用情况
function occupyPark() {
var colors = ['#5793f3', '#d14a61', '#675bba'];
var occupyOption = {
color: colors,

tooltip: {
trigger: 'none',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['十月车位使用数', '十一月车位使用数']
},
grid: {
top: 70,
bottom: 50
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLine: {
onZero: false,
lineStyle: {
color: colors[1]
}
},
axisPointer: {
label: {
formatter: function (params) {
return '使用数  ' + params.value
+ (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}
}
},
data: ["6:00", "7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00"]
},
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLine: {
onZero: false,
lineStyle: {
color: colors[0]
}
},
axisPointer: {
label: {
formatter: function (params) {
return '使用数  ' + params.value
+ (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}
}
},
data: ["6:00", "7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00"]
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '十月车位使用数',
type: 'line',
xAxisIndex: 1,
smooth: true,
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
},
{
name: '十一月车位使用数',
type: 'line',
smooth: true,
data: [3.9, 5.9, 11.1, 18.7, 48.3, 69.2, 231.6, 46.6, 55.4, 18.4, 10.3, 0.7]
}
]
};


在这里我将完整的代码贴出:

/**
* 说明:ECharts 整合例子
* 操作:点击图表,触发场景信息变化
* 交互图表:当前车位状态、车牌信息、车辆类型
* 难度:★★★☆☆
*/
// 动态引入ECharts.js
THING.Utils.dynamicLoad(['lib/echarts.min.js'], function () {
/*
   *var app = new THING.App()一直作为ThingJS的启动来使用的,其中有url等信息需要填写
   *url则是制作好的场景上传到ThingJS网站后的链接
   */

var app = new THING.App({
url: 'https://www.thingjs.com/./client/ThingJS/10321/20190715145918010908508',     // 场景地址
"skyBox": "Night"
});

/**
    * app.on("load",function) 作为全局绑定事件,绑的的方法就是'load' 方法
    */
app.on('load', function (ev) {
showParkingInfo();// 车位信息
showTypeInfo();// 车辆类型信息
showLicenseInfo();// 车牌信息
occupyPark();// 车位占用
})

var timer = null;
// 创建图表
function createChart(option, type) {
var bottomBackground = document.createElement('div');// 创建背景 div
var bottomDom = document.createElement('div');// 图表 div

// 设置背景div和图表div的样式
if (type == "车位状态") {
var backgroundStyle = 'position: absolute;top:3px;right:3px;height:300px;width:380px;background: rgba(22,24,63,0.3); border-radius:3px';
var chartsStyle = 'position: absolute;top:10px;right:0px;width:360px;height:250px;margin:0 10px;';
}
else if (type == "车牌信息") {
var backgroundStyle = 'position: absolute;top:306px;right:3px;height:300px;width:380px;background: rgba(22,24,63,0.3); border-radius:3px';
var chartsStyle = 'position: absolute;top:10px;right:0px;width:360px;height:300px;margin:0 10px;';
}
else if (type == "车位占用情况") {
var backgroundStyle = 'position: absolute;top:3px;left:3px;height:300px;width:380px;background: rgba(22,24,63,0.3); border-radius:3px';
var chartsStyle = 'position: absolute;top:10px;right:0px;width:360px;height:300px;margin:0 10px;';
}
else if (type == "车辆类型") {
var backgroundStyle = 'position: absolute;top:306px;left:3px;height:300px;width:380px;background: rgba(22,24,63,0.3); border-radius:3px';
var chartsStyle = 'position: absolute;top:10px;right:0px;width:360px;height:300px;margin:0 10px;';
}


bottomBackground.setAttribute('style', backgroundStyle);
bottomDom.setAttribute('style', chartsStyle);
// echarts 初始化
var bottomCharts = window.echarts.init(bottomDom);
bottomCharts.setOption(option);

// 给图表添加'click'事件 当点击图图表时触发,params是点击位置信息参数
bottomCharts.on('click', function (params) {
clearTimeout(timer);
// 清除上次点击事件产生的场景变化
cancelOutline();
reset();
clearUIAnchorArr();

// 根据鼠标点击时的参数,控制场景中物体变化
if (params.name == "空置车位") {
app.query("空置车位").style.outlineColor = "#4a8cff"
}
else if (params.name == "占用车位") {
app.query("占用车位").style.outlineColor = "#ff6c00"
}
else if (params.name.indexOf("车") != -1) {
var reg = new RegExp(params.name);
var cars = app.query(reg);
flash(cars);
}
else if (params.name == "京") {
var cars = app.query('[area=京]');
for (var i = 0; i < cars.length; i++) {
createUIAnchor(cars[i]);
}
}
else if (params.name == "津") {
var cars = app.query('[area=津]');
for (var i = 0; i < cars.length; i++) {
createUIAnchor(cars[i]);
}
}
else if (params.name == "冀") {
var cars = app.query('[area=冀]');
for (var i = 0; i < cars.length; i++) {
createUIAnchor(cars[i]);
}
}
else if (params.name == "辽") {
var cars = app.query('[area=辽]');
for (var i = 0; i < cars.length; i++) {
createUIAnchor(cars[i]);
}
}
// 场景中信息显示5s后消失
timer = setTimeout(function () {
cancelOutline();
reset();
clearUIAnchorArr();
}, 5000)
});

bottomBackground.appendChild(bottomDom);
app.domElement.appendChild(bottomBackground);// 添加到app dom下
}
// 取消所有物体钩边
function cancelOutline() {
app.query(".Thing").style.outlineColor = null;
}
// 设置闪烁
function flash(cars) {
cars.on('update', function (ev) {
ev.object.style.opacity = 0.5 + 0.5 * Math.sin(2 * app.elapsedTime / 200);
}, '每帧改变透明度');
}

// 恢复设置
function reset() {
var cars = app.query(/车/);
cars.style.opacity = 1.0;
cars.style.color = null;
cars.off('update', null, '每帧改变透明度');
}

// 存储所有UIAnchor
var uiAnchorArr = [];
// 创建UIAnchor
function createUIAnchor(obj) {
// 创建widget (绑定数据用)
var panel = new THING.widget.Panel({
width: '100px',
cornerType: 'polyline'
})

panel.addString(obj.userData, 'id').caption('');
var uiAnchor = app.create({
type: 'UIAnchor',
parent: obj,
element: panel.domElement,
localPosition: [0, 0, 0],
pivot: [-0.1, 1.5]
});
uiAnchorArr.push(uiAnchor);
return uiAnchor;
}
// 删除所有顶牌
function clearUIAnchorArr() {
for (var i = 0; i < uiAnchorArr.length; i++) {
uiAnchorArr[i].destroy();
}
uiAnchorArr = [];
}

// 当前停车位状态
function showParkingInfo() {
var parkingTotalNum = 16;
var emptyNum = 3;
//parkOption数据可以使用Echarts中的示例数据进行替换,只需更改其中的数据信息即可
var parkOption = {
title: { text: '当前车位状态', x: 'center', textStyle: { color: '#cccccc' } },
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient: 'vertical',
top: 60,
x: 'left',
data: ['占用车位', '空置车位'],
textStyle: {
color: '#cccccc'
}
},
calculable: true,
series: [
{
name: '车位', type: 'pie', radius: '55%', center: ['50%', '60%'],
data: [
{ value: parkingTotalNum - emptyNum, name: '占用车位', itemStyle: { color: "#ff6c00" } },
{ value: emptyNum, name: '空置车位', itemStyle: { color: "#4a8cff" } }
]
}
]
};
createChart(parkOption, "车位状态");
}
// 车辆类型
function showTypeInfo() {
var dataAxis = ["跑车", "轿车", "皮卡车", "面包车", "出租车"];
var data = [3, 6, 1, 1, 2];
var yMax = 7;
var dataShadow = [];

for (var i = 0; i < data.length; i++) {
dataShadow.push(yMax);
}

var typeOption = {
title: { text: '车辆类型', x: 'center', textStyle: { color: '#cccccc' } },
xAxis: {
data: dataAxis,
axisLabel: {
inside: true,
textStyle: {
color: '#fff'
}
},
axisTick: {
show: false
},
axisLine: {
show: false
},
z: 10
},
yAxis: {
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
textStyle: {
color: '#ccc'
}
}
},
dataZoom: [
{
type: 'inside'
}
],
series: [
{ // For shadow
type: 'bar',
itemStyle: {
normal: { color: 'rgba(0,0,0,0.05)' }
},
barGap: '-100%',
barCategoryGap: '40%',
data: dataShadow,
animation: false
},
{
type: 'bar',
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
]
)
},
emphasis: {
color: new echarts.graphic.LinearGradient(
0, 0, 0, 1,
[
{ offset: 0, color: '#2378f7' },
{ offset: 0.7, color: '#2378f7' },
{ offset: 1, color: '#83bff6' }
]
)
}
},
data: data
}
]
};
createChart(typeOption, "车辆类型");
}
// 显示车牌信息
function showLicenseInfo() {
var len_jing = app.query('[area=京]').length;
var len_jin = app.query('[area=津]').length;
var len_ji = app.query('[area=冀]').length;
var len_liao = app.query('[area=辽]').length;
var licenseOption = {
title: { text: '车牌信息', x: 'center', textStyle: { color: '#cccccc' } },
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
legend: {
orient: 'vertical',
x: 'left',
data: ['京', '津', '冀', '辽'],
textStyle: {
color: '#cccccc'
}
},
series: [
{
name: '牌照',
type: 'pie',
radius: ['50%', '70%'],
avoidLabelOverlap: false,
label: {
normal: {
show: false,
position: 'center'
},
emphasis: {
show: true,
textStyle: {
fontSize: '30',
fontWeight: 'bold'
}
}
},
labelLine: {
normal: {
show: false
}
},
data: [
{ value: len_jing, name: '京' },
{ value: len_jin, name: '津' },
{ value: len_ji, name: '冀' },
{ value: len_liao, name: '辽' },
]
}
]
};
createChart(licenseOption, "车牌信息");
}
// 车位占用情况
function occupyPark() {
var colors = ['#5793f3', '#d14a61', '#675bba'];
var occupyOption = {
color: colors,

tooltip: {
trigger: 'none',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['十月车位使用数', '十一月车位使用数']
},
grid: {
top: 70,
bottom: 50
},
xAxis: [
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLine: {
onZero: false,
lineStyle: {
color: colors[1]
}
},
axisPointer: {
label: {
formatter: function (params) {
return '使用数  ' + params.value
+ (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}
}
},
data: ["6:00", "7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00"]
},
{
type: 'category',
axisTick: {
alignWithLabel: true
},
axisLine: {
onZero: false,
lineStyle: {
color: colors[0]
}
},
axisPointer: {
label: {
formatter: function (params) {
return '使用数  ' + params.value
+ (params.seriesData.length ? ':' + params.seriesData[0].data : '');
}
}
},
data: ["6:00", "7:00", "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", "16:00", "17:00"]
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '十月车位使用数',
type: 'line',
xAxisIndex: 1,
smooth: true,
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
},
{
name: '十一月车位使用数',
type: 'line',
smooth: true,
data: [3.9, 5.9, 11.1, 18.7, 48.3, 69.2, 231.6, 46.6, 55.4, 18.4, 10.3, 0.7]
}
]
};

createChart(occupyOption, "车位占用情况");
}
})


avatar
游客~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

130700ppkpl8x3t7tt1b1t