d3总结

项目原因,需要使用web绘制图表,比较靠谱的有echart和d3。

echart:应该是百度的项目,首页做的很漂亮,文档也比较全。个人感觉是一个入手较易,主要在学习怎么配参数,地图是echart的一个亮点。缺点就明显了,入手容易的肯定高度封装过,很难根据自己的需求定制化。而且使用了cavas绘图,在移动端性能不如svg。个人感觉echart适合一些时间比较紧迫,设计没那么明确的场合,直接套上echart,就已经很漂亮了。

d3:大名鼎鼎,受欢迎程度超过jquery,首页的绚丽特效让人眼花,教程的话强烈推荐http://www.ourd3js.com/wordpress/,这个教程好像出了书,叫精通D3.js,基本上把教程撸一遍就没啥大问题了。

d3的优点:用过一段d3后,感觉d3就是svg的jquery,把svg的操作封装为更易用的接口,并提供各种数据可视化的接口。所以d3很灵活,因为你可以用d3在svg中添加一个点、线、饼等等,svg性能不错。链式写法。

缺点:入手稍微慢点,不过撸一遍教程也就一下午的时间。svg的接口网上文档比较少,有些用法stackoverflow都找不到。

如果是学习d3的,推荐前面的教程网站,这里只是个人备忘录,想到哪里说到哪里的流水账,记录那些让人眼前一亮或者眼前一黑的点,以及几个开发中反复查询的用法。

好了,出发

1.

首先,你要在一个dom中添加svg,需要两个参数,width和height,一般我是这么给的

踩坑:需求在指定操作后才绘制该图标,dom display:none的时候,clientWidth和clientHeight是0,所以svg等dom display正常后再添加。

接下来最好设置一下svg的padding,用来应付后面出现的各种文字绘制超出不显示,UI修改等灵细操作。

因为svg直接传的都是px,所以需要根绝屏幕做一下自适应,size_1920函数如下:

坐标轴:

图标中用到最多的是坐标轴,使用坐标轴首先要设定比例尺,目前共用到了4种比例尺

线性比例尺

domain中设置数据的min/max,range中设置svg实际位置。

备注:svg是以左上角为原点的,而常规视角中原点是左下角,所以这里的range起止位置是 svgHeight-0,即起始位置是下边缘y=svgHeight,终止位置是上边缘y=0。这一点需要谨记,后面有许多计算x、y位置的,y的位置总要反着想。其他比例尺也是一样的。

离散比例尺

or

时间比例尺

时间比例尺适用于一些以时间为坐标轴的情况

备注:比如这里是今天到明天,第二天nextDay的算法,就用秒,其他都不行。UTC时间一定要注意,所有时间都改成UTC时间,所有get一律要加UTC。

颜色比例尺

这是个比较特殊的比例尺,不是用来画坐标轴的,而是把颜色均匀分割,category10,category20等等都有,填一个index,输出一个色值。在有些d3的版本中,颜色比例尺没用放在scale里面。

坐标轴

可能还有更多种类的比例尺,目前还没有接触,下面就开始生成坐标轴数据。

几个常用参数

scale,必要参数,把比例尺填进去

orient,非必填,刻度相对坐标轴的位置 top bottom left right

ticks,非必填,刻度个数 注:ticks只是参考,最终生成刻度个数以数据为准,比如数据需要25个刻度,但ticks填了17,那d3就没办法了,会生成一个d3生成的刻度个数中选跟17最接近的。

innerTickSize,非必填,内刻度高,默认是6。 注:这里设置了innerTickSize是整个svg的高度,和y轴innerTickSize设置整个svg的宽配合行程网格效果,正常的坐标轴就再画一个,注意高度计算时错开

outerTickSize,非必填,外刻度高

tickFormat,非必填,刻度值,默认为空  注:这是一个数据绑定参数,即根据数据生成不同的值

tickPadding,非必填,刻度文字与坐标轴的间距

真正的绘制

 

给svg中添加g元素,call绑定坐标轴数据,attr就是给g元素添加各种属性,class(是不是很熟悉),transform。 注:svg中没有top left  margin等属性,大的位移使用transform。

曲线

坐标轴绘制完后,就是曲线的绘制,先生成曲线绘制函数

曲线绘制函数参数

x、y就是根据数据来计算坐标,这里是比例尺大显身手的地方。

interpolate,线段怎么弯曲,讲的最好的是这个地址

http://www.oxxostudio.tw/articles/201411/svg-d3-02-line.html

注:basis曲线保证了优美,没保证曲线与数据的一致,像我这种人是完全无法接受的。

绘制曲线

这一行代码解读一下就是选择所有class是data-line的元素,然后给它绑定数据。data-line哪里来的?这里涉及到d3中一个概念,update  enter  exit

selectAll得到的元素跟数据相比,有三种可能,元素个数 大于/小于/等于数据个数。

数据超出元素个数的部分叫enter,比如第一次绘制时,所有元素都属于paths.enter

paths元素比较简单直接,基本上只需要给一个属性d就能画出来了,d可以用前面的曲线函数直接生成。

stroke,线条颜色,这里可以用颜色比例尺 d3.scale.category10(i)

fill就是填充颜色,paths填充的是一个面。

不超出的部分叫update,即需要更新的部分,paths.update可以看到,也可以直接更新数据,这里是数据驱动的最直观表现

数据少于元素个数的部分叫exit,一般exit只有一个用法

到这里,一个坐标轴差不多出来了,但,是不是少了点啥,对,UED最喜欢的灵魂一击,动画。

曲线进入/更新的时候要动画怎么办

d3的动画很好写

增加 transition ease 和 delay即可,transition前后是动画的起始和结束状态。

绘制一个圆

矩形

半圆角矩形是用path生成的,顶部圆角矩形

topRoundRect和rightRoundRect乍一看完全搞不懂,这里讲的比较详细https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths,仔细观察下,就是

M  起始x y坐标

h 纵移

v 横移

a 比较复杂 前两个参数是圆角的x y radius

中间三个参数 001是三个flag,只能是0/1 圆角矩形都是001

第一个代表弧线角度是否要大于180

第二个代表正角度还是负角度

第三个代表正方向还是反方向

z是合拢

最后两个参数是终止的x y位置

当前了,还有更多的L C S等等,这里不研究了

文字

到这里,d3绘制的套路差不多都熟悉了,append data enter transform attr,拿来画个饼图吧!

生成饼图数据

查看一下this.pieData,你会发现数据增加了 startEngle 和 endEngle

注:饼图默认会按大小排序,如果不需要排序,增加一个sort(null)即可

弧线函数

饼图动画不能使用d了,要使用attrTween

简单的饼图动画

高级饼图动画,自己计算delay的时间,让饼一点一点出来

往饼图中间添加一个圆点

注:centriodData和Angle是钝/锐角的计算提出来,是因为在某些低配机子上,偶现绑定计算错误。

画一个折线

到这里,一般的坐标轴、饼图已经难不倒了,而且自己想添加什么就添加什么,无非就是计算x、坐标,d3就是一堆图形函数,帮你计算坐标而已,那还有什么新东西吗?假如UED说想要阴影,光效,这里介绍一下svg里面一个很牛叉的东西,filter

实话说,这个东西我也只是到抄过来调参的地步,比如dx dy。理解上只知道特效输出为result,下一个特效的in是这个result,其他也是一问三不知,而且看了之后着实没有深入了解下去的想法,简直就是手写Photoshop。

下面是几个介绍filter的地址,留下以备不时之需

1.https://www.w3.org/TR/SVG/filters.html

2.https://www.smashingmagazine.com/2015/05/why-the-svg-filter-is-awesome/

3.https://jorgeatgu.github.io/svg-filters/

 

 

 

 

被优化为无排版和缩进的JavaScript代码,如何调试?

有时候网页上的 JavaScript代码被优化器优化过后,会丢失原来的换行,导致整个的代码蜷缩成一行,完全没办法调试,此时我们就需要借助 Chrome或者 FireFox自带的代码调整功能来实现代码的调试了,如下图:

参考链接


毫无排版和缩进的 JavaScript 代码,怎么阅读?

d3['default'] is undefined

使用Babel引入d3,即import d3 from 'd3',使用时出现undefined的错误,调试后发现

var _d3 = __webpack_require__(164);

var _d32 = _interopRequireDefault(_d3);

var fill = _d32['default'].schemeCategory20;

_d3有schemeCategory20,d32['default']是undefined,

_interopRequireDefault是什么鬼?

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

就是根据__esModule 的一个if else,__esModule又是什么?

这里有一篇比较具体的解释 http://ryerh.com/javascript/2016/03/27/babel-module-implementation.html

简单来说,default就是我们在class后面写的 export default xxx

翻一翻源码,d3的default是true,但没有export default

 

相关链接:__esModule true in build/d3.js?

Improve docs: ES6 usage example

从这两个链接中,找到了d3的正确用法

import * as d3 from 'd3'

import文档

就是说,把d3的所有模块导出,给d3这个作用域

调试来看,就是

var _d3 = __webpack_require__(164);

var d3 = _interopRequireWildcard(_d3);

可以看到,用了import as后

从_interopRequireDefault转变为_interopRequireWildcard

也就是*替换了default

另外,必须再说一下,d3没有default,但d3的插件不一定没有

比如我使用的d3-cloud,还是要用import cloud from 'd3-cloud'

IntelliJ IDEA 2016.2使用Spring 4.3.1.RELEASE,sockjs-1.1.1,stomp-1.2搭建基于Tomcat-7.0.68的WebSocket应用

接着上文IntelliJ IDEA 2016.2使用Spring 4.3.1.RELEASE搭建基于Tomcat-7.0.68的WebSocket应用

上文的最后我们说到, WebSocket是需要定时心跳的,否则会在一段时间后自动断开连接,而更重要的是,不是所有的浏览器都支持 WebSocket,早期的 IE 10之前的版本就是不支持的,而这一部分的设备其实是不算少的,而 sockjs的出现,恰恰好来解决了这个问题。对于不支持 WebSocket的浏览器, sockjs使用了多种方式来兼容这种情况,包括使用长轮询等方式, Spring更是内建支持这种方式。

下面我们看如何在上篇文章的基础上,增加对于 sockjs的支持。

首先是 STOMP的文档官网地址 http://stomp.github.io/
代码的地址为https://github.com/jmesnil/stomp-websocket,项目下面的 lib/stomp.js就是我们想要的文件。也可以本站下载stomp.js.zip

接下来 sockjs的代码地址https://github.com/sockjs/sockjs-client,项目下面的 dist/sockjs-1.1.1.js就是我们想要的文件。也可以本站下载sockjs-1.1.1.js.zip

接下来我们把下载到的文件放到我们工程目录下面的 web-> resources-> javascript目录下面,如下图:

stomp-websockjs-resources

接下来,添加我们需要的 com.fasterxml.jackson.core:jackson-annotations:2.8.1, com.fasterxml.jackson.core:jackson-core:2.8.1, com.fasterxml.jackson.core:jackson-databind:2.8.1这三个 jar包,增加的方式参照上一篇中对于 javax.servlet:javax.servlet-api:3.1.0的操作方法。与上一篇的操作不同的是,这次添加的三个 jar包,都要放到编译完成后的 War包中。最后的结果如下图:
ToolsJacksonMaven

ToolsJacksonMavenWar

下面,我们开始进行代码的操作,我们在上篇文章中的 src-> Tools-> WebSocket中新增两个源代码文件 SockJsController.java, WebJsSocketConfig.java.如下图:

NewJavaSourcesForSockjs

其中的代码如下:
SockJsController.java

WebJsSocketConfig.java

然后修改 WebSocket.jsp

最后,我们修改 web-> WEB-INF-> web.xml,在其中增加

修改后的最终结果如下:

参考链接


 

js文件中获取${pageContext.request.contextPath}

一般从 JSP文件中,可以直接使用 ${pageContext.request.contextPath}非常方便的获得当前页面的路径,用来处理被 Apache2代理之后出现 URL变化的问题,比如增加了某些前缀,方便转发,即使是 JSP内嵌的 JavaScript脚本,也是可以如此操作。但是如果是一个独立的 JavaScript文件,通过

这样的方式引入,则在 JavaScript文件内部是无法直接调用 ${pageContext.request.contextPath}获取前缀的,因为 ${pageContext.request.contextPath}是需要 JSP文件处理的变量,而对于独立的 JavaScript文件,默认是不做任何处理的。

因此这个变量只能是通过某个全局变量传递到 JavaScript文件中。
目前比较有效的实现方法是通过设置一个隐藏的文本框的方式来处理。

JavaScript文件中获取这个变量的方法如下:

JS-深拷贝

在JS中使用变量,使用=号拷贝,如

obj1 = obj2

是浅拷贝,即改变obj1内容的时候也会改变obj2.

有时候我们是不希望看到这种情况的,JS使用深拷贝有很多方法,介绍一个简单好用的

这种用法会破坏obj2的构造类型,但一般情况是足够了。

使用YUIdoc

最近遇到任务,需要对外提供接口。发现最困难的事是写文档,因为代码经常在修改,每天更新word很困难。然后就发现了文档神器YUI doc,以及神器的剑鞘smartdoc:http://www.cnblogs.com/zhh8077/p/4010991.html。

简单介绍一下使用方法和遇到的坑。

YUI doc可以看成一种标准,主要看这里http://www.cnblogs.com/zhh8077/p/4011769.html或者YUI doc的官方文档。

module写法

class写法

method常用写法

其中 param.xx是二级参数的写法。

event与method一样

常量

smartdoc的使用就比较简单了,参考其主页文档。

这里主要想说的是 使用过程中遇到的一些坑。

1.生成的method event等等按照字母顺序排列,而不是按照我们文档中的顺序排列。

.YUIDoc生成的API文档目录不按源文件注释顺序

YUIDoc默认将所有的class、method、properties、events等按字母进行排序。

而且这个是在生成文档时进行排序的,所以如果除去按字母进行排序这种默认行为。

就必须修改YUIDoc的工具文件。修改C:\Users\Administrator\AppData\Roaming\npm\node_modules\yuidocjs\lib 下的 builder.js 文件

第1313-1316行,就是这几句罪魁祸首,注释掉后就可以按源文件注释顺序,当然你也可以自己弄其他排序方法。

方法源自:http://www.cnblogs.com/lovesong/p/3341453.html

2.event的example不显示。使用smartdoc生成文档后,其他地方都挺好,但event的example就是显示不出来。chrome上面,直接F12,看document,看到example部分,display:none。method增加了一个active的class,display:block。很简单,看看这个css是在哪里写的。

C:\Users\用户名\AppData\Roaming\npm\node_modules\smartdoc\theme-smart\assets\css

路径下的main.css。改一下其中的example的display就可以了。

修改整个页面的布局也是修改这里。这里就是我们使用的主题,自己可以改,也可以搞一套。

 

WebStorm下配置less环境

Webstorm是一个很优秀的js IDE。今天打算学习less的时候,创建一个less文件后发现webstorm提示是否AddWatcher,点开后发现是一个自动编译less文件的工具,可惜不能直接使用,需要简单配置一下。

所有资料来自于

https://www.jetbrains.com/webstorm/help/transpiling-sass-less-and-scss-to-css.html。

洋洋洒洒一大坨,读起来有点费劲。实际操作了一下,发现简单的要命。

首先,你要装好node环境,没装的请自行百度。

1.View-ToolWindows-Terminal

2.输入 npm install -g less

搞定。

 

再次打开AddWatcher窗口,你就发现所有选项已经自动填好了。

less文件左边出现了一个小箭头,点开看到了css文件,完全同步。

JS获得element的index

获得某个element在parent中的index。

jquery提供了index接口,可以直接拿到。

如果没有jquery的话,

将document查询到的HTML Collection转为Array,

然后使用Array的index接口拿到index。

CSS:position、float

之前写css,一直是把position:absolute当做android的FrameLayout用的,其他类似。

后来看了下面的文章,满面羞愧。

这些基础的东西,还是要了解透彻的,一直不求甚解的搞下去,自己都不知道做的什么,为什么会出现这种错误,希望能从下面的内容中,总结出一个类似于Androidlayout的规则。

关于position看下面的文章就够了

http://blog.csdn.net/chen_zw/article/details/8741365

css属性大全

http://css.doyoe.com/

这里主要记一下看完自己的理解:

文档流

首先需要了解什么是文档流,可以理解为方块布局,从上到下,从左到右的布局方式就是文档流。

1.margin和padding是占用文档流的,也就是说,layout函数一定是这么写的

element.margin + elment.width/height +element.padding = dom真正占用的空间。

position:static很容易理解,完全遵循文档流。

position:relative 有点特殊,本身遵循文档流,但可以在文档流中使用top left bottom right设置偏移,偏移不遵循文档流。需要注意的是,后面的dom会按照relative元素不偏移来排列。layout函数中完全可以把relative按照static先处理,最后在当前位置进行偏移。

注:relative static无父辈时以body为参考;

position:absolute 脱离文档流,使用top left bottom right设置偏移,偏移参照为父辈最近的非static元素(之前一直认为absolute参照window,深刻检讨)。

注:absolute无父辈时以html为参考。

1、body默认有9个px的margin

2、absolute的元素没有设置top、left时,默认是文档流的位置,会造成设置了absolute,看起来没有效果的现象。

position:fixed fixed以window为参考(即不管你怎么scroll,位置都不会变),设置偏移。

float:absolute会屏蔽掉float,其他的可以共存。

float不遵循文档流。

clear:clear是配合float使用的。意思是把dom的哪边给清除掉。

如clear:both,意思是两边都不许浮动。

如果我来写 html的layout,

1.dom tree static,relative的按照文档流布局,relative单独处理下偏移,完全不影响文档流。

fixed很简单粗暴。

2.处理absolute float

absolute屏蔽float

absolute需要寻找父辈非static元素直到html,比较蛋疼。这个webkit在渲染的时候会把absolute的元素单独出来一层。

float是浮动排版,按文档流布局就差不多。

当然,css3还有更多的排版方式,上面几种已经基本够用,如果还要学习的话就是box了。