将数据传递给D3函数 - Ext JS 4.2.2

时间:2015-04-24 02:56:27

标签: javascript extjs d3.js

我试图在Ext JS 4.2应用程序中使用D3实现类似的东西。

http://bl.ocks.org/mbostock/1153292

在D3中,' path.attr(" d",linkArc);',调用linkArc函数并将数据传递给linkArc函数。这在D3世界中运行良好。



function tick() {
  path.attr("d", linkArc);
  circle.attr("transform", transform);
  text.attr("transform", transform);
}

function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = Math.sqrt(dx * dx + dy * dy);
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}




但是,我试图在Ext JS中使用它(D3 JS在afterRender()函数中加载) -



(function() {
	
Ext.define("d3.widgets.D3Widgets", {
    extend: 'Ext.Component',
    alias: 'widget.d3_workflow',
    width: 800,
    height: 400,	
	circle : '',
	text : '',
    constructor: function(config) {
      ...
    },

    
    initComponent : function() {
    	...
    },

    afterRender: function() {
        this.loadScript(this.onD3Loaded, this);
        return this.callParent(arguments);
    },

	loadScript: function(callback, scope) {
		Ext.Loader.injectScriptElement('http://d3js.org/d3.v3.js', this.onLoad, this.onError, this);
		
    },

    onError : function() {
		console.log('On Error');
	},
	
	onLoad : function() {

		var nodes = {};
		
		var links = [
		  {source: "Initiate", target: "Department Approver Approves", type: "licensing"},
		  {source: "Department Approver Approves", target: "Division Approver Approves", type: "licensing"},
		  {source: "Division Approver Approves", target: "End", type: "suit"}
		];

		links.forEach(function(link) {
		  link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
		  link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
		});

		var width = 960,
			height = 500;
			
		var path = '';	

		var force = d3.layout.force()
			.nodes(d3.values(nodes))
			.links(links)
			.size([width, height])
			.linkDistance(60)
			.charge(-300)
			.on("tick", this.tick(path))
			.start();

		var svg = d3.select("body").append("svg")
			.attr("width", width)
			.attr("height", height);

		// Per-type markers, as they don't inherit styles.
		svg.append("defs").selectAll("marker")
			.data(["suit", "licensing", "resolved"])
		  .enter().append("marker")
			.attr("id", function(d) { return d; })
			.attr("viewBox", "0 -5 10 10")
			.attr("refX", 15)
			.attr("refY", -1.5)
			.attr("markerWidth", 6)
			.attr("markerHeight", 6)
			.attr("orient", "auto")
		  .append("path")
			.attr("d", "M0,-5L10,0L0,5");

		var path = svg.append("g").selectAll("path")
			.data(force.links())
		  .enter().append("path")
			.attr("class", function(d) { return "link " + d.type; })
			.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });

		circle = svg.append("g").selectAll("circle")
			.data(force.nodes())
		  .enter().append("circle")
			.attr("r", 6)
			.call(force.drag);

		text = svg.append("g").selectAll("text")
			.data(force.nodes())
		  .enter().append("text")
			.attr("x", 8)
			.attr("y", ".31em")
			.text(function(d) { return d.name; });

  
	},
	
	
    onRender :function(ct, position) {    	
        this.callParent(arguments);
    },

    	// Use elliptical arc path segments to doubly-encode directionality.
	tick: function(path)  {
	  console.log('Inside Tick --');
	  path.attr("d", linkArc);
	  circle.attr("transform", transform);
	  text.attr("transform", transform);
	},

	linkArc: function(d) {
	  var dx = d.target.x - d.source.x,
		  dy = d.target.y - d.source.y,
		  dr = Math.sqrt(dx * dx + dy * dy);
	  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
	},

	transform: function(d) {
	  return "translate(" + d.x + "," + d.y + ")";
	}

});

})();




在tick函数中,使用

调用linkArc函数

path.attr(" d",linkArc);

和linkArc函数定义为

linkArc:function(d){ }

在Ext JS中,运行此命令时,我在浏览器控制台中收到以下错误 -

未捕获的ReferenceError:未定义linkArc

似乎这种情况正在发生,因为linkArc正在期待数据,而这个数据没有通过。

在Ext JS中是否应该以不同方式调用此函数?

谢谢

2 个答案:

答案 0 :(得分:1)

由于linkArc函数范围内未定义tick,导致错误。要么必须在tick函数中定义该函数,要么使用它,如下面的代码所示。

解决方案1:

tick: function(path)  {
      var widget = this;
      console.log('Inside Tick --');
      path.attr("d", widget.linkArc);
      circle.attr("transform", widget.transform);
      text.attr("transform", widget.transform);
}

解决方案2:

tick: function(path)  {
      function linkArc(d) {
           var dx = d.target.x - d.source.x,
           dy = d.target.y - d.source.y,
           dr = Math.sqrt(dx * dx + dy * dy);
           return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
      };
      function transform(d) {
          return "translate(" + d.x + "," + d.y + ")";
      } 
      console.log('Inside Tick --');
      path.attr("d", linkArc);
      circle.attr("transform", transform);
      text.attr("transform", transform);
}

答案 1 :(得分:1)

像Gilsha说的那样,这是范围的问题。但是你还必须添加正确的transform指针,因为它不会给你一个错误,但它不会正常工作。

以下是我使用的代码和小提琴:https://fiddle.sencha.com/#fiddle/lr6

Ext.application({
        name: 'Fiddle',

        launch: function() {
            Ext.create('Ext.window.Window', {
                width: 900,
                height: 500,
                itemId : 'd3TestWindow',
                title: 'Custom D3',
                listeners: {
                    afterrender: function(window) {
                        var nodes = {};
                        links.forEach(function(link) {
                            link.source = nodes[link.source] || (nodes[link.source] = {
                                name: link.source
                            });
                            link.target = nodes[link.target] || (nodes[link.target] = {
                                name: link.target
                            });
                        });

                        window.force = d3.layout.force().nodes(d3.values(nodes)).links(links).size([window.getWidth(), window.getHeight()]).linkDistance(60).charge(-300).on("tick", window.tick).start();

                        window.svg = d3.select("#" + window.id + "-innerCt").append("svg").attr("width", window.getWidth()).attr("height", window.getHeight());
                        window.appendPath();
                        window.appendCircle();
                        window.appendText();

                        // Per-type markers, as they don't inherit styles.
                        window.svg.append("defs").selectAll("marker").data(["suit", "licensing", "resolved"]).enter().append("marker").attr("id", function(d) {
                            return d;
                        }).attr("viewBox", "0 -5 10 10").attr("refX", 15).attr("refY", - 1.5).attr("markerWidth", 6).attr("markerHeight", 6).attr("orient", "auto").append("path").attr("d", "M0,-5L10,0L0,5");



                    }
                },
                appendPath : function () {
                    var me = this;
                    this.path = this.svg.append("g").selectAll("path").data(me.force.links()).enter().append("path").attr("class", function(d) {
                        return "link " + d.type;
                    }).attr("marker-end", function(d) {
                        return "url(#" + d.type + ")";
                    });
                },
                appendCircle: function() {
                    var me = this;
                    this.circle = this.svg.append("g").selectAll("circle").data(me.force.nodes()).enter().append("circle").attr("r", 6).call(me.force.drag);
                },
                appendText: function() {
                    var me = this;
                    this.text = this.svg.append("g").selectAll("text").data(me.force.nodes()).enter().append("text").attr("x", 8).attr("y", ".31em").text(function(d) {
                        return d.name;
                    });
                },
                transform: function(d) {
                    return "translate(" + d.x + "," + d.y + ")";
                },
                linkArc: function(d) {
                    var dx = d.target.x - d.source.x,
                        dy = d.target.y - d.source.y,
                        dr = Math.sqrt(dx * dx + dy * dy);
                    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
                },
                tick :  function() {
                    var window = Ext.ComponentQuery.query('#d3TestWindow')[0];
                    window.path.attr("d", window.linkArc);
                    window.circle.attr("transform", window.transform);
                    window.text.attr("transform", window.transform);
                }
            }).show();
        }
    });