四时宝库

程序员的知识宝库

webgl3D可视化之使用图表数据交互

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

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

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

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

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

如何修改图表样式?

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

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

Bash
   // 车位占用情况

  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]

  }

  ]

  };

在这里我将完整的代码贴出,大家可以复制该代码进入到ThingJS的在线开发平台中运行查看

Bash
  /**

  * 说明: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} {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} {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, "车位占用情况");

  }

  })

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接