目标

  在这一章,我们将学习如何使SVG坐标空间是动态的,这样我们的数据可视化不论数据是什么,都始终是可见的。

  我们会使得SVG坐标空间尺度上调或下调来适于我们的数据。

三个SVG长方形

  我们就从三个长方形作为开始:

 1   var jsonRectangles = [
2 { "x_axis": 10, "y_axis": 10, "height": 20, "width":20, "color" : "green" },
3 { "x_axis": 40, "y_axis": 40, "height": 20, "width":20, "color" : "purple" },
4 { "x_axis": 70, "y_axis": 70, "height": 20, "width":20, "color" : "red" }];
5
6 var svgContainer = d3.select("body").append("svg")
7 .attr("width", 100)
8 .attr("height", 100);
9
10 var rectangles = svgContainer.selectAll("rect")
11 .data(jsonRectangles)
12 .enter()
13 .append("rect");
14
15 var rectangleAttributes = rectangles
16 .attr("x", function (d) { return d.x_axis; })
17 .attr("y", function (d) { return d.y_axis; })
18 .attr("height", function (d) { return d.height; })
19 .attr("width", function (d) { return d.width; })
20 .style("fill", function(d) { return d.color; });

  得到的结果是:

  漂亮!

  其中SVG容器:

1   var svgContainer = d3.select("body").append("svg")
2 .attr("width", 100)
3 .attr("height", 100);

宽100单位,高100单位。

  也就是说,图中三个长方形中最右下角的点的坐标(90,90)仍然在SVG容器视窗范围内。

  但是,如果紫色的长方形的x坐标,突然增加了四倍,从40变成160,结果会怎么样呢?

 1   //原来
2 { "x_axis": 40, "y_axis": 40, "height": 20, "width":20, "color" : "purple" }
3
4 //变为
5 { "x_axis": 160, "y_axis": 40, "height": 20, "width":20, "color" : "purple" }
6
7 //因此,数据集 jsonRectangles 变成了:
8 var jsonRectangles = [
9 { "x_axis": 10, "y_axis": 10, "height": 20, "width":20, "color" : "green" },
10 { "x_axis": 160, "y_axis": 40, "height": 20, "width":20, "color" : "purple" },
11 { "x_axis": 70, "y_axis": 70, "height": 20, "width":20, "color" : "red" }];

  这也就是说,紫色长方形有坐标值(160,40)。

  这个坐标已经超出高100宽100的范围。

  这样我们的数据可视化结果成了:

  就像我们想象的那样,太糟了!

动态调整SVG容器空间

  我们真正需要的是,能够根据我们的数据,对SVG容器的width、height属性进行动态调节。

  我们打算使用基础JavaScript循环(loop)来对JSON对象数组处理,找出最大的X坐标he最大的Y坐标。

  最大的x坐标和最大的y坐标就是长方形的最右下角点的坐标。

 //新的jsonRectangle数据(其中紫色长方形的x坐标现在是160)
var jsonRectangles = [
{"x_axis":10,"y_axis":10,"height":20,"width":20,"color":"green"},
{"x_axis":160,"y_axis":40,"height":20,"width":20,"color":"purplr"},
{"x_axis":70,"y_axis":70,"height":20,"width":20,"color":"red"}
]; var max_x = 0;//用于存储最大x坐标
var max_y = 0;//用于存储最大y坐标 //在jsonRectangle数组上的循环
for(var i = 0;i<jsonRectangles.length;i++){
var temp_x,temp_y; //为了得到最右的点,我们需要把x坐标和width相加
temp_x = jsonRectangles[i].x_axis+jsonRectangles[i].width; //为了得到最下面的点,我们需要把y坐标和height相加
temp_y = jsonRectangles[i].y_axis+jsonRectangles[i].height; /**
*如果临时x坐标比max_x大,
*那么就让max_x等于temp_x
*否则,什么都不用做
*同理,max_y也一样
*/
if(temp_x>=max_x){
max_x = temp_x;
} if(temp_y>=max_y){
max_y = temp_y;
} }//循环停止 max_x;
//返回180 max_y;
//返回 90

  如果数据发生了变化,max_x和max_y将始终都是数据中的最大值。

  现在,我们可以更新我们的SVG容器:

 //原来
var svgContainer = d3.select("body").append("svg")
.attr("height",200)
.attr("width",200); //现在(使用变量max_x和max_y)
var svgContainer = d3.select("body").append("svg")
.attr("width",max_x + 20)
.attr("width",max_x + 20);
//注意 — 在这里给max_x和max_y各加了20,是为了给元素多一些文本空间

  这样,SVG容器就一直能够显示右边的最大尺寸,我们的数据也就能正确的出现在其内部。

成品

  既然问题解决了,完整的代码如下:

 1   var jsonRectangles = [
2 { "x_axis": 10, "y_axis": 10, "height": 20, "width":20, "color" : "green" },
3 { "x_axis": 160, "y_axis": 40, "height": 20, "width":20, "color" : "purple" },
4 { "x_axis": 70, "y_axis": 70, "height": 20, "width":20, "color" : "red" }];
5
6 var max_x = 0;
7 var max_y = 0;
8
9 for (var i = 0; i < jsonRectangles.length; i++) {
10 var temp_x, temp_y;
11 var temp_x = jsonRectangles[i].x_axis + jsonRectangles[i].width;
12 var temp_y = jsonRectangles[i].y_axis + jsonRectangles[i].height;
13
14 if ( temp_x >= max_x ) { max_x = temp_x; }
15
16 if ( temp_y >= max_y ) { max_y = temp_y; }
17 }
18
19 var svgContainer = d3.select("body").append("svg")
20 .attr("width", max_x)
21 .attr("height", max_y)
22
23 var rectangles = svgContainer.selectAll("rect")
24 .data(jsonRectangles)
25 .enter()
26 .append("rect");
27
28 var rectangleAttributes = rectangles
29 .attr("x", function (d) { return d.x_axis; })
30 .attr("y", function (d) { return d.y_axis; })
31 .attr("height", function (d) { return d.height; })
32 .attr("width", function (d) { return d.width; })
33 .style("fill", function(d) { return d.color; });

  现在,所有的长方形都出现啦!

  SVG视窗能够把最右的(max_x+20,max_y+20)包括进去。

  而且,SVG视窗是动态生成,不需要我们去手动的更新width和height。

  使用JavaScript的For循环,我们就能够实现动态的resize我们的SVG视窗容器来适应数据。

  如果数据再次改变,我们的视窗(容器)也能够随时包含全部的数据可视化结果。

d2.js学习笔记(七)——动态SVG坐标空间的更多相关文章

  1. JS 学习笔记 (七) 面向对象编程OOP

    1.前言 创建对象有很多种方法,最常见的是字面量创建和new Object()创建.但是在需要创建多个相同结构的对象时,这两种方法就不太方便了. 如:创建多个学生信息的对象 let tom = { n ...

  2. Node.js学习笔记(七) --- Node.js的静态文件托管、路 由、EJS 模板引擎、GET 、POST

    1 . Nodejs 静态文件托管静态 web 服务器封装 2 . 路由 官方解释:  路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET.POST 等)组成的, ...

  3. D3.js学习笔记(四)—— 使用SVG坐标空间

    目标 在这一章,你将要使用D3.js基于一些数据把SVG元素添加到你想要的坐标位置上. 我们的目标就是使用下面的数据集: var spaceCircles = [30,70,110]; 并使用D3.j ...

  4. D3.js学习笔记(六)——SVG基础图形和D3.js

    目标 在这一章,我们将会重温SVG图形,学习如何使用D3.js来创建这些图形. 这里会包括前面例子中的SVG基础图形以及如何使用D3.js设置图形的属性. 使用D3.js画一个SVG 的 圆 circ ...

  5. 系列文章--Node.js学习笔记系列

    Node.js学习笔记系列总索引 Nodejs学习笔记(一)--- 简介及安装Node.js开发环境 Nodejs学习笔记(二)--- 事件模块 Nodejs学习笔记(三)--- 模块 Nodejs学 ...

  6. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  7. WebGL three.js学习笔记 使用粒子系统模拟时空隧道(虫洞)

    WebGL three.js学习笔记 使用粒子系统模拟时空隧道 本例的运行结果如图: 时空隧道demo演示 Demo地址:https://nsytsqdtn.github.io/demo/sprite ...

  8. WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法

    WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNor ...

  9. JS学习笔记5_DOM

    1.DOM节点的常用属性(所有节点都支持) nodeType:元素1,属性2,文本3 nodeName:元素标签名的大写形式 nodeValue:元素节点为null,文本节点为文本内容,属性节点为属性 ...

随机推荐

  1. 改变label中的某字体颜色

    NSString *allString=@"你家在哪里,需要我送你么"; NSString *subString=@"在哪里"; UILabel *string ...

  2. FW: AMD, CMD, CommonJS和UMD

    javascript 我是豆腐不是渣 4月5日发布 推荐 2 推荐 收藏 32 收藏,486 浏览 今天由于项目中引入的echarts的文件太大,requirejs经常加载超时,不得不分开来加载ech ...

  3. "零代码”开发B/S企业管理软件之二:怎么创建数据源

    声明:该软件为本人原创作品,多年来一直在使用该软件做项目,软件本身也一直在改善,在增加新的功能.但一个人总是会有很多考虑不周全的地方,希望能找到做同类软件的同行一起探讨. 本人文笔不行,能把意思表达清 ...

  4. Scrapy框架-scrapy框架快速入门

    1.安装和文档 安装:通过pip install scrapy即可安装. Scrapy官方文档:http://doc.scrapy.org/en/latest Scrapy中文文档:http://sc ...

  5. Scrapy框架-scrapy框架架构详解

    1.Scrapy框架介绍 写一个爬虫,需要做很多的事情.比如:发送网络请求.数据解析.数据存储.反反爬虫机制(更换ip代理.设置请求头等).异步请求等.这些工作如果每次都要自己从零开始写的话,比较浪费 ...

  6. 我的Android进阶之旅------>解决错误: java.util.regex.PatternSyntaxException: Incorrect Unicode property

    1.错误描述 今天使用正则表达式验证密码的时候,报了错误 java.util.regex.PatternSyntaxException: Incorrect Unicode property near ...

  7. 启动一个支持文件上传的HTTP-Server

    Python实现,源码来自网络,代码内部有作者信息. HTTP方式共享文件,对于不需要用户名和密码验证的系统非常方便.通过浏览器就可以实现文件上传和下载.非常适合用作测试系统的脚手架. 对于系统使用c ...

  8. vue-router路由器的使用

    一. vue-router路由 1.简介 1.为什么要用vue-router 使用Vue.js开发SPA(Single Page Application)单页面应用 2.什么是单页面应用 根据不同ur ...

  9. python selenium firefox使用

    演示的版本信息如下: Python 3.6.0 Selenium  3.5.0 Firefox 55.0.3 geckodriver v1.0.18.0 win64 1.前提准备 1.1 安装pyth ...

  10. 杭电1024Max Sum Plus Plus

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=1024 题目: Problem Description Now I think you have got a ...