无法在iframe中嵌入包含svg元素的html页面

时间:2016-05-23 11:49:36

标签: html5 iframe svg object-tag

flowchart.js

/**
* Basic flow chart to draw connections between nodes and lines.
* requires jQuery and jQuery UI.
*/
var FlowChart = function(jQueryLibraryObj){
  var _t = this;
  _t.jQueryLibraryObj = jQueryLibraryObj;
  _t.jQueryLibraryObj('body').append(_t.connectionsLayerTemplate);
  _t.jQueryLibraryObj('body').append(_t.nodesLayerTemplate);
};

/**
 * jQuery library object.
 *
 * @type {jQuery}
 */
FlowChart.prototype.jQueryLibraryObj = {};

/**
 * Connections layer template.
 * This layer is for connection lines only.
 *
 * @type {string}
 */
FlowChart.prototype.connectionsLayerTemplate = "<svg id='connections-layer' class='layer'><svg>";

/**
 * Nodes layer template.
 * This layer is for nodes only. Each node is can be whatever absolute positioned DOM element.
 *
 * @type {string}
 */
FlowChart.prototype.nodesLayerTemplate = "<div id='nodes-layer' class='layer'></div>";

/**
 * Default node templates. Node templates are key - value objects, where key is in the same time the node type
 * and node css class. Value is the node content template. Node content is wrapped in a node wrapper DOM element.
 * Node wrapper DOM element is absolute positioned and placed in the nodes layer.
 *
 * @type {{simple-node: string}}
 */
FlowChart.prototype.nodeTemplates = {
  "simple-node": "simple node"
};

/**
 * Default root node position in the nodes layer.
 *
 * @type {{left: number, top: number}}
 */


/**
 * Default offset for the next child node element. If not explicitly specified, the child nodes are added on the
 * right side of the parent node with this particular offset.
 *
 * @type {number}
 */
FlowChart.prototype.offsetForNextElement = 200;

/**
 * Default node action end effect name.
 *
 * @type {string}
 */


/**
 * Default node actions for each node added to the nodes layer.
 * Default action adds a new simple node when user clicks on the node.
 *
 * @param nodeObj
 * @param chartInstanceObj
 */


/**
 * Elements index counter used to generate unique id for the nodes and layers.
 *
 * @type {number}
 */
FlowChart.prototype.elementIndex = 0;

/**
 * Returns next available element index.
 *
 * @returns {number}
 */
FlowChart.prototype.nextElementIndex = function(){
	this.elementIndex = this.elementIndex + 1;
	return this.elementIndex;
}

/**
 * Chart connections collection.
 *
 * @type {{}}
 */
FlowChart.prototype.connections = {};

/**
 * Adds or updates a connection in the connections collection.
 *
 * @param connId
 * @param startNodeId
 * @param endNodeId
 * @param connD
 */
FlowChart.prototype.addOrUpdateConnectionInConnectionsObject = function(connId, startNodeId, endNodeId, connD){
	this.connections[connId] = {
		start: startNodeId,
		end: endNodeId,
		d: connD
	};
};

/**
 * Deletes connection from connections collection.
 *
 * @param connId
 */


/**
 * Gets a connection from connections collection.
 *
 * @param connId
 * @returns {collection object}
 */
FlowChart.prototype.getConnectionFromConnectionsObject = function(connId){
	return this.connections[connId];
};

/**
 * Chart Nodes collection.
 *
 * @type {{}}
 */
FlowChart.prototype.nodes = {};

/**
 * Adds or updates node in the nodes collection.
 *
 * @param nodeId
 * @param nodeType
 * @param nodeContent
 * @param nodeLeftPos
 * @param nodeTopPos
 * @param startpointFor
 * @param endpointFor
 */
FlowChart.prototype.addOrUpdateNodeInNodesObject = function(nodeId, nodeType, nodeContent, nodeLeftPos, nodeTopPos, startpointFor, endpointFor){
	this.nodes[nodeId] = {
		type: nodeType, 
		content: nodeContent, 
		left: nodeLeftPos, 
		top: nodeTopPos, 
		startFor: startpointFor, 
		endFor: endpointFor
	};
};

/**
 * Deletes node from the nodes collection.
 *
 * @param nodeId
 */
FlowChart.prototype.deleteNodeFromNodesObject = function(nodeId){
	delete this.nodes[nodeId];
};

/**
 * Gets node from the nodes collection.
 *
 * @param nodeId
 * @returns {*}
 */
FlowChart.prototype.getNodeFromNodesObject = function(nodeId){
	return this.nodes[nodeId];
};

/**
 * Positions single connection point (start- or endpoint).
 *
 * @param left
 * @param top
 * @param linePointType
 * @param lineObj
 * @param finishArrangement
 */
FlowChart.prototype.positionConnectionPoint = function(left, top, linePointType, lineObj, finishArrangement){
    var d = this.getConnectionFromConnectionsObject(lineObj.attr('id')).d.split(' ');
    if (linePointType === 'endpoint') {
      d[3] = left + ',' + top;
      if (finishArrangement) {
        d[2] = left + ',' + top;
      }
    }  
    if (linePointType === 'startpoint') {
      d[0] = 'M' + left + ',' + top;
      if (finishArrangement) {
        d[1] = 'C' + left + ',' + top;
      }
    }
	d = d.join(' ');
    lineObj.attr('d', d);
	this.connections[lineObj.attr('id')].d = d;
}

/**
 * Positions connections of the node.
 *
 * @param nodeObj
 * @param finishArrangement
 */
FlowChart.prototype.positionConnectionLines = function(nodeObj, finishArrangement){
     var _t = this;
     var t = nodeObj;
     var left = t.offset().left + t.outerWidth() / 2;
     var top = t.offset().top + t.outerHeight() / 2;
      
     var linesRight = _t.nodes[t.attr('id')].startFor;
     var linesLeft = _t.nodes[t.attr('id')].endFor;
      
        for (var i = 0; i < linesRight.length; i++)
        {
          this.positionConnectionPoint(left, top, 'startpoint', _t.jQueryLibraryObj('#' + linesRight[i]), finishArrangement);
        }
     

        for (var i = 0; i < linesLeft.length; i++)
        {
          this.positionConnectionPoint(left, top, 'endpoint', _t.jQueryLibraryObj('#' + linesLeft[i]), finishArrangement);
        }
}

/**
 * Adds new node both in nodes collection and in the DOM.
 *
 * @param nodeId
 * @param nodeType
 * @param nodeContent
 * @param posLeft
 * @param posTop
 * @returns {string}
 */
FlowChart.prototype.addNodeWithIdContentAndPosition = function(nodeId, nodeType, nodeContent, posLeft, posTop){
  var _t = this;
  
  // if no content specified, just get the template
  if (!nodeContent || nodeContent === ''){
	  nodeContent = _t.nodeTemplates[nodeType];
  }
  
  // add new node to nodes layer
  var nodesLayer = this.jQueryLibraryObj('#nodes-layer');
  var nodeClass = 'node ' + nodeType;
  var node = "<div id='" + nodeId + "' class='" + nodeClass + "'>" + nodeContent + "</div>";
  nodesLayer.append(node);
  node = this.jQueryLibraryObj('#' + nodeId);
  
  // add node
  _t.addOrUpdateNodeInNodesObject(nodeId, nodeType, _t.nodeTemplates[nodeType], 0, 0, [], []);

  // define node position
  node.offset({left: posLeft, top: posTop});
  _t.nodes[nodeId].left = posLeft;
  _t.nodes[nodeId].top = posTop;
  
  
  
    
  // adjust layers size to avoid scrolling out of viewport
  _t.adjustLayersSize();
  
  // nice appearing effect

   
  return node;
}

/**
 * Adds new node both in nodes collection and in the DOM.
 *
 * @param nodeType
 * @param posLeft
 * @param posTop
 * @returns {*}
 */
FlowChart.prototype.addNodeWithPosition = function(nodeType, posLeft, posTop){
  var _t = this;
  return _t.addNodeWithIdContentAndPosition("node-" + _t.nextElementIndex(), nodeType, _t.nodeTemplates[nodeType], posLeft, posTop);
}

/**
 * Adds new node both in nodes collection and in the DOM.
 *
 * @param nodeType
 * @param parentNode
 * @returns {*}
 */
FlowChart.prototype.addNode = function(nodeType, parentNode) {
  var _t = this;
  var posLeft = 0;
  var posTop = 0;
  var node = null;
  if (!parentNode){
	posLeft = _t.rootElementPosition.left;
	posTop = _t.rootElementPosition.top;
	node = _t.addNodeWithPosition(nodeType, posLeft, posTop);
  }else{
	posLeft = parentNode.offset().left + _t.offsetForNextElement;
	posTop = parentNode.offset().top;
    node = _t.addNodeWithPosition(nodeType, posLeft, posTop);
    _t.addConnectionBetween(parentNode, node);
  }   
  return node;
}

/**
 * Deletes node both from nodes collection and DOM.
 *
 * @param nodeId
 */
FlowChart.prototype.deleteNode = function(nodeId){
  var _t = this;
  var node = _t.jQueryLibraryObj('#' + nodeId);
  var nodeObj = _t.getNodeFromNodesObject(nodeId);
  var linesRight = nodeObj.startFor;
  var linesLeft = nodeObj.endFor;   
  node.remove();
  _t.deleteNodeFromNodesObject(nodeId);
  
    for (var i = 0; i < linesRight.length; i++) {
      _t.deleteConnection(linesRight[i]);
    }

    for (var i = 0; i < linesLeft.length; i++) {
      _t.deleteConnection(linesLeft[i]);
    }
}

/**
 * Deletes connection both in connections collection and DOM.
 *
 * @param connectionId
 */
FlowChart.prototype.deleteConnection = function(connectionId){
  var conn = this.jQueryLibraryObj('#' + connectionId);
  var connObj = this.getConnectionFromConnectionsObject(connectionId);
  var startNode = this.nodes[connObj.start];
  var endNode = this.nodes[connObj.end];
  if(startNode){
    var linesRight = startNode.startFor;
    var index = linesRight.indexOf(connectionId);
    linesRight.splice(index,1);
    this.nodes[connObj.start].startFor = linesRight;
  }
  if(endNode){
    var linesLeft = endNode.endFor;
    var index = linesLeft.indexOf(connectionId);
    linesLeft.splice(index,1);
    this.nodes[connObj.end].endFor = linesLeft;
  }
  this.deleteConnectionFromConnectionsObject(connectionId);
  conn.remove();
}

/**
 * Adds connection between two nodes. And registers it to these nodes.
 *
 * @param startNode
 * @param endNode
 */
FlowChart.prototype.addConnectionBetween = function(startNode, endNode){
    var _t = this;

    // add connection line and register it to start and end nodes
    var conId = this.addConnection(startNode, endNode);

    var startpointFor = this.nodes[startNode.attr('id')].startFor;
    startpointFor.push(conId);
    this.nodes[startNode.attr('id')].startFor = startpointFor;

    var endpointFor = this.nodes[endNode.attr('id')].endFor;
    endpointFor.push(conId);
    this.nodes[endNode.attr('id')].endFor = endpointFor;

    // reposition connection lines
    _t.positionConnectionLines(startNode, true);
    _t.positionConnectionLines(endNode, true);
}

/**
 * Adds connection between two nodes without registering it to these nodes.
 *
 * @param startNode
 * @param endNode
 * @returns {string}
 */
FlowChart.prototype.addConnection = function(startNode, endNode) {
  var conLayer = this.jQueryLibraryObj('#connections-layer');
  var currentDate = new Date();
  var startNodePos = startNode.offset();
  var endNodePos = endNode.offset();
  var conCoordinates = "M" + startNodePos.left + "," + startNodePos.top + 
                       " C" + startNodePos.left + "," + startNodePos.top + 
                       " " + endNodePos.left + "," + endNodePos.top + 
                       " " + endNodePos.left + "," + endNodePos.top;
  
  var newpath = document.createElementNS("http://www.w3.org/2000/svg","path");
      newpath.setAttributeNS(null, "id", "line-" + this.nextElementIndex() );  
      newpath.setAttributeNS(null, "d", conCoordinates);
  
  conLayer[0].appendChild(newpath);
	 	 	 			 			 							 	
  this.addOrUpdateConnectionInConnectionsObject("line-" + this.elementIndex, startNode.attr('id'), endNode.attr('id'), conCoordinates);
   
  return "line-" + this.elementIndex;
}

/**
 * Adjusts layers sizes so it can pass to the layers content.
 */
FlowChart.prototype.adjustLayersSize = function() {
  this.jQueryLibraryObj('.layer').width(this.jQueryLibraryObj(document).width())
                                 .height(this.jQueryLibraryObj(document).height());
}

/**
 * Exports chart as a JSON object.
 *
 * @returns {{nodes: Array, connections: Array}}
 */
FlowChart.prototype.exportChart = function(){
	var nodes = this.nodes;
	var conns = this.connections;
	var chartJSON = {
		nodes: [],
		connections: []
	};
	
	for (var node in nodes) {
     if (nodes.hasOwnProperty(node)) {
       var nodeObj = {
		   id: node,
		   type: nodes[node].type,
		   content: nodes[node].content,
		   left: nodes[node].left,
		   top: nodes[node].top
	   }
	   chartJSON.nodes.push(nodeObj);
     }
    }
	
	for (var conn in conns) {
     if (conns.hasOwnProperty(conn)) {
       var connObj = {
		   start: conns[conn].start,
		   end: conns[conn].end
	   };
	   chartJSON.connections.push(connObj);
     }
    }
	
	return chartJSON;
}

/**
 * Imports chart as a JSON object.
 *
 * @param chartJSON {{nodes: Array, connections: Array}}
 */
FlowChart.prototype.importChart = function(chartJSON){
	var _t = this;
	var nodes = chartJSON.nodes;
	var conns = chartJSON.connections;
	for (var i = 0; i < nodes.length; i++){
		_t.addNodeWithIdContentAndPosition(nodes[i].id,
		                                  nodes[i].type, 
										  nodes[i].content, 
										  nodes[i].left, 
										  nodes[i].top);
	}
	for (var i = 0; i < conns.length; i++){
		var startNode = _t.jQueryLibraryObj('#' + conns[i].start);
		var endNode = _t.jQueryLibraryObj('#' + conns[i].end);
		_t.addConnectionBetween(startNode, endNode);
	}
}

我在html页面中绘制了一个圆圈,该圆圈来源于另一个页面上的iframe。 iframe显示除了那些不可见的圆圈之外的一切。我是否必须使用其他内容而不是iframe? flowchart.js

HTML流程图

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="Styles/style.css" rel="stylesheet" />
<script src="/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui.min.js"></script>
<link href="Styles/flowchart.css" rel="stylesheet" />
<script src="Scripts/flowchart.js"></script>   

<script>
$(document).ready(function () { 
var obj = JSON.parse($("#hdnchartJSON").val());        //get chartJSON from code-behind
var chart = null;
chart = new FlowChart($);                              //instantiate and import chartJSON to flowchart.js 
chart.nodeTemplates = {
             "simple-node": "<div></div>",
             "start-node": "<svg> width='100%' height='100%'> <circle cx='148' cy='50' r='35' stroke='black' fill='white' /> <text x='148' y='50' font-family='sans-serif' font-size='20px'text-anchor='middle' fill='Black'>Start</text></svg>",
             "end-node": "<svg> width='100%' height='100%'> <circle cx='148' cy='50' r='35' stroke='black' fill='white' /> <text x='148' y='50' font-family='sans-serif' font-size='20px'text-anchor='middle' fill='Black'>End</text></svg>"
         };

chart.importChart(obj);
        });   
</script>

</head>
<body>
 <h1 class="form-section title">Process FlowChart </h1>
<form id="form1" runat="server">
 <asp:HiddenField ID="hdnchartJSON" runat="server" />
</form>

HTML another.aspx

<div class="row-fluid">
<aside style="background-color: white;">
<iframe style="width: 100%; border: none" src="FlowChart.aspx" onload="resizeIframe(this)"></iframe>
</aside>
</div>

也试过这个

<div class="row-fluid">
<object style="width: 100%; border: none" data="FlowChart.aspx"></object>
</div>

当我直接访问flowchart.aspx时,它显示整个流程图正确,但不在iframe或对象中

enter image description here

此外,如果我删除svg圈子i-e:开始和结束节点,那么iframe显示流程图。

这是iframe或对象标签

的结果

enter image description here

2 个答案:

答案 0 :(得分:0)

而不是iframe可能会考虑使用对象标签吗?

http://prntscr.com/b7ep2w

https://svgontheweb.com/

答案 1 :(得分:0)

这不是有效的标记,你有两个&gt;对于每个&lt;

<svg> width='100%' height='100%'> 

这样的事情是需要的

<svg width='100%' height='100%'>