svg + d3

爲了實現元素的添加,刪除,拖拽,左鍵點擊,右鍵單擊,懸浮等功能,使用了d3 + svg 的技術來實現界面。html

最開始是採用canvas,可是因爲功能緣由放棄了該技術,能夠看下 canvas簡介json

另附:canvas和svg區別canvas

首先,下載d3.min.js和snap.svg-min.js數組

若是使用的是bower,app

安裝d3,bower --allow-root install -S d3svg

安裝svg,bower --allow-root install -S snap.svgthis

而後頁面再引入。spa

新建畫布主要有兩種方式,.net

(1)html頁面中code

<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文檔

相關文章
相關標籤/搜索