为了实现元素的添加,删除,拖拽,左键点击,右键单击,悬浮等功能,使用了d3 + svg 的技术来实现界面。

最开始是采用canvas,但是由于功能原因放弃了该技术,可以看下 canvas简介

另附:canvas和svg区别

首先,下载d3.min.js和snap.svg-min.js

如果使用的是bower,

安装d3,bower --allow-root install -S d3

安装svg,bower --allow-root install -S snap.svg

然后页面再引入。

新建画布主要有两种方式,

(1)html页面中

<svg id="svg_order" xmlns="http://www.w3.org/2000/svg" version="1.1" width="622px" height="417px">
</svg>

js中

var svg = Snap("#svg_order");
var rect = svg.paper.rect(hengwidth*widthOffest,shuwidth*heightOffest,imageWidth,imageHeight,imageRadius);
var text = svg.paper.text((hengwidth*widthOffest)+imageWidth/2-5, (shuwidth*heightOffest)+imageHeight/2, i+1);
var group = svg.paper.g(rect, text).attr({id:"groupId"+i,class:"groupClass"});

(2)html页面中

<div id="main_client_order">
</div>

js中

var svg = null;

        /*构建基础画布*/
function drawPanel(screenWidth, screenHeight) {
svg = d3.select('#main_client_order')
.append('svg:svg')
.attr('width', screenWidth+100)
.attr('height', screenHeight+100)
.style("margin-left", "20px")
.style("margin-top", "20px")
.attr("id", "orderId");
}
var addRect = svg.append("g");
addRect.append("rect");
addRect.append("text");

在画布上面开始画图

var addRect = svg.append("g");
addRect.append("rect");
addRect.append("text");
addRect.append("rect").style('visibility', 'hidden');(标记1)
addRect = addRect.call(drag);//给元素添加拖拽事件,拖拽事件需要定义在此代码之前。

给元素添加事件

悬浮事件和右键事件

addRect.on("contextmenu", function (data, index) {
//右键事件
d3.event.preventDefault();
}).on("mouseover", function (data, index) {
//悬浮事件 over
}).on('mouseleave', function () {
//悬浮事件 leave
});

拖拽事件(此方法要放在元素添加拖拽事件之前)

var drag = d3.behavior.drag()
.on('dragstart', function (d) {
//拖拽开始事件,需要通过标志位区分点击按下时和拖拽开始。
}).on('drag', function (d) {
//拖拽中事件,此时可以限制拖拽的边缘范围。
}).on('dragend', function (d) {
//拖拽结束事件,需要通过标志位区分点击松起时和拖拽结束。
});

事件实现概述

在界面中画图时,需要边画边在页面存入数据,我存入的数据是一个二维数组,a[i][j] i表示的是行 j表示的是列

var rect = "{id:'inner_" + id + "',x:" + startX + ",y:" + startY + ",type:" + colortype + ",highlight:"+highlighttype+"}";
var jsonRect = eval('(' + rect + ')');
var a1 = startX / widthOffset;
var a2 = startY / heightOffset;
if (gData[a2] == null) {
gData[a2] = new Array();
}
//存储元素的id,x,y
gData[a2][a1] = jsonRect;
//存储id备份值 只存储id (标记2)
var rect_id_bak = "{id:'inner_" + id + "'}";
var jsonRect_id_bak = eval('(' + rect_id_bak + ')');
if (gDataId_bak[a2] == null) {
gDataId_bak[a2] = new Array();
}
gDataId_bak[a2][a1] = jsonRect_id_bak;

只所以存储一个备份id,是为了保存行列元素与id值的对应。也就是第几行第几列的元素的id值。

针对以上的两次标记,解释如下:

  1.g元素是空元素,无法捕捉悬浮,点击,拖拽等事件。需要在等位置填充一个元素。目前是采用相同位置,相同长宽的方块来填充该位置。(对应标记1)

The g element is just an empty container which cannot capture click events,then appending an invisible rectangle to it as a place to hover over 来源:d3-js-mouseover-event-not-working-properly-on-svg-group

  2.g元素没有x,y值,移动g元素只能用transform(x,y)的方式。(对应标记2)

The <g>-element doesn't have x and y attributes. To move the contents of a <g>-element you can only do so using the transform attribute, using the "translate" function, like this: transform="translate(x,y)".来源:SVG g element

鼠标点击的mouse()方法只能获取在画布中的位置,根据该位置的行列,x除以长得到i,y除以宽得到j,然后再从备份数据gDataId_bak中,找到对应的id,然后再根据id在html中获取该元素的偏移量,也就是transform(x,y)中的x,y,相加之后得到实际位置的x,y,x除以长得到i,y除以宽得到j,然后再从gData中获取真正的元素。

需要注意几点:

  1.拖拽中,d3.event.x  d3.event.y可以获取真实位置信息。

  2.d3.event.sourceEvent.button 可以区分左右键点击事件,0 是左键 2是右键

  3.另附d3文档

svg + d3的更多相关文章

  1. D3+svg 案例

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

  2. [D3] 2. Basics of SVG

    1. svg should use 'fill' prop instead 'background-color'2. svg width & height no need 'px'3. att ...

  3. 【D3.V3.js系列教程】--(十五)SVG基本图形绘制

    [D3.V3.js系列教程]--(十五)SVG基本图形绘制 1.path <!DOCTYPE html> <html> <head> <meta charse ...

  4. D3中的each() 以及svg defs元素 clipPath的使用

    each() 方法允许我们定制对选择集中DOM元素的处理行为: selection . each ( func ) 参数 func 是调用者定义的函数,在d3中被称为 访问器/accessor . d ...

  5. D3.js & Data Visualization & SVG

    D3.js & Data Visualization & SVG https://davidwalsh.name/learning-d3 // import {scaleLinear} ...

  6. angular7 + d3 显示svg

    汇总一些之前没有注意到的问题 总体思路: app只是显示svg为主,接收后端推送的数据改变,显示变化后的svg. 因此,只用d3的数据绑定更新组件里<svg></svg>节点. ...

  7. 使用d3.v3插件绘制出svg图

    众所周知,这个插件使用的svg技术,而IE8(包括IE8)之前的浏览器是不支持svg的 接下来看代码吧 从后台获取到带id和父id的目录数据[json格式] var module = requestU ...

  8. SVG基础图形和D3.js

    使用D3.js画一个SVG 的 圆 circle 可以使用如下代码创建: <svg width="50" height="50"> <circ ...

  9. D3——绘制SVG图形-直方图

    1.创建SVG元素 var svg = d3.select("body").append("svg"); 2.为SVG元素设置属性 svg.attr() .at ...

随机推荐

  1. [LeetCode] Search for a Range 搜索一个范围

    Given a sorted array of integers, find the starting and ending position of a given target value. You ...

  2. Oracle 表和表数据恢复

    1. 表恢复 对误删的表,只要没有使用 purge 永久删除选项,那么基本上是能从 flashback table 区恢复回来的. 数据表和其中的数据都是可以恢复回来的,记得 flashback ta ...

  3. Todo list and 学习心得

    1. 理论实践要区分起来学习,结合起来运用. 2. 内事不决问百度外事不决问谷歌 3. 一个人走的快,一群人走得远或者更快 2016-09-01 23:27:58  九月目标:对程序从编译到执行的整个 ...

  4. 详解C#中的反射

    反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B ...

  5. FFmpeg 转码和截屏

    转码 (flv转码为MP4,libx264是MP4编码格式 , -b 3000k是码率,比特率) ffmpeg -i /home/ghr/mp4/mp4.flv -vcodec libx264 -b ...

  6. insmod模块的几种常见错误

    1. 与内核版本不一致 嵌入式开发时,模块编译时需要制定内核的路径,内核的版本信息会加入到模块文件中,如果目标板上运行的内核与模块中包含的内核版本对不上,加载就会出错,报如下错误:  insmod i ...

  7. python实战(开发新浪微博应用)

    #coding=utf-8 """ 本应用主要功能 1.用户选择喜欢的标签加关注 2.获取用户粉丝中自己还没有关注的,->加关注,提高粉丝稳定性 3.获取用户关注列 ...

  8. C#定义类型转化 及 格式化字符串

    operator 关键字 operator 关键字用来重载内置运算符,或提供类/结构声明中的用户定义转换.它可以定义不同类型之间采用何种转化方式和转化的结果. operator用于定义类型转化时可采用 ...

  9. typedef

    第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, ...

  10. html中用div代替textarea实现输入框高度随输入内容变化

    项目中的需求:留言栏输入高度变化,超过1行时,自动伸展,超过4行后,不再伸展.主要思想是利用最小高度和最大高度,再加上overflow来实现,到了最大高度,文字不会溢出而是隐藏.根据文本框中字体的大小 ...