0

Using the following Raphael SVG code I can alter the color of the text but not the text itself:

    function create_Star_Icons(){

        var container = Raphael(feedback_Icons, 500, 70);
        var star_Icons = container.set();

        star_Icons.push(
            container.text(60,32,"Punctuality"),
            container.path("M28.631,12.359c-0.268-0.826-1.036-1.382-1.903-1.382h-0.015l-7.15,0.056l-2.155-6.816c-0.262-0.831-1.035-1.397-1.906-1.397s-1.645,0.566-1.906,1.397l-2.157,6.816l-7.15-0.056H4.273c-0.868,0-1.636,0.556-1.904,1.382c-0.27,0.831,0.029,1.737,0.74,2.246l5.815,4.158l-2.26,6.783c-0.276,0.828,0.017,1.739,0.723,2.25c0.351,0.256,0.763,0.384,1.175,0.384c0.418,0,0.834-0.132,1.189-0.392l5.751-4.247l5.751,4.247c0.354,0.26,0.771,0.392,1.189,0.392c0.412,0,0.826-0.128,1.177-0.384c0.704-0.513,0.997-1.424,0.721-2.25l-2.263-6.783l5.815-4.158C28.603,14.097,28.901,13.19,28.631,12.359zM19.712,17.996l2.729,8.184l-6.94-5.125L8.56,26.18l2.729-8.184l-7.019-5.018l8.627,0.066L15.5,4.82l2.603,8.225l8.627-0.066L19.712,17.996z"),
            container.text(17,18,"7"),
            container.text(210,32,"Intensity"),
            container.path("M28.631,12.359c-0.268-0.826-1.036-1.382-1.903-1.382h-0.015l-7.15,0.056l-2.155-6.816c-0.262-0.831-1.035-1.397-1.906-1.397s-1.645,0.566-1.906,1.397l-2.157,6.816l-7.15-0.056H4.273c-0.868,0-1.636,0.556-1.904,1.382c-0.27,0.831,0.029,1.737,0.74,2.246l5.815,4.158l-2.26,6.783c-0.276,0.828,0.017,1.739,0.723,2.25c0.351,0.256,0.763,0.384,1.175,0.384c0.418,0,0.834-0.132,1.189-0.392l5.751-4.247l5.751,4.247c0.354,0.26,0.771,0.392,1.189,0.392c0.412,0,0.826-0.128,1.177-0.384c0.704-0.513,0.997-1.424,0.721-2.25l-2.263-6.783l5.815-4.158C28.603,14.097,28.901,13.19,28.631,12.359zM19.712,17.996l2.729,8.184l-6.94-5.125L8.56,26.18l2.729-8.184l-7.019-5.018l8.627,0.066L15.5,4.82l2.603,8.225l8.627-0.066L19.712,17.996z"),
            container.text(17,18,"7"),
            container.text(380,32,"Enjoyment"),
            container.path("M28.631,12.359c-0.268-0.826-1.036-1.382-1.903-1.382h-0.015l-7.15,0.056l-2.155-6.816c-0.262-0.831-1.035-1.397-1.906-1.397s-1.645,0.566-1.906,1.397l-2.157,6.816l-7.15-0.056H4.273c-0.868,0-1.636,0.556-1.904,1.382c-0.27,0.831,0.029,1.737,0.74,2.246l5.815,4.158l-2.26,6.783c-0.276,0.828,0.017,1.739,0.723,2.25c0.351,0.256,0.763,0.384,1.175,0.384c0.418,0,0.834-0.132,1.189-0.392l5.751-4.247l5.751,4.247c0.354,0.26,0.771,0.392,1.189,0.392c0.412,0,0.826-0.128,1.177-0.384c0.704-0.513,0.997-1.424,0.721-2.25l-2.263-6.783l5.815-4.158C28.603,14.097,28.901,13.19,28.631,12.359zM19.712,17.996l2.729,8.184l-6.94-5.125L8.56,26.18l2.729-8.184l-7.019-5.018l8.627,0.066L15.5,4.82l2.603,8.225l8.627-0.066L19.712,17.996z"),
            container.text(17,18,"7")
        );

        // formatting

        star_Icons[0].attr({"font-family": "Calibri, Arial, sans-serif","font-size": 18,"font-weight":"bold",fill: "#808080"}); // label                
        star_Icons[1].attr({fill: "#b2b2b2", stroke: "none"});                                                                  // star
        star_Icons[2].attr({"font-family": "Arial Black, sans-serif","font-size": 12,"font-weight":"bold",fill: "#ff0000"});    // number               
        star_Icons[3].attr({"font-family": "Calibri, Arial, sans-serif","font-size": 18,"font-weight":"bold",fill: "#808080"}); // label
        star_Icons[4].attr({fill: "#b2b2b2", stroke: "none"});                                                                  // star
        star_Icons[5].attr({"font-family": "Arial Black, sans-serif","font-size": 12,"font-weight":"bold",fill: "#ff0000"});    // number
        star_Icons[6].attr({"font-family": "Calibri, Arial, sans-serif","font-size": 18,"font-weight":"bold",fill: "#808080"}); // label
        star_Icons[7].attr({fill: "#b2b2b2", stroke: "none"});                                                                  // star
        star_Icons[8].attr({"font-family": "Arial Black, sans-serif","font-size": 12,"font-weight":"bold",fill: "#ff0000"});    // number

        // positioning

        star_Icons[0].transform("t0,0");          // label
        star_Icons[1].transform("t120,20s1.75");  // star
        star_Icons[2].transform("t120,20s1.75");  // number
        star_Icons[3].transform("t0,0");          // label
        star_Icons[4].transform("t280,20s1.75");  // star
        star_Icons[5].transform("t280,20s1.75");  // number
        star_Icons[6].transform("t0,0");          // label
        star_Icons[7].transform("t440,20s1.75");  // star
        star_Icons[8].transform("t440,20s1.75");  // number

        // id's and classess

        star_Icons[1].node.setAttribute("class", "punctuality_Star");
        star_Icons[2].node.setAttribute("class", "punctuality_Num");                
        star_Icons[4].node.setAttribute("class", "intensity_Star"); 
        star_Icons[5].node.setAttribute("class", "intensity_Num");  
        star_Icons[7].node.setAttribute("class", "enjoyment_Star"); 
        star_Icons[8].node.setAttribute("class", "enjoyment_Num");  

    } // create_Star_Icons

The following jquery is being used:

                $(".punctuality_Num").attr("fill","#00ffff");   
                $(".punctuality_Num").attr("text","1");

Any ideas why this won't update? Wondering if it is because it is in a set and whether this means that the text element needs to be accessed differently.

EDIT - Important

I forgot to say that the text as seen in the HTML viewer on Firefox DOES change. But what you see DOES NOT CHANGE

codepuppy
  • 1,130
  • 2
  • 15
  • 25
  • Are you sure you do no need to use `$(".punctuality_Num").text("1");` instead? – Bram Vanroy Dec 28 '12 at 15:40
  • @BramVanroy OK that changes both the viewable and html text ....But it also wipes out the positioning, just looking to see if I can fix that. May move the positioning to a transform. – codepuppy Dec 28 '12 at 15:52
  • I think you are wrongly mixing up Raphäel and jQuery, you should stick using Raphäel all the way though – Alexander Dec 28 '12 at 15:54
  • I think you are wrongly mixing up Raphäel and jQuery, you should stick using Raphäel all the way through – Alexander Dec 28 '12 at 16:03
  • @Alexander But the update is driven external to the SVG could you point the way to incorporating Raphael code in a script other than that in which the SVG is defined? I have use jquery with Raphael SVG elsewhere. – codepuppy Dec 28 '12 at 16:10
  • @BramVanroy what is actually happening using the .text("1") syntax is that the tspan gets replaced and that alters the positioning. Just looking at fixing that. – codepuppy Dec 28 '12 at 16:12
  • @BramVanroy ok the answer is $(".punctuality_Num tspan").text("1"); – codepuppy Dec 28 '12 at 16:19
  • @codepuppy, I posted an answer showing this – Alexander Dec 28 '12 at 17:22

3 Answers3

3

You should stick using Raphäel.

For instance,

  • You can modify your function create_Star_Icons to return the array star_Icons.

    function create_Star_Icons(){
      ...
      return star_Icons;
    }
    
  • Save a reference of the returned array in your code.

    var star_Icons = create_Star_Icons();
    
  • Use it to modify the elements.

    $("selector").click(function(){
      star_Icons[2].attr("text", "1");
    });
    

Furthermore, you can refactor your code to make it play nicer.

function create_Star_Icons(){
  var container = Raphael(feedback_Icons, 500, 70);
  var star_Icons = {};

  star_Icons.Punctuality = {
    label: container.text(60,32,"Punctuality"),
    star: container.path("..."),
    number: container.text(17,18,"7")
  };

  ...

  return star_Icons;
}

var star_Icons = create_Star_Icons();

$("selector").click(function(){
  star_Icons.Punctuality.number.attr("text", "1");
});

See the refactored code running here.

Alexander
  • 23,432
  • 11
  • 63
  • 73
  • @Alexander - OK that makes a lot of sense I can see that my mixed approach is not desirable. I had been planning to have the SVG and controlling script separate thinking of reuseability but the returned array works great. Hopefully I am not misunderstanding the refactored code but I note that you are not using sets which from my reading I had concluded was the preferred approach - does this imply that sets are bad practice / inefficient? – codepuppy Dec 29 '12 at 19:21
  • @codepuppy, I dropped the `set()` because you wasn't using it at all – Alexander Dec 29 '12 at 19:24
  • @Alexander apologies for taking up your time but I am suddenly a bit lost. So just thinking out aloud - originally I was applying attributes across the set, but latterly applied them per element, so agreed not using the set function anymore. In the refactored code you are treating star_Icons as an object rather than a set. The object syntax is better practice and more efficient where applying attributes across a set is not needed and indeed you could apply attributes across the object if rqd. Is this correct? – codepuppy Dec 30 '12 at 12:38
  • @codepuppy, that's fine. But more than efficiency it is about sanity – Alexander Dec 30 '12 at 13:05
2

Using Raphael to define text and jQuery to edit attributes of SVG sounds like the worst of both worlds...

To set the text using Raphael is really easy:

star_Icons[2].attr("text",1);

jsfiddle example

Raphael text is hairy. In particular, it tends to go nuts in Internet Explorer. Also, plenty of browsers don't interpret SVG text well - e.g. it's often not selectable, not great for accessibility, etc. If possible, it's a good idea to create and control text as regular divs and use jQuery to style them and line them up with your Raphael elements.

And jQuery's SVG support isn't great. It only started supporting SVG at all quite recently. Raphael, however, is designed for the purpose.


Also, it's worth remembering that Raphael isn't like jQuery - there isn't a quick, easy way to look up your Raphael objects. When you create a Raphael object, you need to file it carefully, and you need to plan in advance how to organise your Raphael objects so you can get at them when you need them.

In your case, each one has a name, and they're all related, so why not organise them into an object keyed by name? Have an object with a punctuality key, an intensity key, etc... with text, star, label keys in each one, and loop through the object and put everything into the appropriate sets. Then you can look up each object more easily by name.

You'll need to make sure the object is in a scope where everything that works with it can see it. Here's an example of someone with a similar problem.

Community
  • 1
  • 1
user56reinstatemonica8
  • 32,576
  • 21
  • 101
  • 125
0

The text value is stored in a separate tag <tspan dy="4.5">0</tspan> which is inside the <text> tag

<text .... ><tspan dy="4.5">0</tspan></text>

Following various posts on SO and elsewhere the suggested syntax is

 $(".punctuality_Num").attr("text","1");

But all this does is add the attribute text="1" to the tag <text> so has nil effect on the displayed value in the <tspan> tag.

 $(".punctuality_Num").text("1");

is obviously destructive wiping out the <tspan> which does indeed make the correct value display but messes up the formatting.

So

 $(".punctuality_Num tspan").text("1");

updates the displayed value and retains the formatting.

codepuppy
  • 1,130
  • 2
  • 15
  • 25
  • That may work in this case, but it's not generalisable. For example, if you create a Raphael text element with multiple lines like this: `paper.text(20,20,"This has \n two lines");`, Raphael will create a text element with two tspan elements, one for each line. Your jQuery code would change both of them to be 1. – user56reinstatemonica8 Dec 28 '12 at 17:33
  • @user568458 Yes ok I can see this now and having worked through Alexander's solution I can see the error of my ways. – codepuppy Dec 29 '12 at 19:24