29

I'm trying to create a webpage which using a lot of Raphael objects like lines, rectangles, circle. I'm using different colors for each of the event on these objects like onmouseover one color, onmouseout another etc.. So since I have a lot of styling I was wondering if I can specify a css class to these objects. I tried using the following code on IE, but I could not see the styling effect

rectObj.attr('class','mediumBold');

mediumBold is one the defined css class.

I'm fairly new to this. Any pointer will be helpful.

Thanks.

sgbharadwaj
  • 395
  • 2
  • 5
  • 9
  • You should provide your CSS rules. From what I can tell, Raphael outputs SVG, which you can style with CSS, but the properties are not always the same. (For example, paths in SVG use "stroke" for their outline, not "border") – Anthony Dec 23 '10 at 22:51
  • 1
    If you set the style using CSS class doesn't work on IE < 9 (because raphael use VML instead of SVG). I suggest to don't use CSS for raphael style. – Davide Icardi Jul 12 '11 at 17:06

7 Answers7

34

The way i'm doing it:

var rph = Raphael("target",100,100);

var p = rph.rect(0, 0, 12, 12, 1);

p.node.setAttribute("class","track");
CoolBeans
  • 20,654
  • 10
  • 86
  • 101
Anselmo
  • 1,519
  • 1
  • 13
  • 9
  • 8
    If you set the style using CSS class doesn't work on IE < 9 (because raphael use VML instead of SVG). I suggest to don't use CSS for raphael style. – Davide Icardi Jul 12 '11 at 17:07
  • 2
    Davide Icardi is correct. In fact, doing this in IE < 9 will cause the element to disappear. However, unlike other answers, it does work in FF and Chrome, though you'll have to contend with CSS rule precedence. If you want persistent element grouping, see http://stackoverflow.com/questions/6277129/raphael-js-how-to-use-jquery-selectors-on-objects-in-ie/6944372#6944372 – David Eads Aug 04 '11 at 19:41
10

Firstly, I did not know about this js tool. Looks awsome. Coming back to the solution, a change is needed for Raphael.js in order to make this work. I an referring to the uncompressed source file here. At line number 78 there is a property called availableAttrs which lists all the possible attributes that can be set using attr() function. change that property to include class with a default value like below:

availableAttrs = {
    blur: 0, 
   "clip-rect": "0 0 1e9 1e9", 
    cursor: "default", 
    cx: 0, 
    cy: 0,
    fill: "#fff", 
   "fill-opacity": 1, 
    font: '10px "Arial"', 
   "font-family": '"Arial"', 
   "font-size": "10", 
   "font-style": "normal", 
   "font-weight": 400, 
    gradient: 0, 
    height: 0, 
    href: "http://raphaeljs.com/", 
    opacity: 1, 
    path: "M0,0", 
    r: 0, 
    rotation: 0, 
    rx: 0, 
    ry: 0, 
    scale: "1 1", 
    src: "", 
    stroke: "#000", 
   "stroke-dasharray": "", 
   "stroke-linecap": "butt", 
   "stroke-linejoin": "butt", 
   "stroke-miterlimit": 0, 
   "stroke-opacity": 1, 
   "stroke-width": 1, 
    target: "_blank", 
   "text-anchor": "middle", 
    title: "Raphael", 
    translation: "0 0", 
    width: 0, 
    x: 0, 
    y: 0, 
    class:""

},

Once this change is done class attributes can be assigned using attr function.

P.S: Please check the licensing terms before changing the script and using it.

zessx
  • 68,042
  • 28
  • 135
  • 158
Chandu
  • 81,493
  • 19
  • 133
  • 134
  • Thanks Cybernate. But I wonder after specifying 'class' in the available attributes will the actual style properties will be applied to the object. Will try that. – sgbharadwaj Dec 24 '10 at 00:19
  • They would as long as they are SVG css attributes. Check this link http://www.w3.org/TR/SVG/styling.html – Chandu Dec 24 '10 at 00:31
  • Does it work in IE all versions if we add `class:""` to availableAttrs property? – kittu Jul 04 '15 at 18:05
  • This worked perfectly! Not tested with lower versions of IE, but luckily we don't have a need for those. Thanks so much! – Rockster160 Dec 16 '15 at 04:59
  • @Rockster160 Thanks, I would however recommend trying the solution provided by Anselmo as it doesn't involve changing the source code of the library. – Chandu Dec 16 '15 at 14:23
  • You don't have to edit the source. You can add the following line to any JS file that depends on Raphael: `Raphael._availableAttrs["class"] = "";` – Agi Hammerthief Jun 20 '19 at 15:35
7

Why don't you simply add the "addClass" method to all Element instances?

Like this:

Raphael.el.addClass = function(className) {
    this.node.setAttribute("class", className);
    return this;
};

Then, you can do:

rectObj.addClass('mediumBold');
fabiangebert
  • 2,623
  • 2
  • 22
  • 25
5

I've run into the same problem - I wanted more specifically to be able to assign a CSS class to the SVG object created by Raphael. This is the way I made it:

paper= Raphael("thePaperObj", 200, 10); //create a Raphael Obj
paper.canvas.className.baseVal="stretchBar";

the result is that I get a rendered SVG element like this:

<svg class="stretchBar" style="overflow: hidden; position: relative;" width="200" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">

Of course, the class can be defined to contain the desired CSS attributes in a stylesheet.

Hope this can help someone in the future.

eddo
  • 2,094
  • 1
  • 25
  • 31
5

I used

$(rectObj.node).attr("class", "mediumBold");
Maxim
  • 51
  • 1
  • 2
  • this worked for me. Note that the class needs to contain SVG styles, for example `fill: red` and not `background-color: red` – ps0604 Jul 14 '16 at 12:22
5

Raphael's attr is different to jQuery's attr as it's designed for SVG specifically. I wouldn't mess about with this and use the different libraries for their different purposes. To use rectObj with jQuery, you have to get the actual DOM element via rectObj.node:

$(rectObj.node).addClass("mediumBold");

If you're not using jQuery, you can do:

rectObj.node.className += " mediumBold";
David Tang
  • 92,262
  • 30
  • 167
  • 149
  • As Davide Icardi says below, this will not work in IE < 9. However, unlike the answer that uses setAttribute, this technique doesn't work reliably in Chrome or FF, either (presumably Safari and others have similar problems). – David Eads Aug 04 '11 at 19:38
  • 5
    Neither of these work at all; why is this upvoted at all? "class" is an animated property in SVG and must be treated differently from typical properties of the DOM. – M. Anthony Aiello Apr 16 '12 at 16:15
  • If a quick-and-dirty hack is acceptable, you can `element.className.baseVal += " new_class"; element.className.animVal += " new_class";` This works on FF, WebKit, and IE9. If you're using jQuery, a better way would likely be to use the [SVG plugin for jQuery](http://keith-wood.name/svg.html) – M. Anthony Aiello Apr 16 '12 at 17:51
2

In case anyone else stumbles across this there is a reason Raphael is lacking the ability to set some SVG specific things and that is because it is a tool for creating vector graphics that has a subset of operations that is the common ground between SVG and VML. Extending it with SVG specifics is rather pointless as when VML is used you will lose that functionality. And vice versa of course, there may well be VML things that it doesn't do because SVG does not support that particular feature.