D3.js学习之SVG基础知识

马(云)老师说现在是DT时代,数据就是当代社会的“石油”。有了数据后,如何利用数据,挖掘出数据的价值才会让数据的价值真正体现出来。数据可视化在近年来也越来受到重视,而d3 .js作为当下最流行的可视化工具,值得大家花时间云学习和掌握。d3.js基于svg来绘制各种各样的报表,所以学习d3.js的第一步就是了解svg。本文整理记录我入门d3.js时了解的一些svg基础知识。

1. SVG 是什么

SVG 全称是可缩放矢量图(Scalable Vector Graphics)。这里有两个重点:可缩放、矢量图。

可缩放表明 SVG 放大缩小不会失真。

与矢量图对应的则是位图。平时我们用手机,相机拍摄的照片都是位图,在手机,电脑上看到的图片也是位图。总之,复杂的图像用位图,矢量图适合表现一些简单的图像。

1.1 SVG 的坐标系统与尺寸单位

SVG,HTML,canvas 的坐标系统都是相同的:左上角为原点(0,0),向右为 x 轴正方向,向下为 y 轴正方向

svg坐标系统

用户单位和屏幕单位的映射关系被称为用户坐标系统。用户单位即 SVG 渲染图形时使用的单位,屏幕单位我们可以理解了像素(px),一般情况下,SVG中1个用户单位等同于1个屏幕单位:

<svg width="100" height="100">

上面的元素定义了一个100*100px的SVG画布,这里1用户单位等同于1屏幕单位。

但这种映射关系可以通过viewBox属性改变

<svg width="200" height="200" viewBox="0 0 100 100">

这里定义的画布尺寸是200200px。但是,viewBox属性定义了画布上可以显示的区域:从(0,0) 点开始,100宽100高的区域。这个100 x 100的区域,会放到200 x 200的画布上显示。于是就形成了放大两倍的效果。关于 viewBox 更详情的解释可以参看理解SVG viewport,viewBox, preserveAspectRatio缩放

1.2 如何在 HTML 中使用 SVG

可以通过以下方式在 HTML 中使用 SVG:

<!--在 img 标签中使用 svg -->
<img src="demo.svg" style="display: inline-block; width: 500px; height: 500px;">

<!--把 svg 作为背景图片使用 -->
<div style="display: inline-block; width: 500px; height: 500px; background-image: url(demo.svg)"></div>

<!--在 object 标签中使用 svg -->
<object type="image/svg+xml" data="demo.svg" class="example"></object>

<!--直接使用 svg 标签 -->
<svg class="svg" width="500" height="500"></svg>

<!--在iframe中使用svg-->
<iframe src="./world-population.svg" frameborder="0" width="500" height="500"></iframe>

另外,SVG 也可以转换成 base64 内联进 Data URI中。

1.3 SVG 中的颜色

假如要定义红色,可以使用下面的任一方式:

  • 'red'
  • '#f00'
  • '#ff0000'
  • rgb(155,0,0)
  • rgb(100%,0%,0%)

1.3 SVG 的优缺点

  • 优点:主流浏览器都支持;实现了 DOM 接口,可以通过 JS,CSS 操作 SVG。
  • 缺点:图像表现能力有限,不适合表现复杂图像。

2. SVG 标签元素

以下是 SVG 常用标签元素,这些元素都可以直接打印到 canvas 中。

  • text:文本
  • line:线段
  • rect:矩形
  • circle:圆形
  • ellipse:椭圆
  • polyline:折线
  • polygon:多边形
  • path:路径
  • image:插入图片
  • use:复制一个形状

另外,还可以使用 g 标签对元素进行分组。下图是这些 svg 标签和相应的属性解释:

svg常用标签

3. 使用 D3.js 操作svg标签元素

使用 d3.js 基于 SVG 标签去绘制图像,总结起来就就2步:

  1. 在 svg 画布中插入相应的 svg 标签
  2. 设置相应的属性
// 矩形
d3.select('.rect')
    .append('rect')  
    .attr('x', 10)
    .attr('y', 10)
    .attr('width', 100)
    .attr('height', 50)
    .attr('fill', 'none')
    .attr('stroke', 'red')
    .attr('stroke-width', 1);

// 椭圆
d3.select('.ellipse')
    .append('ellipse')
    .attr('cx', 80)
    .attr('cy', 80)
    .attr('rx', 40)
    .attr('ry', 60)
    .attr('fill', 'none')
    .attr('stroke', 'red')
    .attr('stroke-width', 1);

// 折线
d3.select('.polyline')
    .append('polyline')
    .attr('points', '60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145')
    .attr('fill', 'none')
    .attr('stroke', 'red')
    .attr('stroke-width', 1);

这些代码涉及到了d3的选择器,svg操作基础,当然这并不能体现 D3.js 的强大可视化展示能力,但基本思路是这样。后续我会陆续发布一些 d3.js 相关的学习笔记,希望对大家有些许帮助;如果你有好的 d3.js 学习资源或方法,也欢迎在评论中与我交流。以上!

4. 参考

留言列表
  • lkt:
    请问题下,部署服务器时需要把那些文件上传到服务器部署,是只有打包后的dist文件夹,还是说要把整个my-project的根目录一起上传到服务器
      2019年05月27日 14:29 回复
    • lm:
      数据的预取总是失败,求大佬指教下,实现了个ssr,但是总觉得我实现的ssr不对
        2019年03月15日 16:46 回复
      • ewr:
        eqr
          2018年09月21日 09:17 回复
        • 小王:
          你好,请问一下,官网demo 跑起来了,但是用浏览器http://localhost:8080.一直加载不出来是怎么回事呢?
            2018年09月20日 14:50 回复
          • dk:
            请教博主一点问题,目前我的ssr项目已基本完成开发,但不知如何部署到虚拟服务器centos7中,具体的问题是不懂需要将哪些代码上传到服务器并使用pm2来启动项目.希望博主有空回答下,谢谢.
            • u3xyz:
              你好,其实这个问题与“hp5”的问题有点类似,你可以看下那个回复,理论上构建生成的所有前端资源文件都会用到,都需要放到服务器
              2018年09月11日 21:47
            2018年09月11日 20:18 回复
          • hp5:
            你好,vue-ssr开发基本没什么问题,但是不知道如何部署,希望请教一下,上线部署时,需要将那些文件给后端,希望博主有时间回复一下,谢谢。
            • u3xyz:
              你好,所谓VueSSR,本质是在前后端共用一套js代码,在Node环境下直接吐出页面的过程。SSR一定是在Node环境 ,这个与Java,php等传统后端没什么关系(后端只提供数据接口),也就谈不上要给他们什么文件了,独立部署即可。
              2018年07月25日 10:36
            2018年07月24日 13:10 回复
          • lgf:
            我的项目是vue-cli 然后 实现ssr seo渲染
              2018年07月03日 19:07 回复
            • lgf:
              你好,我现在也是有SEO需求,SSR做,在浏览器打开的时候显示网页源代码可以看到详细的html,增加百度搜索更多的关键子,现在我ssr还是不太能行,用了个prerender-spa-plugin,但是这个插件问题太多,你这篇文章我看了一遍我实现有点困难,(比较菜) 有没有再详细点的教程呢 需求比较着急,所以问问您还有再详细点的demo吗
              • u3xyz:
                推荐多参考官方Demo: https://github.com/vuejs/vue-hackernews-2.0/
                2018年07月25日 10:28
              2018年07月03日 19:05 回复
            • 小白白:
              刚开始研究 我有一个问题 开发过程中我修改代码 就要重新打一次包么?怎么实现热更新啊 希望指点一下
                2018年06月29日 11:40 回复
              • 木メメ木+大:
                你好,发现你的博客的一个现象:比如在第二页点击进入详情,然后按下浏览器返回,就回到第一页,这个是博主刻意为之的吗? 另外特别想请教一下,左右目录联动的实现~
                • u3xyz:
                  第一个问题:你是说在第二页的文章返回时默认到了第一页吗?这个不是刻意为之,算小bug吧 第二个问题:可以参看我的文章《如何实现markdown文章标题导航》
                  2018年06月28日 12:33
                2018年06月27日 11:46 回复
              • 昌子:
                最近在做ssr,前面过程很顺利,到后面npm run build时,会爆出一个elementUI的样式错误,搞了好几天了还是无头绪,有时间帮忙看下吗?项目急上线
                • u3xyz:
                  这个得你自己想办法解决哈
                  2018年06月28日 12:31
                2018年06月26日 22:56 回复
              • meme:
                不太懂服务端,骨架屏倒是实现了,ssr看了好多,明白大致流程,就是对服务端不太了解,首先阿里买个云主机,然后你用sheel 连接ssh 登录 起一个www服务器,那么数据库放哪里呢,怎么就线上也能用了?还有node 服务放哪里,还有比如我是node写的接口,怎么弄呢。最近又看了 nginx 是说可以静态资源转发,不太明白其中的流程。期望大佬,写篇文章。或者私信一下。谢谢了
                • u3xyz:
                  可以看看文章中的服务器部署模块。我只用了一台阿里云主机,node服务,nginx,数据库都是在这台机器上
                  2018年06月28日 12:30
                2018年06月26日 21:10 回复
              • PlainHeart:
                作者,您好,我最近刚开始研究这个,按照您的文档我并不能实现功能,希望在配置上能给予一些更详细的帮助,谢谢!
                • u3xyz:
                  首先,得耐心一点,我也不是一下就很顺利得做出来了,那里有问题就想办法解决。此文章也只是列出了关键步骤,并不是所有的步骤。建议多研究官方示例vue-hackernews-2.0,或者试试Nuxt.js
                  2018年06月28日 12:28
                2018年06月23日 17:55 回复
              • ljc:
                你好,本人刚接触vue-ssr,开发的时候基本没什么问题,但是不知道如何上线部署,想请教一下,上线部署的时候 ,需要把哪些文件给后端呢,希望博主有时间回复一下
                • u3xyz:
                  你好,回复已经单独发qq邮箱(7048***)
                  2018年04月21日 00:56
                2018年04月20日 15:33 回复

              发表评论: