svg + d3

为了实现元素的添加,删除,拖拽,左键点击,右键单击,悬浮等功能,使用了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文档

时间: 2024-12-06 17:32:54

svg + d3的相关文章

[D3] 2. Basics of SVG

1. svg should use 'fill' prop instead 'background-color'2. svg width & height no need 'px'3. attr(function(data_val, index){})4. create svg, d3.select('selector').append('svg').attr('width', xxx).attr('height', xx)5. svg should use 'rect' instead of

d3 根据数据绘制svg

var dataset = [ 5, 10, 15, 20, 25 ]; var circles = svg.selectAll("circle") .data(dataset) .enter() .append("circle"); circles.attr("cx", function(d, i) { return (i * 50) + 25; }) .attr("cy", h/2) .attr("r"

d3创建多个svg元素

当然也可以创建dom var svg = d3.select('#svg'); svg .slectAll('circle.bb')     //选中DOM中的所有circle.bb标签,当DOM中不存在circle.bb时,那么这个返回值将是null .data(new Array(50))   //计算并且传递数组的值,数组长度为50,因此所有经过此节点的处理过程将处理50次,每次对应数组中不同的元素值 .enter() //创建新的DOM元素,当数组的数据被传递至此,数组中的元素个数多于D

D3——绘制SVG图形

1.创建SVG元素 var svg = d3.select("body").append("svg"); 2.为SVG元素设置属性 svg.attr("width", 500) .attr("height", 50); 或: //Width and height var w = 500; var h = 50; var svg = d3.select("body") .append("svg&qu

D3利用viewBox属性等比例缩放SVG图像

把svg标签下的所有元素所占的1000*1000大小在300*300中显示,代码如下: var svg = d3.select("body").append("svg")     .attr("width", 300)     .attr("height", 300)     .attr("viewBox", "0 0 1000 1000")     .append("g&qu

D3中对svg 分析新增 defs元素 增加each()

each() 方法允许我们定制对选择集中DOM元素的处理行为: selection . each ( func ) 参数 func 是调用者定义的函数,在d3中被称为 访问器/accessor . d3将对选择集中的 每一个 DOM对象, 依次 调用该访问器函数. 在调用 访问器 函数时,d3会将 this 指向当前要处理的 DOM对象 , 并传入两个参数: datum : 当前DOM对象对应的数据 index :当前DOM对象在集合中的序号 可以认为 访问器 是d3流水线中每个处理环节 用户逻

d3.js(2)-svg

1.svg基础 话不多说直接上代码. <svg width=500 height=960> <rect x="0" y="0" width="500" height="50"/> <ellipse cx="250" cy="225" rx="100" ry="25"/> <line x1="0&q

SVG基础图形和D3.js

使用D3.js画一个SVG 的 圆 circle 可以使用如下代码创建: <svg width="50" height="50"> <circle cx="25" cy="25" r="25" fill="purple" /> </svg> D3.js来创建这些图形可以看做这一过程为两步: 创建SVG容器(SVG坐标空间) 画圆形 //创建一个SVG容

d3.js学习

画svg图像 1.添加svg元素 2.添加g元素,g元素是一个分组的元素,相当于html中的div元素 3.画图像 4.画坐标轴 ----------------------------------------------------------------------------- d3画闲线性曲线例子 html: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&