为了实现元素的添加,删除,拖拽,左键点击,右键单击,悬浮等功能,使用了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. JS组件系列——BootstrapTable+KnockoutJS实现增删改查解决方案(一)

    前言:出于某种原因,需要学习下Knockout.js,这个组件很早前听说过,但一直没尝试使用,这两天学习了下,觉得它真心不错,双向绑定的机制简直太爽了.今天打算结合bootstrapTable和Kno ...

  2. 小谈Jquery框架

    现在Jquery框架对于开发人员基本上是无人不知,无人不晓了,用起来十分的方便,特别是选择器十分强大,提高了我们的开发速度.但是好多人也只是停留在了会用的基础上,我个人觉得会用一个框架不算什么,只能说 ...

  3. chpasswd-批量修改用户密码

    批量修改用户密码 工作原理: 从系统的标准输入读入用户的名称和口令,并利用这些信息来更新系统上已存在的用户的口令 语法: :# echo 用户名:密码 | chpasswd :# chpasswd & ...

  4. MySQL基础

    数据库操作 ---终端使用数据库 mysql -u root -p 之后回车键 输入密码 ---显示所有数据库: show databases; ---默认数据库: mysql - 用户权限相关数据 ...

  5. java--面向对象---访问属性

    <第一节> private--只能用于成员变量和成员函数(限制于类而不是对象),即只能在本类中访问被定义为private 的变量 public-- protected-- <第二节& ...

  6. 用Python实现多核心并行计算

    平常写的程序,无论是单线程还是多线程,大多只有一个进程,而且只能在一个核心里工作.所以很多应用程序即使正在满载运行,在任务管理器中CPU使用量还是只有50%(双核CPU)或25%(四核CPU) 如果能 ...

  7. gdb调试器的使用

    想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车    是运行上一个命令 ...

  8. vue2.0---组件

    什么是组件? 组件是vue.js最强大的功能之一.它可以扩展HTML元素,封装可重用的代码.在更高的层次上,组件是自定义的元素,vue的编译器给它添加特殊功能.其实在有些情况下,组件也可以是原生HTM ...

  9. 【原创】JEECMS v6~v7任意文件上传漏洞(1)

    文章作者:rebeyond 受影响版本:v6~v7 漏洞说明: JEECMS是国内Java版开源网站内容管理系统(java cms.jsp cms)的简称.该系统基于java技术开发,继承其强大.稳定 ...

  10. 【转】Ubuntu 16.04安装配置TensorFlow GPU版本

    之前摸爬滚打总是各种坑,今天参考这篇文章终于解决了,甚是鸡冻\(≧▽≦)/,电脑不知道怎么的,安装不了16.04,就安装15.10再升级到16.04 requirements: Ubuntu 16.0 ...