爲了實現元素的添加,刪除,拖拽,左鍵點擊,右鍵單擊,懸浮等功能,使用了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文檔