资讯专栏INFORMATION COLUMN

数据可视化实践

PrototypeZ / 914人阅读

摘要:但如果数据可视化做的较弱,反而会带来负面效果错误的表达往往会损害数据的传播,完全曲解和误导用户,所以更需要我们多维的展现数据,就不仅仅是单一层面,目前有多种第三方库来实现数据的可视化等。数据可视化的具体实现这里基于两种实现方式,一种一种。

数据可视化的目的其实就是直观地展现数据,例如让花费数小时甚至更久才能归纳的数据量,转化成一眼就能读懂的指标;通过加减乘除、各类公式权衡计算得到的两组数据差异,在图中颜色敏感、长短大小即能形成对比;数据可视化是一个沟通复杂信息的强大武器。通过可视化信息,我们的大脑能够更好地抓取和保存有效信息,增加信息的印象。但如果数据可视化做的较弱,反而会带来负面效果;错误的表达往往会损害数据的传播,完全曲解和误导用户,所以更需要我们多维的展现数据,就不仅仅是单一层面,
目前有多种第三方库来实现数据的可视化:Highcharts, Echarts, Chart.js, D3.js等。
总的来说,现在的第三方库都是基于这两种浏览器图形渲染技术实现的:Canvas和SVG。canvas和webGL都是基于openGL来进行封装。但是webGL由于更贴近openGL所以学习曲线较陡,这里就讲解Canvas和SVG两种。
下面是两种图形渲染技术的对比

SVG Canvas
不依赖分辨率 依赖分辨率
支持事件处理器 不支持事件处理器
最适合带有大型渲染区域的应用程序 弱的文本渲染能力
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快) 能够以 .png 或 .jpg 格式保存结果图像
不适合游戏应用 最适合图图像密集型的游戏
可以为某个元素附加 JavaScript 事件处理器。在 SVG 中,每个被绘制的图形均被视为对象。 一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景都需要重新绘制。
Echarts

是百度的一个开源的数据可视化工具,一个纯 Javascript 的图表库,能够在 PC 端和移动设备上流畅运行,兼容当前绝大部分浏览器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底层依赖轻量级的 Canvas 库 ZRender,ECharts 提供直观,生动,可交互,可高度个性化定制的数据可视化图表。下面是简单的使用方法:

option = {
    xAxis: {
        type: "category",
        data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    },
    yAxis: {
        type: "value"
    },
    series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: "line"
    }]
};

如何支持多种渲染方式

echarts支持svg、canvas、vml等底层技术
echarts会根据具体的渲染平台去做不同的渲染实现,底层是一个叫路径代理PathProxy的类,它会负责这个底层的绘制指令。根据不同的渲染器,底层进行不同的实现。

const rect = new zrender.Rect({
  shape: {
    x: 10,
    y: 10,
    width: 80,
    height: 80
  }
});
如何支持事件处理

在canvas不能够为某个元素绑定事件,所以采用给整个图表容器绑定事件。当进行事件处理的时候,先判断鼠标是否在图形以内。因为图形经过旋转和缩放,所以需要将鼠标坐标切换到图形坐标系。获取到图形坐标系以后,就可以知道鼠标和图形之间的关系,就可以进行相应的事件处理。

SVG渲染如何部分更新

在渲染的时候canvas一旦改变就完全重绘,但是效率很高。对于SVG而言,假如说散点图有一千个,那么DOM就有一千个节点。如果每一帧都需要把DOM元素进行删除然后添加,效率是非常低的。所以这里可是使用virtual-Dom的方法,通过维护一个渲染对象列表,每帧将新的渲染对象列表与上一帧的进行diff,获得新增、修改、删除的渲染对象列表,在根据列表对DOM相关节点进行调整。

数据可视化的具体实现

这里基于两种实现方式,一种canvas一种svg。

Canvas

在这里实现了一个简单的库,可以绘制柱状图、饼状图、折线图、雷达图。
下面是使用方法:

const canvas = document.getElementById("canvas");
const data = [{
    name: "篮球",
    value: 2260,
},
{
    name: "羽毛球",
    value: 1170,
},
{
    name: "乒乓球",
    value: 1230,
},
{
    name: "足球",
    value: 1450,
},
];
const settings = {
    type: "bar"
};
new Chart(canvas, data, {
    title: "Sport"
}, settings);

下面是效果图

构造函数可以传入的参数有四个,canvas画布对象,data是我们传入的数据对象,settings是传入的配置,就可以定义图形的类型,可以是柱状图,或者折线图。在这里根据传入的type进行相应的绘图更改。内部的实现原理如下:

if (settings) {
  Object.keys(settings).map((key) => {
    this[key] = settings[key];
  });
}

上面这个部分就能够让传入的参数覆盖已有的默认设置,颜色,坐标。有些设置需要通过计算才能获得,例如每个单位长度的标记,获取每个值的比例。例如:

this.totalValue = this.getTotalValue();
this.maxValue = this.getMaxValue();
function getTotalValue() {
  let total = 0;
  this.data.map((item) => {
    total += item.value;
  });
  return total;
}

这里先计算出总数,然后绘制饼状图的时候就计算出每一条数据所占的比例,进行绘图。
下面这部分会根据传入的type来绘制不同的图形,下面是具体实现:

if (this.type === "bar" || this.type === "line") {
  this.drawBarUpdate();
} else if (this.type === "pie" || this.type === "ring") {
  this.drawPieUpdate();
} else if (this.type === "radar") {
  this.drawRadarUpdate();
}

draBarUpdate的具体实现:

  drawBarUpdate() {
    this.drawAxis();
    this.drawPoint();
    this.drawTitle();
    this.drawBarChart();
  }

前三个函数用于基本的结构,轴、点、标题。第四个函数用来绘制图形。主要借助的是canvas的几种方法fillStyle:设置填充绘画的颜色、渐变或模式;strokeStyle: 设置笔触的颜色、渐变或模型;beginPath:开始一条路径,或者重置当前的路径;arc: 用来创建弧/曲线arc(x, y, r, startAngle, endAngle, direction)x,y分别代表圆中心的x,y坐标。startAngle为起始角,endAngle为结束角,direction代表顺时针,还是逆时针绘图。首先根据数据的长度,确定每条数据的长度和坐标然后使用下面操作进行绘图。

this.ctx.beginPath();
this.ctx.arc(x, y, radius, startAngle, endAngle, direction);
this.ctx.fill();

这样就可以绘制图形了

SVG

SVG是一种使用XML描述2D图形的语言。SVG基于XML,这意味着SVG DOM的每个元素都是可用的。你可以为每个元素附加javaScript事件处理器。
svg不同于canvas,提供了很多基本形状。例如rect: 圆;circle: 椭圆;ellipse:直线;line: 折线;polyline:多边形;polygon:路径。
这里借助common模块下的pie.js进行了解。
下面是使用方法:

var myPie = new Pie({
  pieR: 40, // 外径
  donutR: 35, // 内径
  rotation: -90, // 旋转到从y轴正方向起始
  strokeColor: "#FFF", // 使用白色描边
  animation: true, // 启用默认展现动画
  slices: [{
    color: "#E3E3E3", // 第一切片颜色
    percent: 0.1 // 第一切片面积占比
  }, {
    color: "#5FC2F5", // 第二切片颜色
    percent: 0.2 // 第二切片面积占比
  }, {
    percent: 0.3 // 第三切片面积占比
  }, {
    percent: 0.4 // 第四切片面积占比
  }]
});

$("body").append(myPie.getNode()); // 插入饼图。

下面是效果图


首先也是进行重置默认的参数设置,还有计算一些属性,例

this.args = $.extend({
  pieR: 100,
  slices: [{
    percent: 1,
  }],
}, args);
$.each(this.args.slices, function(i, item) {
  item.angle = (item.percent || 0) * 360;
})

然后设置每个元素应该设置的路径,是通过下面函数进行实现:

 /**
  *  @param {Number} startAngle 开始的角度
  *  @param {Number} angle 旋转角度
  *  @param {Number} pieR 半径
  *  @param {Number} donutR 环形图所需要的参数
  *  @return {Object} 坐标对象
  */
getSectorPath(startAngle, angle, pieR, donutR) {
  startAngle = startAngle * Math.PI / 180;
  angle = angle * Math.PI / 180;

  var startAngleTri = {
    cos: Math.cos(startAngle),
    sin: Math.sin(startAngle)
  };

  var angleTri = {
    cos: Math.cos(startAngle + angle),
    sin: Math.sin(startAngle + angle)
  };

  return [
    "M", donutR * startAngleTri.cos, donutR * startAngleTri.sin, // 开始点
    "L", pieR * startAngleTri.cos, pieR * startAngleTri.sin, // 开始的边界
    "A", pieR, pieR, // 外部的半径
    0, // x轴上的旋转
    Math.abs(angle) > Math.PI ? 1 : 0, // large-arc-flag
    1, // sweep-flag
    pieR * angleTri.cos, pieR * angleTri.sin, // end point
    "L", donutR * angleTri.cos, donutR * angleTri.sin, // end edge
    "A", donutR, donutR, // inner arc
    0, // x轴上的旋转
    Math.abs(angle) > Math.PI ? 1 : 0, // large-arc-flag
    0, // sweep-flag
    donutR * startAngleTri.cos, donutR * startAngleTri.sin // 结束点
  ].join(" ");
}

绘制图形是靠的path这个元素,下面的命令可以用于路径数据:

M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Belzier curve
T = smooth quadratic Belzier curveto
A = elliptical Arc
Z = closepath

简便写就可以如下:

那么绘制饼状图的就可以如下这么写:

$(path).attr({
  "d": getSectorPath(startAngle, angle, pieR, donutR)
}).css({
  // 属性
})

这就是svg的绘画方式,相对canvas绘画,svg因为提供了一些基本的图形组件所以更好画,但是各有优点

如果需要制作更好的图形库,我们就需要借助绘图引擎,就能够针对多种平台使用不同的渲染方式。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99368.html

相关文章

  • 容器监控实践—Prometheus数据视化

    摘要:二可视化是一个开源的图表可视化系统,简单说图表配置比较方便生成的图表比较漂亮。 一. 概述 Prometheus自带了一个web服务,包括一个默认的dashboard,可以使用表达式查询并进行图表可视化,默认服务的地址为:http://prometheus_ip:9090 如下图: showImg(https://segmentfault.com/img/remote/14600000...

    URLOS 评论0 收藏0
  • 容器监控实践—Prometheus数据视化

    摘要:二可视化是一个开源的图表可视化系统,简单说图表配置比较方便生成的图表比较漂亮。 一. 概述 Prometheus自带了一个web服务,包括一个默认的dashboard,可以使用表达式查询并进行图表可视化,默认服务的地址为:http://prometheus_ip:9090 如下图: showImg(https://segmentfault.com/img/remote/14600000...

    赵连江 评论0 收藏0
  • 容器监控实践—Prometheus数据视化

    摘要:二可视化是一个开源的图表可视化系统,简单说图表配置比较方便生成的图表比较漂亮。 一. 概述 Prometheus自带了一个web服务,包括一个默认的dashboard,可以使用表达式查询并进行图表可视化,默认服务的地址为:http://prometheus_ip:9090 如下图: showImg(https://segmentfault.com/img/remote/14600000...

    dayday_up 评论0 收藏0
  • 利用TICK搭建Docker容器视化监控中心

    摘要:在我的前文容器可视化监控中心搭建之中我们就实践过容器的可视化监控,在那篇文章中我们是使用了技术栈来完成的。 showImg(https://segmentfault.com/img/remote/1460000015484084); 概述 性能监控是容器服务必不可少的基础设施,容器化应用运行于宿主机上,我们需要知道该容器的运行情况,包括 CPU使用率、内存占用、网络状况以及磁盘空间等...

    LiuZh 评论0 收藏0
  • 用最科学的方法展示最形象的图表——前段数据视化选型实践

    摘要:提供的图表的确可以满足大部分的需求,遵循了数据可视化的一些经典范式。数据可视化已然成为了新的风向标。数据团队的前端要做的就是用最科学的方法向用户展示最形象的图表,而这,也是我们前行的目标。 前言 也许很多人都会觉得奇怪,在这样一个更多以后台数据分析为主的公司,为什么需要一个专注于前端的团队?今天这篇文章就来讲述那些年我们错过的前端数据可视化,以此来解答这个问题。 需求 那么,在我们的项...

    Eminjannn 评论0 收藏0

发表评论

0条评论

PrototypeZ

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<