zoukankan      html  css  js  c++  java
  • 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文档

  • 相关阅读:
    NGINX -- 详解Nginx几种常见实现301重定向方法上的区别
    数据库外键的使用以及优缺点
    phpok -- 域名问题
    Sql Server系列:多表连接查询
    Go -- cron定时任务的用法
    JavaScript -- 清除缓存
    sql CAST用法
    Mock -- 数据模拟
    EsLint入门
    citus real-time 分析demo( 来自官方文档)
  • 原文地址:https://www.cnblogs.com/cuiyf/p/4930788.html
Copyright © 2011-2022 走看看