Search code examples
javascripttextfor-loopraphaelonmousedown

Including labelPath in Raphael function for onmousedown


Raphael example of Australia map has the following script (modified to include names in text labels on top of shape paths):

        <script type="text/javascript" charset="utf-8">
        window.onload = function () {
            var R = Raphael("paper", 800, 600);
            var attr = {
                fill: "#eee",
                stroke: "#666",
                "stroke-width": 1,
                "stroke-linejoin": "round"
            };
function labelPath( pathObj, text, textattr )
{
    if ( textattr == undefined )
        textattr = { 'font-size': 11, fill: '#000', stroke: 'none', 'font-family': 'Arial,Helvetica,sans-serif', 'font-weight': 40 };

    var bbox = pathObj.getBBox();
    var textObj = pathObj.paper.text( bbox.x + bbox.width / 2, bbox.y + bbox.height / 2, text ).attr( textattr );
    return textObj;

}
            var alb = {};
        alb.cudhi = R.path("m 619.04203,203.24913 -3.9,5.4 -4.2,3.6 -8.7,5.4 -6.9,8.1 -3,2.7 -5.1,5.4 -2.7,0 -2.1,0 -6,2.7 -3,0 -3.9,-5.4 -5.7,-9 -3,-7.2 3,-5.4 0,-6.3 -8.1,-13.5 -1.8,-4.5 0,-3.6 -6.9,-5.4 -5.1,7.2 -4.8,-7.2 -6,-12.6 -3.9,-8.1 -3.9,-9 3,-8.1 0,-8.1 0,-6.3 -9,-8.1 -4.8,-8.1 -5.1,-5.4 -0.9,-6.3 -1.2,-9 -3.9,0 -8.7,-4.5 -10.8,-6.3 -5.1,-7.2 -1.8,-10.8 -1.2,-6.3 -3.9,-9 0,-9.9 -1.8,-13.5 1.8,-4.5 2.1,-3.6 4.8,0 6,-2.7 6,-2.7 4.8,7.2 9,14.4 9.9,13.5 9.6,6.3 4.2,1.8 10.8,0.9 18.6,-5.4 5.1,3.6 4.8,4.5 9.9,9.9 0.9,0.9 5.1,5.4 5.7,6.3 6.9,9.9 0,9.9 9,2.7 3,0.9 10.8,9.9 7.8,11.7 1.2,0.9 9.9,9 8.7,0.9 0.9,6.3 -0.9,10.8 -0.9,11.7 -2.1,4.5 -3,5.4 -7.8,6.3 -1.8,7.2 0,2.7 -1.2,3.6 -0.9,4.5 -3.9,2.7 -3.9,6.3 z").data('id', 'alb["cudhi"]').attr(attr);
        alb.kruje = R.path("m 447.14203,127.64913 -4.8,-9.9 -6,-6.3 -3.9,-6.3 -3.9,-5.4 -6,-6.3 -3.9,-7.2 -1.8,-9 -5.1,-9 -3,-9.9 3,-2.7 6,0 10.8,2.7 3.9,0 6,0 9.9,-5.4 9.9,-4.5 11.7,-5.4 3.9,9 1.2,6.3 1.8,10.8 5.1,7.2 10.8,6.3 8.7,4.5 3.9,0 1.2,9 0.9,6.3 5.1,5.4 4.8,8.1 9,8.1 0,6.3 0,8.1 -3,8.1 3.9,9 3.9,8.1 6,12.6 4.8,7.2 -6.9,4.5 -7.8,6.3 -9,7.2 -3.9,6.3 -3.9,4.5 -3.9,7.2 -2.1,-3.6 -3,-4.5 -5.7,-0.9 -6,0 0,-12.6 4.8,1.8 3,-0.9 0.9,-3.6 -2.7,-9.9 -2.1,-5.4 -3,-3.6 -10.8,-4.5 -9,-6.3 -4.8,-5.4 -9.9,-6.3 -3.9,-8.1 -2.1,-9.9 -3,-8.1 z").data('id', 'alb["kruje"]').attr(attr);

labelPath( alb["cudhi"], "Cudhi" );
labelPath( alb["kruje"], "Kruje" );


            var current = null;
            for (var state in alb) {
                alb[state].color = Raphael.getColor();
                (function (st, state) {
                    st[0].style.cursor = "pointer";
                    st[0].onmousedown = function () {
                        current && alb[current].animate({fill: "#eee", stroke: "#666"}, 500) && (document.getElementById(current).style.display = "");
                        st.animate({fill: st.color, stroke: "#ccc"}, 500);
                        st.toBack();
                        R.safari();
                        document.getElementById(state).style.display = "block";
                        current = state;
                    };
                    if (state == "durres") {
                        st[0].onmousedown();
                    }
                })(alb[state], state);
            }
        };
        </script>

Now, the 'onmousedown' function works when the pointer is over the path, however, it doesn't work when mouse is over the text/labelPath.

Is there a way I can add this functionality by modifying the 'for (var state in alb)' loop to include the labelPath as well?


Solution

  • There are a number of ways of tackling this. You could make the members of your alb object be sets rather than paths, and then add the labels to those sets -- that way, both label and path would share the same click handler. Unfortunately, that would also make your path animations apply to the label as well, and so is probably not feasible.

    Alternatively, you could assign data (using Raphael's built-in Element.data method) to a specific key using the same values for items that belong together. For instance, the path AND the label would both have data 'click-group' = 'Cudhi'. Then you could use Paper.forEach to identify every element that is paired together and assign the appropriate click handler to it.

    Here's a fiddle demonstrating such a mechanism.

    I'm sure there are other ways to accomplish this as well! Using Paper.forEach and Element.data or Element.id seem like particularly promising tools to me.