I have an SVG text element:
<text class="countries" dy="0" dx="-339.87646027037385" font-size="22" style="fill: #1f77b4;">Afghanistan</text>
and all I want to do is to grab the "Afghanistan" text from that on a click event.
d3.select(this)...
Thanks!
You can do this by running
var text = d3.select(this).text();
If you want the click event on your svg Element:
When generating your element you can add a click event using:
.on("click", function(){
// ...
}
Does the text you want come out of your data? Then you could do something like:
.on("click", function(d){
window.alert(d.text)
}
Hope that helped.
Related
In my application I need to use the same icon in different places.
in v-card-action's button
in a SVG graphic
For the button it is as explained in vuetify documentation:
<v-card-actions>
<v-btn value="previous" color="red" >
<span class="hidden-sm-and-down">Previous</span>
<v-icon right>mdi-arrow-left-circle</v-icon>
</v-btn>
</v-card-actions>
But now, how to use the exact same icon (using it's name) in a custom SVG
<svg viewBox="0 0 100 100">
<rec x="0" y="0" width="100" height="100" stroke="grey" />
<???> mdi-arrow-left-circle </???>
</svg>
First, do i need to use SVG <img>, <text> or <path> primitive ?
Second, how do i get the proper icon from it's name mdi-arrow-left-circle ?
I had the exact same question. This link came in handy when putting this together:
How do I include a font awesome icon in my svg?
Disclaimer: I'm using TS components in Vue and have added Vuetify.
in the template I have a SVG:
<svg>
<text
x="100"
y="100"
class="licon"
fill="red">
{{ content('mdi-close') }}
</text>
</svg>
The content method does this:
content(cls: string): string {
// this copies the content from the pseudo element :before as it's needed to show the icon from material design
const ele = document.querySelector('.' + cls);
if(ele) {
const styles = window.getComputedStyle(ele, ':before');
return styles.content.replaceAll('"', "");
}
return '';
}
The last piece needed was to make sure to use the correct font (include in your stylesheet/etc):
.licon {
font: bold 300px 'Material Design Icons';
}
Hopefully this helps someone else.
I have the following SVG code. To scale the circle only, I have to scale the container. I can't scale the circle inside the SVG.
I can access the circle element, but why can't I like other html elements? Is the code scaling the circle or the container?
<html>
<head>
<script>
function scale() {
document.getElementById('container').setAttribute('currentScale', 1.5);
}
</script>
</head>
<body>
<svg height="150" width="150" id="container">
<circle cx="25" r="20" cy="20" fill="blue" id="circle"></circle>
</svg>
<button id="zoom" onclick="scale()">scale</button>
</body>
</html>
I've never tried scaling the whole SVG (using the pure SVG transform attribute). But look like you can just scale each element inside SVG. In this case you have to target (select) the circle first before calling setAttribute on it to modify the transform attribute to scale(1.5,1.5) like this:
function scale() {
document.querySelector("#container > circle")
.setAttribute('transform', 'scale(1.5,1.5)');
}
Here is the Demo. Note that you have to select the option No Wrap - in <head> (on the right hand in the Frameworks & Extensions section). Or better you should attach click handler right in JS code editor (not inline as an attribute in HTML code).
Here is one way to scale just the circle using JS:
Demo: http://jsfiddle.net/hb4nnau0/1/
For convenience, give your circle a transform attribute with no change in scale added. (Alternatively you can add this programmatically on demand.)
`
In your event handler, modify the scale of this transform element:
var circle = document.querySelector('circle'); // Or however, e.g. by id
var scale = circle.transform.animVal.getItem(0); // The first transform
scale.setScale(4,3); // Modify the transform
can you help me to place a Highchart inside a SVG element instead of an HTML . Cascaded elements work fine. I have already done it with the jquery SVG plot. But Highchart throws an error 13. What can i do?
Kind regards
Markus Breitinger
You can generate chart in div, which will have negative margin. Then use getSVG() function and paste it ot svg element.
http://api.highcharts.com/highcharts#Chart.getSVG()
Unfortunately it is not suppored, highcharts renders the chart in additional divs and adds elements like labels/datalabels as html objects.
But you can copy the SVG of highstock in you SVG. But you will lose all attached events.
Like drag and drop, click ....
Here an Example of it.
http://jsfiddle.net/L6SA4/10/
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-c.json&callback=?', function(data) {
// Create a hidden and not attached div container.
var div = $('<div>This is an hidden unatached container.</div>');
// Create the chart
div.highcharts('StockChart', {
chart: {
width: 480,
height: 400,
events: {
load: function () {
// If hidden div was generated, take the svg content and put it into svg.
var stockSvg = $('svg', this.container);
var svgObj = $('#mySvg').svg();
// Force position of highstock
stockSvg.attr('x', 20);
stockSvg.attr('y', 30);
// Replace ugly rect with highstock
$('#container', svgObj).replaceWith(stockSvg);
}
}
},
series : [{
name : 'AAPL',
data : data,
tooltip: {
valueDecimals: 2
}
}]
});
});
In JavaScript we have document.elementfrompoint to get an element based on coordinates.
Is there any thing like that in Openlaszlo to get a view based on coordinate?
There is no direct support for that functionality in OpenLaszlo, but for ActionScript 3 based runtimes you can utilize the flash.display.DisplayObjectContainer#getObjectsUnderPoint() method. In the DHTML runtime, you can use the document.elementFromPoint(x, y), and based on Quirksmode that should be supported by all modern browsers.
Here is an example program implementing an canvas.elementFromPoint() method:
<canvas debug="true">
<passthrough when="$as3">
import flash.geom.Point;
</passthrough>
<view id="background" width="100%" height="100%" bgcolor="#eeeeee" clickable="true"/>
<view id="red" x="200" y="100" width="200" height="200" bgcolor="#ff0000" opacity="0.3" clickable="true" />
<view id="green" x="150" y="200" width="200" height="200" bgcolor="#00ff00" opacity="0.3" clickable="true"/>
<view id="blue" x="250" y="200" width="200" height="200" bgcolor="#0000ff" opacity="0.3" clickable="true"/>
<handler name="onclick" reference="lz.GlobalMouse">
canvas.elementFromPoint();
</handler>
<method name="elementFromPoint"><![CDATA[
var mouseX = canvas.getMouse('x'),
mouseY = canvas.getMouse('y'),
objects = null, // array of objects at mouse pointer in SWF runtime
element = null; // The element we are looking for
Debug.info( 'mouse position: x=' + mouseX + ' / mouseY=' + mouseY );
if ($as3) {
// in SWF runtime, use the DisplayObjectContainer.getObjectsUnderPoint() method
objects = canvas.getDisplayObject().getObjectsUnderPoint(new Point(mouseX, mouseY));
element = objects[objects.length-1].owner;
} else {
// in DHTML, we can use elementFromPoint, and need to retrieve the owner view of the div
element = document.elementFromPoint(mouseX, mouseY).owner.owner;
}
Debug.info('View under mousecursor:', element);
return element;
]]></method>
</canvas>
There are 4 views, one background view scaled to 100% x 100%. And three color views: red, green and blue - with the blue one being the top one. When clicking on the view, the correct view object is returned.
The code has been tested in the DHTML runtime with Chrome 22.0, Firefox 16.0.1, and Opera 12.02. Flash should work in every browser, I haven't tested with IE.
I don't think so.
You will have to build your own custom array or observer object, collect all views and then loop through all items and do a check if the coordinates are inside the bounding box of the view.
In Flash there is also something like "hitTest", that might be similar to JavaScript's "document.elementfrompoint" to get the exact pixel matching, in case the bounding box is not enough for you.
Sebastian
how can we achieve this?
I got the SVG in the function, how can i make it transparent on top of canvas?? Currently i have all my functions working on the canvas. But I found out that SVG can do the add and remove function. How can I go about it?
function Add() {
var id = Math.floor(Math.random()*101+1);
x = Math.random() * 550;
y = Math.random() * 250;
if (document.getElementById('amount').value < 50){
document.getElementById('amount').value++;
svg = document.getElementById("main");
// construct uniqueid for the images
uniqueid = "frog" + document.getElementById('amount').value;
//namespaces for SVG
svgNS="http://www.w3.org/2000/svg";
xlinkNS="http://www.w3.org/1999/xlink";
// create a image element
image = document.createElementNS(svgNS, 'image');
// set id and other attributes
image.setAttributeNS(null, "id", uniqueid);
image.setAttributeNS(xlinkNS, "href","jef-frog.gif");
image.setAttributeNS(null, "x", x);
image.setAttributeNS(null, "y", y);
image.setAttributeNS(null, "width", "50");
image.setAttributeNS(null, "height", "50");
// append to svg
svg.appendChild(image);
} else {
alert("we got 50");
}
}
Assuming you are asking about transparency in SVG <image> elements, I'm pleased to say that it works just fine:
Demo: http://jsfiddle.net/XBCEK/
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xl="http://www.w3.org/1999/xlink">
<image xl:href="http://phrogz.net/tmp/alphaball.png"
x="20" y="30" width="128" height="128" />
<image xl:href="http://phrogz.net/tmp/hand.gif"
x="220" y="30" width="32" height="32" />
</svg>
If you embed that SVG on a page along with the following CSS:
body { background:url(http://phrogz.net/tmp/grid.gif) }
svg { background:rgba(255,0,0,0.3) /*…*/ }
…then you will see that:
The background of the SVG is transparent by default. We can even provide a low-opacity color background that lets the background of the page (the grid) show through.
The background of both 8-bit-transparency PNG (the ball) and 1-bit transparency GIF (the hand) allow the background of the SVG/page to shine through correctly.