clientIO / JointJS_plus

JointJS+ support
4 stars 9 forks source link

Using CSS- how to add or remove CSS class from individual SVG element #18

Closed ryang123 closed 10 years ago

ryang123 commented 10 years ago

I would like to use CSS classes to style SVG elements. I tested this for a rectangle by adding a class 'testclass' to the shape definition in the joint.js shapes (in this case a rect) and then adding simple stying in a style sheet like rect.testclass { stroke-width: 3; } and that works fine.

What I am having trouble figuring out is how to add and remove classes dynamically for each element. Either adding it to the parent g or to the rect would work. I thought it would be a combination of a jointjs function and jquery class operations, but not sure how to bridge them and am somewhat flexible as to how to get there.

As an aside, one reason I want to do this is to have a nice clean exportable JSON format without the changed styling- the styling reflects only a transient state, not something I want captured in the longer term layout properties. Also, I'm speculating that using CSS styling might have somewhat better performance when changing a large number of elements, but will have to test to verify...

ryang123 commented 10 years ago

Of course, right after I posted this, I realized that the model-id attribute of the parent g is the id of the element, the value which I already have in my function, so all I have to do is this:

$( "g[model-id=' + currentElement.id + ']" ).attr("class", "thenewclass(es)"); //Or I could get the children from here

And this does what I wanted, so I'm happy. I also learned that apparently the jquery addclass and removeclass functions don't work with SVG without a plugin, so the .attr method seems the best way to go.

DavidDurman commented 10 years ago

Hi Ryan, you're right, that's one way to get to the DOM element. JointJS actually has a facility to do that:

paper.findViewByModel(element).$el.attr('class', 'newclass');

Note that the findViewByModel() accepts both a cell or a cell ID.

The fact about jQuery add/removeClass and SVG is annoying, we agree. We might build-in something to JointJS to make life easier doing this in the future.

deevis commented 10 years ago

I'm late to the party - has anything been done to make life easier now that it's the future?

DavidDurman commented 10 years ago

Yes, Vectorizer (the JointJS internal SVG-mini library) now contains methods: addClass(), removeClass(), toggleClass() and hasClass(). See the docs: http://jointjs.com/api#v:hasClass.

Adding a class to the SVG container of a JointJS element is as easy as:

V(paper.findViewByModel(element).el).addClass('myclass')

If your element is, for example, of type 'basic.Rect', you can then in your CSS conditionally set a text-shadow (for instance) on the inside text:

.element.basic.Rect.myclass text {
     text-shadow: 1px 1px 1px black;
}
deevis commented 10 years ago

Like a charm!

+1 Karma for fast and correct response :D

Shonnalii commented 7 years ago

I want to add some css to my link and not element.It is not working this way. app.paper.findViewByModel(yeslink).attr('class', 'newclass');

kumilingus commented 7 years ago

There is no method attr() on the LinkView defined. Please access the vel property (the DOM element wrapped with Vectorizer) on the view first.

paper.findViewByModel(elementOrLink).vel.addClass('myclass');