clientIO / joint

A proven SVG-based JavaScript diagramming library powering exceptional UIs
https://jointjs.com
Mozilla Public License 2.0
4.48k stars 839 forks source link

Auto-resize UML class elements to fit text #191

Closed DontShootMe closed 6 months ago

DontShootMe commented 8 years ago

From this source code

var size = this.model.get('size') || { width: 1, height: 1 };

This seem to always send something from the model ( wich seem to be set by default to { width: 1, height: 1 }) So it will be better to test individually the width and height, no ?

var size = this.model.get('size');
size.width = size.width || 1;
size.height = size.height || 1;

Or maybe i've missed something ! ?

Calling resize without arguments from an element, set the size.width and size.height to undefined so the transform attributes is set with an incorrect format with NaN data, in the elementView resize function.

chill117 commented 8 years ago

Can you provide some sample application code that you've written that is problematic for you?

DontShootMe commented 8 years ago

here is a fiddle (click to resize , and over the first div ) with two problem : The first one is related to the bad formating of transform() attribute.

The second is about the joint.shapes.uml.Class. When you change the name, methods or attributes of the class, an update and resize of the elementView should occur. Even if this occur there is no modification visible, to have any modification you have to use the resize from the element without arguments. And here we fall in the first problem.

chill117 commented 8 years ago

It sounds like you're saying that the joint.shapes.uml.Class is not auto-resizing to fit its inner text when changing its name, methods, or attributes and that this would be the expected behavior?

Reference:

DontShootMe commented 8 years ago

yes it would be the expected behaviour. In the demo everything is fixed by code, not any auto-sizing. I can auto-resize the shapes using the ( backbone.model ) element.resize. But it was hard to track the difference with elementView.resize wich must do the job ?? ( if not, is the code source false ???) At first i was thinking about the bad formating of transform() attribute, but it seems to be another problem, not linked ??

DavidDurman commented 8 years ago

The UML shapes are not auto-sizing based on the text inside. This must be done manually. You can take advantage of the Vectorizer's bbox() method to find the bounding box of texts: http://jointjs.com/api#v:bbox. In the future, we do plan to make the UML shapes a bit more clever in this sense. If you create a better UML shape, we'd be happy if you could share it with us.

DontShootMe commented 8 years ago

@DavidDurman

The UML shapes are not auto-sizing based on the text inside

mmm... ??? are you sure ?

let me ask you : from joint.shapes.uml.Class = joint.shapes.basic.Generic.extend

we have the initialize function :

initialize: function() {

        this.on('change:name change:attributes change:methods', function() {
            this.updateRectangles();
            this.trigger('uml-update');
        }, this);

        this.updateRectangles();

        joint.shapes.basic.Generic.prototype.initialize.apply(this, arguments);
    },

We listen to the changing on name, attributes and methods then we call this.updateRectangles();

    updateRectangles: function() {

        var attrs = this.get('attrs');

        var rects = [
            { type: 'name', text: this.getClassName() },
            { type: 'attrs', text: this.get('attributes') },
            { type: 'methods', text: this.get('methods') }
        ];

        var offsetY = 0;

        _.each(rects, function(rect) {

            var lines = _.isArray(rect.text) ? rect.text : [rect.text];
            var rectHeight = lines.length * 20 + 20;

            attrs['.uml-class-' + rect.type + '-text'].text = lines.join('\n');
            attrs['.uml-class-' + rect.type + '-rect'].height = rectHeight;
            attrs['.uml-class-' + rect.type + '-rect'].transform = 'translate(0,' + offsetY + ')';

            offsetY += rectHeight;
        });
    }

and after that we trigger an event this.trigger('uml-update'); This event we found it in joint.shapes.uml.ClassView = joint.dia.ElementView.extend Precisly :

initialize: function() {

        joint.dia.ElementView.prototype.initialize.apply(this, arguments);

        this.listenTo(this.model, 'uml-update', function() {
            this.update();
            this.resize();
        });
    }

So my question is : Are you sure that is not auto-resizing ?? what this function chain are for ?

If you create a better UML shape, we'd be happy if you could share it with us

If i can have good information about how the resize work, i could certainly improve the uml shapes, and add some others. But i can't trace any part of code to found how it work (it is a hard work , lot of time). What piece of code get in touch with the resize process ?

DontShootMe commented 8 years ago

Why when i call this.resize from joint.shapes.uml.ClassView nothing happend ? But if, instead, i call this.model.resize() the shape is resized ? I thought that the model handles the size and the view render it ? So we set the size on the uml.Class and if we call resize from an instance of uml.Class in the backround we use the resize of the uml.ClassView instance attached to the model ?? is it like that ? I presume there is an event triggered calling the resize on the uml.ClassView ? But i haven't spent more time to look for what the goal of batch:start , batch:end etc ...

kumilingus commented 8 years ago

Right. Each time an Element model triggers the change:size event, the associated ElementView(s) executes the resize() method.

github-actions[bot] commented 11 months ago

This issue is stale because it has been open 60 days with no activity. Please remove stale label or comment or this will be closed in 14 days.

kumilingus commented 6 months ago

Use standard.Record shape to implement an UML Class shape as shown here.