質問

I'm building activity diagrams using joint.js, which extends raphael.js. It's pretty simple, here is an example. In this example, var r creates the raphael paper and attaches it to the identified div ID. c1, c2, c3 create the diagram boxes. The x.joint(y) function draws the connectors between the created objects.

var r = Raphael("activity1", 500, 500),
c1 = r.rect(40, 40, 50, 50, 10),
c2 = r.rect(140, 140, 50, 50, 10);
c3 = r.rect(240,40,50,50,10);
c1.joint(c2);
c2.joint(c3);
c1.joint(c3);

Now--what I'm wanting to do is still a little confusing for me, as someone who is still learning as I go with javascript. I could easily just continue doing what I'm doing above. However, what I want to do instead is to create a Constructor for the diagrams and then use the Constructors to populate the diagram a little more easily.

How would I go about creating function diagNode(params){properties and methods}; that would make sense here? I started down this path, but then I feel like I'm not sure what to do next with it...

//create a new constructor for diagram nodes
function diagNode(xStart,yStart,Width,Height,Corner){
    this.xStart = xStart;
    this.yStart = yStart;
    this.wide = Width;
    this.tall = Height;
    this.corner = Corner;
};
diag1 = new diagNode(300,100,100,50,10);
役に立ちましたか?

解決

I create a jsfiddle working demo here I create two simple Objects Node and Diagram:

  • Node define a state of the diagram; the constructor accept a spec literal object (spec.uid, spec.x, spec,y, etc) see comments in code
  • the Diagram constructor accept an html id selector and a optional spec object literal (spec.width and spec.height)
  • the Diagram object exspose a public API that permitt to

    • add new node to the diagram by the addState Method (see the comment in the code)
    • add an array of nodes to the diagram by the addStates Method (see the comment in the code)
    • joint two nodes by the jointState Method (see the comment in the code)
    • search a node in the Diagram by the searchState Method

CODE:

/*
** Node constructor
** crate a new Node (or state diagram)
** 
** @params {object} spec  the specification object (spec.x,spec.y,spec.width,spec.height, spec.radius
**
** @return NodeObject
*/
var Node = function(spec) {
    spec = spec || {};
    //uid usefull for search this node in a diagram
    this.uid = spec.uid || 0;
    this.x = spec.x || 0;
    this.y = spec.y || 0;
    this.width = spec.width || 0;
    this.height = spec.height || 0;
    this.radius = spec.radius || 0;
};

/*
** Diagram constructor
** 
** @params {object} selector  the paper selector 
**
** @return Diagram Object
*/
var Diagram = function(selector, spec) {
    //relay on default value if spec is undefined
    var defaultSpec = {
        width: 500,
        height: 500
    },
        dWidth = spec.width || defaultSpec.width,
        dHeight = spec.height || defaultSpec.height;

    //define the paper property
    this.paper = Raphael(selector, dWidth, dHeight);

    //define the state array; usefull for search node in diagram
    this.states = [];

};

Diagram.prototype = {
    //inefficent method to search a state by UID in array
    //TODO:optimize! 
    searchState: function(stateId) {
        var instance = this,
            i = 0,
            max = this.states.length,
            currentState, find = false,
            selectedState;

        //search the stateId params in diagram states array
        for (; i < max; i++) {
            currentState = instance.states[i];
            if (currentState.node.uid === stateId) {
                find = true;
                selectedState = currentState;
            }
        }


        //return the response object
        return selectedState;

    },

    //add single state (Node) to diagram    
    addState: function(node) {
        //create a rect shape with state param spec
        var state,
            stateShape = this.paper.rect(node.x, node.y, node.width, node.height, node.radius);

        state = {
            node : node,
            shape: stateShape
        };
        //add state to array  
        this.states.push(state);

        return this;
    },

    //add an array of states (Node) to diagram    
    addStates: function(stateArray) {
        var instance = this,
            i = 0,
            max = stateArray.length,
            currentState;
        for (; i < max; i++) {
            currentState = stateArray[i];
            instance.addState(currentState);
        }
        return this;
    },

    //join two states
    jointState: function(sourceState, destinationState) {
        var source = this.searchState(sourceState.uid),
            dest = this.searchState(destinationState.uid);


        //joint only if all the states passed to the function, already exist in the diagram    
        if (source && dest) {
            source.shape.joint(dest.shape);
        }
        return this;
    }
};


//code
// define nodes (or states)
var c1 = new Node({
    uid: 1,
    x: 50,
    y: 40,
    width: 50,
    height: 50,
    radius: 10
}),
    c2 = new Node({
        uid: 2,
        x: 150,
        y: 140,
        width: 50,
        height: 50,
        radius: 10
    }),
    c3 = new Node({
        uid: 3,
        x: 250,
        y: 50,
        width: 50,
        height: 50,
        radius: 10
    }),
    c4,
    // define an array of state to optionally pass to addStates Diagram function
    allStates = [c1, c2, c3],
    myDiag;
//create the diagram passing allStates array and settings node (state) joins
myDiag = new Diagram("activity1", 500, 500).addStates(allStates).jointState(c1, c2).jointState(c2, c3).jointState(c1, c3);

//later create anothe node
c4 = new Node({
    uid: 4,
    x: 350,
    y: 150,
    width: 50,
    height: 50,
    radius: 10
});

//add node to diagram
myDiag.addState(c4);
//join c3 to c4
myDiag.jointState(c3, c4);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top