JointJS从磁铁创建链接不起作用

时间:2016-09-07 08:39:33

标签: javascript jointjs

我设法创建了一个包含元素,端口和多个输出端口的图表。 所有元素都使用从输入端口到输出端口的链接进行连接。

当我尝试使用我已经拥有的链接(从JSON加载)时,它可以正常工作。 出于某种原因,当我尝试通过按下端口来创建新链接时,它会拖动元素。

当我按下它们时,如何让端口创建新链接?

joint.shapes.Question = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
    markup: '<g class="rotatable">' +
        '<g class=""><g class="inPorts" /><rect class="question-wrapper" /><rect class="question-title" /><rect class="options-body" /><g class="outPorts" /></g>' +
        '<text class="question" /><g class="options" />' +
    '</g>',
    portMarkup: '<g class="port port-<%= port.type %> port-<%= port.id %>"><circle class="port-body" /><text class="port-label" /></g>',
    optionMarkup: '<g class="option-wrapper"><text class="option"/></g>',

    defaults: joint.util.deepSupplement({
        type: 'Question',

        minWidth: 200,
        optionHeight: 25,

        inPorts: [{"id": "in", "label": "IN"}],

        attrs: {
            '.': {
                magnet: false
            },
            '.question-wrapper': {
                width: 200,
                height: 95,
                fill: '#f2f2f2',
                rx: 10,
                ry: 10,
                ref: '.paper'
            },
            '.question-title': {
                height: 30,
                fill: '#ffffff',
                rx: 5,
                ry: 5,
                ref: '.question-wrapper',
                'ref-x': 5,
                'ref-y': 5,
                'ref-width': -10
            },
            '.question': {
                fill: '#000000',
                'font-size': 14,
                'y-alignment': 'middle',
                'x-alignment': 'middle',
                ref: '.question-title',
                'ref-x': .5,
                'ref-y': .5,
            },
            '.options-body': {
                height: 50,
                fill: '#ffffff',
                rx: 5,
                ry: 5,
                ref: '.question-wrapper',
                'ref-x': 5,
                'ref-y': 40,
                'ref-width': -10
            },
            '.options': {
                ref: '.options-body',
                'ref-x': 5,
                'ref-y': 5
            },
            '.option-wrapper': {
                ref: '.options'
            },
            '.option': {
                fill: '#000000',
                'font-size': 14
            },
            '.port-in': {
                ref: '.question-wrapper',
                'ref-y': 0,
                'ref-x': .5,
                magnet: true,
                type: 'in'
            },
            '.port-in .port-body': {
                r: 15,
                fill: '#75caeb',
                ref: '.port-in'
            },
            '.port-in .port-label': {
                'font-size': 10,
                fill: '#ffffff',
                'x-alignment': 'middle',
                'y-alignment': -10,
                ref: '.port-in .port-body'
            },
            '.port-out': {
                ref: '.question-wrapper',
                magnet: true,
                type: 'out'
            },
            '.port-out .port-body': {
                r: 10,
                ref: '.question-wrapper',
                'ref-dy': 15,
                'ref-x': .5,
                fill: '#158cba',
                'y-alignment': 'middle'
            },
            '.port-out .port-label': {
                'text': 'R',
                'font-size': 10,
                'y-alignment': 'middle',
                'x-alignment': 'middle',
                fill: '#ffffff',
                ref: '.port-out .port-body',
                'ref-x': .5,
                'ref-y': 15,
                'pointer-events': 'none'
            }
        }

    }, joint.shapes.basic.Generic.prototype.defaults),

    initialize: function () {
        this.attr('.question/text', this.get('question'), {silent: true});

        this.onChangePosition();
        this.onChangeOptions();
        joint.shapes.basic.PortsModelInterface.initialize.apply(this, arguments);
    },

    onChangePosition: function () {
        var timer;
        var timer_interval = 500;

        this.on('change:position', function (cellView, position) {
            clearTimeout(timer);
            timer = setTimeout(function () {
                $.ajax({
                    url: routes.questionPosition.replace(':question', cellView.id),
                    data: position,
                    method: 'post',
                    headers: {'X-CSRF-TOKEN': $('[name="csrf_token"]').attr('content')}
                });
            }, timer_interval);
        });
    },

    onChangeOptions: function () {
        var options = this.get('options');
        var size = this.get('size');
        var optionHeight = this.get('optionHeight');

        // First clean up the previously set attrs for the old options object.
        // We mark every new attribute object with the `dynamic` flag set to `true`.
        // This is how we recognize previously set attributes.
        var attrs = this.get('attrs');
        _.each(attrs, function (attrs, selector) {
            if (attrs.dynamic) {
                // Remove silently because we're going to update `attrs`
                // later in this method anyway.
                this.removeAttr(selector, {silent: true});
            }
        }, this);

        // Collect new attrs for the new options.
        var offsetY = 0;
        var attrsUpdate = {};
        _.each(options, function (option) {
            var selector = '.option-' + option.id;

            attrsUpdate[selector] = {transform: 'translate(0, ' + offsetY + ')', dynamic: true};
            attrsUpdate[selector + ' .option'] = {text: option.text, dynamic: true};

            offsetY += optionHeight;
        }, this);

        this.attr(attrsUpdate);
        this.autoresize();
    },

    autoresize: function () {
        var options = this.get('options') || [];
        var gap = this.get('paddingBottom') || 15;

        var height = options.length * this.get('optionHeight');
        var wrapperHeight = height + this.attr('.question-title/height') + gap;
        var width = joint.util.measureText(this.get('question'), {
                fontSize: this.attr('.question/font-size')
            }).width + (this.attr('.question-title/rx') * 6);

        this.attr('.options-body/height', height);
        this.resize(Math.max(this.get('minWidth'), width), wrapperHeight);
        this.attr('.question-wrapper/width', width);
        this.attr('.question-wrapper/height', wrapperHeight);
    },

    getPortAttrs: function (port, index, total, selector, type) {
        var attrs = {};

        var portSelector = selector + ' .port-' + type;

        attrs[portSelector + ' .port-label'] = {text: port.label};
        attrs[portSelector + ' .port-body'] = {
            port: {
                id: port.id,
                type: type
            }
        };

        if (selector === '.outPorts') {
            attrs[portSelector] = {'ref-x': ((total / 2) * 30 * -1) + (index * 30) + 15};
        }

        return attrs;
    }
}));

joint.shapes.QuestionView = joint.dia.ElementView.extend(_.extend({}, joint.shapes.basic.PortsViewInterface, {
    initialize: function () {
        joint.shapes.basic.PortsViewInterface.initialize.apply(this, arguments);
    },

    renderMarkup: function () {
        joint.dia.ElementView.prototype.renderMarkup.apply(this, arguments);

        // A holder for all the options.
        this.$options = this.$('.options');
        // Create an SVG element representing one option. This element will
        // be cloned in order to create more options.
        this.elOption = V(this.model.optionMarkup);

        this.renderOptions();
    },

    renderOptions: function () {
        this.$options.empty();

        _.each(this.model.get('options'), function (option, index) {
            var className = 'option-' + option.id;
            var elOption = this.elOption.clone().addClass(className);
            elOption.attr('option-id', option.id);
            this.$options.append(elOption.node);
        }, this);

        // Apply `attrs` to the newly created SVG elements.
        this.update();
    }
}));

0 个答案:

没有答案