I have dynamically generated SVG, and I need to find the current coordinates of one of the elements. According to the SVG documentation, this can be done with the getCMT() function. I have not been able to get this to work in JavaScript. Here is an example code fragment:
thing = document.getElementById("#bx" + myState.myId);
matrix = thing.getCTM();
I correctly select the SVG element, which is a 'g' element, so it has a transform matrix. When I try to get the matrix, it returns a 'null'. This is a simple task, so it is very puzzling that it does not work. I've spent some time looking for examples, but they all seem to use static SVG directly loaded in HTML. What am I missing?
I've also tried this with getBBox() and had the same result. I'm using the current FireFox release.
I found out what the problem was. I was using getElementById in conjunction with the visibility attribute. I was setting visibility to hidden in the root of the SVG structure, and then setting the visibility attribute to visible in a nested g element. The getElementById function returns null when intermediate nodes are not displayed. Calling getElementbyId before changing the visibility made things work.
Here is a reference to where I found this out: https://bugzilla.mozilla.org/show_bug.cgi?id=756985
The specifics have to do with whether the SVG is attached or not. If it is not attached then everything must be visible. If it is attached then it is possible to use hidden/visible.
Thanks to those who responded. In FireFox, it didn't make any difference if there was a "#" at the start of the getElementId argument, but it's good to know the correct syntax. Thanks.
Related
How do you tell if one element is above another (like after all the z indexes are calculated) with the results from querySelectorAll.
Don't think there is an easy solution, as in there is a browser API you could call and get element "z-height".
You could approach this problem similarly to how rendering engine is working, which stacking elements one on top of the other based on DOM tree depth. Then there is also CSS engine, which changes element positions based on tag types and special rules from CSS, such as z-index, special position properties (relative, absolute, etc.) and even CSS "quirks", for example z-index + opacity changes how elements are stacked.
Based on your goal, you could simplify the parsing and ignore what CSS is doing and only take HTML in consideration. There you have DOM API, which makes traversing the tree structure super easy and the DOM rendering engine will handle all the weird cases of wrong-but-still-working markup.
If you can use jQuery, check
$(element).css("z-index");
I've been trying to change the width of a single column in a bar chart created using Highcharts. Here is a codepen.
In all the search that I did, I could only find two solutions given in this question.
The problem with that is that since they are set dinamically after initialization, any action that calls the redraw method will revert their width to the calculated one.
Also, I don't understand why they are using series[0].data[5].graphic.attr('width') and how it affects, since I don't see such property in the object (console screenshot)
Finally, in the codepen I'm also changing the color of the same point, but doing it in the initialization function. I wonder if there is a way to do the same for the width.
Am I missing something? Because I didn't find anything in the API docs and I'm clueless as to how these solutions actually work if there is no such property in the object.
Short explanation:
attr method is inherited from Element class. You can see that method in prototype (in console click __proto__). Method attr works in two ways: attr(property_name) is a getter (to get e.g. width) and attr({ property_name: value }) is a setter (to set e.g. width). If you use source files (.src.js), then you would notice that SVGElement class.
width will change on any redraw event, because it is recalculated again (like updating point, or resizing window). In fact you can use chart.events.redraw and there change width. In fact, I would use both, chart.events.redraw and chart.events.load with one function, to update widths.
And to explain, why you can't set width in point, like you did with color: there is not such option on point level, like pointWidth. You can set specific width for all points within one series only (using mentioned pointWidth). There is an idea for Highcharts, to add such feature (to the core or as a plugin). Feel free to vote for it on the UserVoice. Here is interesting example: http://jsfiddle.net/75oucp3b/14/ (works with v4.1.8)
I am using d3 to make a chart with multiple paths. I am displaying the path(s) description on the left hand side. The data & descriptions are dynamic so the size of the legend is naturally also dynamic, since it is not a big deal as long as I know the size of the text (just a minor adjustment to the domain/range). The problem is that I do not see an easy way to find the size of the text element in Firefox browsers.
Previously I was doing it with jquery's .width() but the clientWidth on the element is zero which seems to cause a NaNpx to be returned.
...
.on("click", function(){
alert( $(this).width() ); // NaNpx
})
...
DEMO: Click on the words.
While writing up this question I found the solution (but still going to post it because I spent a very long time searching before finding it deep in a code example). Might be just because I am brand new to d3 and svg this month but there is a getBBox() method on the text element (most elements) that will generate an object with the width/height/x/y (and it really should be used instead of jquery for all svg dimensions).
Hope posting this will help anyone else who runs into this problem because it did not seem very visible to me.
DEMO
And in the example the ~~ is a flip-bit-operator, twice will actually work like a Math.floor() but will likely be faster in all browsers then .floor().
Got the same problem. Seems like there is a bug in firefox (45.0) that <text> elements width inside SVG is always 0.
I overcame the bug by using a <tspan> element (inside the <text> element), and seems like the <tspan> has the correct width of text.
Hope it helps.
I'm trying to figure out how to highlight a line (series) in Highcharts from an element that's not related to the Chart object in any way.
I went through the documentation, and don't really see a way of achieving this. I can get into the series elements using the series.get(id).
Seems like there are no methods that can be helpful - http://www.highcharts.com/ref/#series-object
Any ideas if that's even possible?
After a lot of digging and testing, I've managed to get this working - still not sure if this is the best way (probably not).
Chart.series.get(someId).graph.attr('stroke-width', '5')
Unfortunately, this is just getting into the actual DOM element and changing the value of the property of a single element, so if you need to change the stroke width, and the styles of the markers on this line, you'd have to loop through all elements, and apply changes manually.
UPDATE: Ok, there's a better way
But this is using the private API, so if the library changes thins, your code will not work:
Chart.series.get(someId).onMouseOver() and Chart.series.get(someId).onMouseOut().
This actually fires the defined hover-state.
All of the examples on jQuery SVG's website seem to be geared toward building an SVG object in javascript and building new elements within it. It doesn't talk much about manipulating existing markup.
PROBLEM:
I have an existing SVG object with events wired up to javascript functions. I want to take the event target (in this case, an SVG Path element) and .animate() it using jQuery SVG.
However, simply $(myElement).animate() doesn't seem to work. The issue at hand seems to be that $(myElement) doesn't accept SVG objet arguments, or something.
Oddly the animate completion callback seems to work, but NO animation type I try to do with it works at all.
I'm not convinced it's properly recognizing the event target as an SVG <path>.
Even directly manipulating the attributes of the path don't seem to work (using .attr())
I know factually that myElement is a valid SVG path because if I use basic JS DOM techniques like changing the class with .setAttribute(), it works fine.
Probably this one could help you out: http://keith-wood.name/svgRef.html#support
Just an example taken from this page:
$(shape).animate({svgFill: 'lightblue'}, 2000);