Selecting path element fill with JQuery - javascript

I have some outer g element and an inner element with a green fill colour that is part of a maps SVG path. I've managed to select the inner path element, but am unable to select its fill attribute to get its colour. How can I select the first inner path element's fill colour?
Selecting the first path element:
var item = $('.datamap path')
And my attempt to get the fill, which yields the following exception:
$(item).attr('fill')
Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '[object SVGPathElement]' is not a valid selector.
Here's what my DOM looks like:
<g id="" class="datamaps-subunits">
<path d="M335.2035703570357,117.04432210343535L336.6065106510651,117.58613066703171L337.6587158715872,117.39767551447646L337.95934593459344,116.76163937460245L339.06165616561657,116.54962732797782L339.8132313231323,116.12560323472849L340.11386138613864,115.01842921346635L341.2662766276628,114.75930337870288L341.51680168016804,114.26460860324534L342.1681668166817,114.61796201428643L342.5690069006901,114.66507580242525L343.37068706870684,114.68863269649465L344.37278727872786,114.97131542532753L344.82373237323736,115.13621368381338L345.8258325832584,114.68863269649465L346.27677767776777,114.97131542532753L346.7277227722773,114.33527928545355L347.5795079507951,114.35883617952294L347.7799279927993,114.1468241328983L347.93024302430246,113.58145867523254L348.531503150315,113.11032079384438L349.2830783078308,113.41656041674668L349.13276327632764,113.840584509996L349.5837083708371,113.91125519220422L349.433393339334,115.0890998956746L349.9845484548455,115.53668088299332L350.485598559856,115.25399815416041L351.0868586858686,115.11265678974398L351.93864386438645,114.47662064987L352.8906390639064,114.59440512021703L354.34368436843687,114.59440512021703L354.5942094209421,114.99487231939695L353.7925292529253,115.13621368381338L353.09105910591063,115.39533951857686L351.487698769877,115.56023777706272L349.9845484548455,115.86647739996499L349.1828682868287,116.45539975170018L349.483498349835,117.04432210343535L349.6839183918392,117.75102892551756L348.98244824482447,118.33995127725274L349.0325532553255,118.8582029467797L348.63171317131713,119.37645461630663L347.32898289828984,119.32934082816783L347.8801380138014,120.24805969687469L346.9782478247825,120.60141310791579L346.3769876987699,121.42590440034505L346.477197719772,122.27395258684369L345.92604260426043,122.6508628919542L345.4249924992499,122.53307842160717L344.32268226822686,122.72153357416242L344.1723672367237,123.09844387927293L343.1702670267027,123.09844387927293L342.3685868586859,123.89937827763278L342.31848184818483,125.07722298110312L340.51470147014703,125.64258843876888L339.5627062706271,125.52480396842185L339.2620762076208,125.83104359132413L338.46039603960395,125.66614533283828L337.05745574557454,125.85460048539355L334.70252025202524,125.14789366331132L335.9551455145515,123.89937827763278L335.85493549354936,123.0042163029953L334.8027302730273,122.76864736230124L334.70252025202524,121.87348538766378L334.2515751575158,120.76631136640165L334.85283528352835,120.01249075618061L334.2515751575158,119.80047870955596L334.6023102310231,118.78753226457147Z" class="datamaps-subunit AFG" style="fill: rgb(171, 221, 164); stroke-width: 1px; stroke: rgb(253, 253, 253);">
</path>
<path d="M283.29477947794777,181.87289458244325L283.44509450945094,182.29691867569258L283.24467446744677,182.98006860370538L283.495199519952,183.63966163764877L283.29477947794777,184.1579133071757L283.44509450945094,184.62905118856384L280.53900390039,184.60549429449446L280.43879387938796,189.03419037954296L281.3907890789079,190.18847818894392L282.2926792679268,191.06008326951195L279.7373237323732,191.6254487271777L276.3802880288029,191.41343668055305L275.42829282928295,190.75384364660965L269.76642664266427,190.82451432881788L269.5660066006601,190.91874190509552L268.71422142214226,190.28270576522152L267.81233123312336,190.2355919770827L267.0106510651065,190.47116091777679L266.3091809180918,190.75384364660965L266.2089708970897,189.8586816719722L266.40939093909395,188.65728007443244L266.8603360336034,187.36165090061505L266.96054605460546,186.7727285488799L267.4114911491149,185.52421316320132L267.7121212121212,184.95884770553556L268.51380138013803,184.04012883682867L268.9647464746475,183.4276495910241L269.11506150615065,182.39114625197018L269.0649564956496,181.59021185361036L268.6140114011401,181.09551707815282L268.26327632763275,180.24746889165417L267.9125412541254,179.4229775992249L268.0127512751275,179.14029487039204L268.4135913591359,178.57492941272628L268.0127512751275,177.2321864507701L267.7121212121212,176.3134675820632L267.0106510651065,175.41830560742574L267.1609660966097,175.15917977266227L267.7121212121212,174.970724620107L268.1129612961296,174.9942815141764L268.6140114011401,174.82938325569057L272.72262226222625,174.85294014975997L273.0733573357336,175.88944348881387L273.474197419742,176.71393478124313L273.77482748274826,177.16151576856186L274.3259825982598,177.89177948471348L275.2278727872787,177.77399501436645L275.6788178817882,177.58553986181118L276.48049804980496,177.77399501436645L276.6809180918092,177.44419849739475L277.0316531653165,176.6197072049655L277.88343834383437,176.57259341682666L277.98364836483654,176.3370244761326L278.6851185118512,176.3134675820632L278.53480348034805,176.83171925159016L280.23837383738373,176.80816235752076L280.2884788478848,177.67976743808882L280.53900390039,178.22157600168518L280.33858385838585,179.0696241881838L280.43879387938796,179.91767237468247L280.8897389738974,180.4359240442094L280.83963396339635,182.08490662906792L281.1903690369037,181.96712215872088L281.7916291629163,181.99067905279028L282.64341434143415,181.80222390023502ZM266.96054605460546,174.73515567941294L266.55970597059707,173.67509544628965L267.1609660966097,173.08617309455445L267.5618061806181,172.8506041538604L268.0628562856286,173.32174203524852L267.5618061806181,173.60442476408141L267.36138613861385,173.9813350691919L267.31128112811285,174.5702574209271Z" class="datamaps-subunit AGO" style="fill: rgb(171, 221, 164); stroke-width: 1px; stroke: rgb(253, 253, 253);">
</path>
<path d="M278.63501350135016,108.42249887403241L278.484698469847,108.89363675542054L278.6851185118512,109.48255910715571L279.2362736273627,109.83591251819684L279.2362736273627,110.18926592923793L278.78532853285327,110.4012779758626L278.6851185118512,110.84885896318133L278.03375337533754,111.53200889119412L277.7832283228323,111.41422442084709L277.7832283228323,111.1079847979448L277.031653`1653165,110.66040381062606L276.8813381338134,109.97725388261327L276.98154815481547,109.03497811983698L277.1819681968197,108.61095402658768L276.98154815481547,108.37538508589361L276.8813381338134,107.95136099264428L277.482598259826,107.26821106463146L277.53270327032703,107.52733689939494L277.9335433543354,107.3859955349785L278.23417341734176,107.76290584008902L278.5849084908491,107.90424720450545Z" class="datamaps-subunit ALB" style="fill: rgb(171, 221, 164); stroke-width: 1px; stroke: rgb(253, 253, 253);">
</path>
<path d="M321.7754275427543,132.92166870621563L322.0259525952595,132.85099802400742L322.0760576057606,133.2279083291179L323.1783678367837,133.01589628249326L324.33078307830783,133.06301007063206L325.18256825682573,133.0865669647015L326.13456345634563,132.1678480959946L327.13666366636664,131.27268612135714L328.03855385538554,130.40108104078908L328.2890789078908,130.8722189221772L328.489498949895,131.97939294343934L327.78802880288026,131.97939294343934L327.63771377137715,132.89811181214623L327.88823882388243,133.0865669647015L327.2869786978698,133.36924969353436L327.2869786978698,133.93461515120012L326.88613861386136,134.49998060886588L326.8360336033603,135.06534606653165L326.5354035403541,135.34802879536454L322.37668766876686,134.66487886735175L321.82553255325536,133.25146522318732Z" class="datamaps-subunit ARE" style="fill: rgb(171, 221, 164); stroke-width: 1px; stroke: rgb(253, 253, 253);">
</path>
<path d="M156.82973297329733,243.07370537476248L155.97794779477948,243.02659158662365L154.47479747974796,243.02659158662365L154.47479747974796,239.91708156946194L155.02595259525953,240.55311770933594L155.72742274227426,241.61317794245923L157.53120312031203,242.43766923488846L159.485298529853,242.7910226459296L158.83393339333935,243.4977294680118L157.53120312031203,243.5448432561506ZM162.74212421242123,197.6324567148765L165.29747974797482,199.89391854553955L166.44989498949894,200.1059305921642L168.15346534653466,201.1424339312181L169.6065106510651,201.6842424948145L169.80693069306932,202.29672174061906L168.4039903990399,204.41684220686568L169.80693069306932,204.7937525119762L171.4102910291029,205.00576455860084L172.51260126012602,204.77019561790678L173.76522652265226,203.71013538478348L173.96564656465648,202.4851768931743L174.66711671167116,202.22605105841083L175.3685868586859,203.0269854567707L175.31848184818483,204.1341594780328L174.16606660666068,204.91153698232324L173.2140714071407,205.476902439989L171.66081608160817,206.8196454019452L169.80693069306932,208.72775382156715L169.45619561956198,209.83492784282927L169.1054605460546,211.2718983810631L169.1054605460546,212.63819823708872L168.8048304830483,212.9679947540604L168.7046204620462,213.86315672869787L168.6044104410441,214.59342044484947L170.35808580858088,215.77126514831983L170.15766576657666,216.73709780516552L171.05955595559556,217.34957705097008L170.95934593459344,218.0327269789829L169.65661566156615,219.79949403418843L167.55220522052207,220.55331464440945L164.7964296429643,220.83599737324232L163.24317431743174,220.6946560088259L163.54380438043805,221.54270419532452L163.24317431743174,222.57920753437844L163.49369936993702,223.28591435646064L162.6920192019202,223.75705223784877L161.23897389738974,223.94550739040403L159.93624362436245,223.4508126149465L159.38508850885088,223.8041660259876L159.58550855085508,225.1940227760826L160.48739873987398,225.61804686933192L161.2890789078908,225.1704658820132L161.6899189918992,225.90072959816482L160.3871887188719,226.32475369141414L159.2848784878488,227.1963587719822L159.08445844584458,228.5862155220772L158.73372337233724,229.34003613229822L157.43099309930994,229.34003613229822L156.32868286828685,230.07029984844985L155.92784278427843,231.10680318750374L157.33078307830783,232.11974963248826L158.63351335133515,232.40243236132113L158.18256825682568,233.6509477469997L156.52910291029104,234.42832525129012L155.62721272127214,236.0773078361486L154.37458745874588,236.61911639974497L153.7733273327333,237.27870943368836L154.22427242724274,238.71567997192219L155.1762676267627,239.516614370282L154.57500750075008,239.44594368807378L153.27227722772278,239.23393164144915L149.9152415241524,239.04547648889388L149.36408640864084,238.24454209053403L149.36408640864084,237.18448185741073L148.46219621962194,237.27870943368836L147.96114611461147,236.78401465823083L147.81083108310833,235.29993033185818L148.9131413141314,234.6874510860536L149.36408640864084,233.81584600548553L149.16366636663668,233.10913918340333L149.9152415241524,231.90773758586357L150.4162916291629,230.07029984844985L150.26597659765974,229.2458085560206L150.86723672367236,228.98668272125713L150.7169216921692,228.46843105173016L150.06555655565558,228.18574832289727L150.56660666066608,227.5968259711621L149.9152415241524,227.07857430163517L149.61461146114613,225.4767055049155L150.16576657665766,225.1940227760826L149.9152415241524,223.4979264030853L150.26597659765974,222.06095586485148L150.6167116711671,220.83599737324232L151.46849684968498,220.31774570371536L151.01755175517553,218.95144584768977L151.01755175517553,217.6793735679418L152.06975697569757,216.78421159330432L152.01965196519654,215.60636688983396L152.82133213321333,214.2636239278778L152.82133213321333,212.9679947540604L152.47059705970597,212.70886891929692L151.81923192319232,210.30606572421743L152.67101710171016,208.892652080053L152.57080708070808,207.5263522240274L153.07185718571856,206.27783683834883L153.97374737473746,204.95865077046204L154.97584758475847,204.11060258396338L154.52490249024902,203.54523712629762L154.82553255325536,203.0976561389789L154.7754275427543,200.789080520177L156.27857785778576,200.1059305921642L156.77962796279627,198.645403159861L156.62931293129313,198.3156066428893L157.78172817281728,197.0435343631413L159.58550855085508,197.39688777418243L160.3871887188719,198.38627732509752L160.93834383438343,197.27910330383537L162.54170417041703,197.3262170919742Z" class="datamaps-subunit ARG" style="fill: rgb(171, 221, 164); stroke-width: 1px; stroke: rgb(253, 253, 253);">
</path>
<path d="M310.65211521152116,109.48255910715571L312.60621062106213,109.27054706053107L312.85673567356736,109.62390047157217L313.4078907890789,109.85946941226624L313.1072607260726,110.21282282330733L313.85883588358837,110.70751759876488L313.45799579958,111.13154169201421L314.0592559255926,111.50845199712472L314.7106210621062,111.74402093781879L314.7106210621062,112.70985359466448L314.2095709570957,112.75696738280328L313.6584158415842,111.95603298444345L313.6584158415842,111.72046404374937L313.0571557155715,111.74402093781879L312.60621062106213,111.36711063270828L312.35568556855685,111.39066752677766L311.80453045304534,110.99020032759776L310.7523252325233,110.63684691655666L310.9026402640264,109.97725388261327Z" class="datamaps-subunit ARM" style="fill: rgb(171, 221, 164); stroke-width: 1px; stroke: rgb(253, 253, 253);">
</path>
</g>

if you want to get css property value you should use css not attr
var item = $('.datamaps-subunits path');
$(item).css('fill');
see it work here

Related

how to make svg curve at one end

im using svg for circular progress bar , i want to make one end curve not the both end . how is this possible ?
how can i implement one end curve in svg?
svg {
height: 80vh;
margin: 10vh auto;
border: 1px solid red;
display: block;
transform: rotate(-90deg);
}
svg circle {
stroke-width: 10;
fill: transparent;
}
#outer {
stroke: lightgrey;
}
#inner {
stroke: blue;
animation: value 2.5s linear forwards;
stroke-linecap: round;
}
#keyframes value {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 90 100;
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="outer" cx="50" cy="50" r="40" />
<circle id="inner" pathLength="100" cx="50" cy="50" r="40" />
</svg>
The easiest way would be to mask the starting point of the blue circle.
For this you will need a <mask> like so:
<mask id="m">
<rect width="100" height="100" fill="white"/>
<rect x="85" y="40" width="10" height="10" />
</mask>
Please observe that the first rectangle is white and it covers the whole chart. (Everything under a white pixel will be visible). The smaller rectangle is black and covers the starting point of the blue circle. Everything under a black pixel will be invisible.
svg {
height: 80vh;
margin: 10vh auto;
border: 1px solid red;
display: block;
transform: rotate(-90deg);
}
svg circle {
stroke-width: 10;
fill: transparent;
}
#outer {
stroke: lightgrey;
}
#inner {
stroke: blue;
animation: value 2.5s linear forwards;
stroke-linecap: round;
}
#keyframes value {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 90 100;
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<mask id="m">
<rect width="100" height="100" fill="white"/>
<rect x="85" y="40" width="10" height="10" />
</mask>
<circle id="outer" cx="50" cy="50" r="40" />
<circle id="inner" pathLength="100" cx="50" cy="50" r="40" mask="url(#m)" />
</svg>
Try this code:
svg {
height: 80vh;
margin: 10vh auto;
border: 1px solid red;
display: block;
transform: rotate(-90deg);
border-top-right-radius: 20px;
}
svg circle {
stroke-width: 10;
fill: transparent;
}
#outer {
stroke: lightgrey;
}
#inner {
stroke: blue;
animation: value 2.5s linear forwards;
stroke-linecap: round;
}
#keyframes value {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 90 100;
}
}
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<circle id="outer" cx="50" cy="50" r="40" />
<circle id="inner" pathLength="100" cx="50" cy="50" r="40" />
</svg>
I came up with an alternative solution than enxaneta suggested. The problem with using a mask is that when your value goes over 96% or so, the circle isn't completely filled and the mask is revealed.
Instead, you can set a rounded progress line on top of another progress line that has flat endcaps. By rotating the rounded progress line by roughly 5 degrees, the flat end is revealed.
Here's how to do that in React Native with react-native-svg:
const radius = 60;
let myPercentage = 40;
const circleCircumference = 2 * Math.PI * radius;
const valueOffset = circleCircumference -
(circleCircumference * myPercentage * 0.98) / 100;
<Svg height={radius * 2 + 30} width={radius * 2 + 30}>
<G rotation={-90} originX={radius + 15} originY={radius + 15}>
// Background gray circle
<Circle
cx="50%"
cy="50%"
r={radius}
stroke="rgb(60, 60, 60)"
fill="transparent"
strokeWidth="10"
strokeDasharray={circleCircumference}
strokeLinecap="butt"
/>
// Background progress circle with flat ends
<Circle
cx="50%"
cy="50%"
r={radius}
stroke={"rgb(0, 51, 204)"}
fill="transparent"
strokeWidth="10"
strokeDasharray={circleCircumference}
strokeDashoffset={valueOffset}
strokeLinecap="butt"
/>
// Progress circle with round ends rotated by 5 degrees
<Circle
cx="50%"
cy="50%"
r={radius}
stroke={rgb(0, 51, 204)}
fill="transparent"
rotation={5}
originX={radius + 15}
originY={radius + 15}
strokeWidth="10"
strokeDasharray={circleCircumference}
strokeDashoffset={valueOffset}
strokeLinecap="round"
/>
</G>
</Svg>

SVG Linear Gradient SVG Background

I am trying to use an SVG, which will be dynamically created from JavaScript, as the background image on another SVG. This works when the fill color of the object is a solid color, but not when I try to use a linear gradient. Run the code to see an example. Please help figure how to use the linear gradient!
const createElement = (tag, attributes) => {
const element = document.createElement(tag);
if (attributes) Object.keys(attributes).forEach(key => element.setAttribute(key, attributes[key]));
return element;
}
// Create background for first SVG using solid color fill:
const svg3bg = createElement('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 50 50', width: 50, height: 50 });
svg3bg.appendChild(createElement('circle', { cx: 25, cy: 25, r: 20, fill: '#00F' }));
const svg3 = document.getElementById('svg3');
svg3.style.backgroundImage = `url('data:image/svg+xml,${svg3bg.outerHTML.replace(/\#/g, '%23')}')`; // This does not display unless I replace the # signs with a hex code.
svg3.style.backgroundColor = 'palegreen';
// Create background for second SVG using linear gradient fill:
const svg4bg = createElement('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 50 50', width: 50, height: 50 });
const lg4 = svg4bg.appendChild(createElement('linearGradient', { id: "lg4" }))
lg4.appendChild(createElement('stop', { offset: "0%", 'stop-color': '#d67ef5' }))
lg4.appendChild(createElement('stop', { offset: "50%", 'stop-color': '#2b78ba' }))
lg4.appendChild(createElement('stop', { offset: "100%", 'stop-color': '#4d79a9' }))
svg4bg.appendChild(createElement('circle', { cx: 25, cy: 25, r: 20, fill: 'url(#lg4)' }));
const svg4 = document.getElementById('svg4');
svg4.style.backgroundImage = `url('data:image/svg+xml,${svg4bg.outerHTML.replace(/\#/g, '%23')}')`;
svg4.style.backgroundColor = 'palegreen';
This shows an SVG using another SVG (generated from JavaScript) of blue dots as its background image:
<div id="div3">
<svg id="svg3" iewBox="0 0 100 100" style="width: 150; height: 150;">
<rect x="10" y="10" width="80" height="80" style="stroke: black; fill: none; stroke-width: 4"></rect>
</svg>
</div><br>
When trying to do the same thing with a linear gradient to fill the object instead of a solid color, it does not
display:
<div id="div4">
<svg id="svg4" iewBox="0 0 100 100" style="width: 150; height: 150;">
<rect x="10" y="10" width="80" height="80" style="stroke: black; fill: none; stroke-width: 4"></rect>
</svg>
</div><br>
This shows what the background image with the linear gradient should look like:
<div id="div5">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 50 50" width="50" height="50">
<lineargradient id="lg5">
<stop offset="0%" stop-color="#d67ef5"></stop>
<stop offset="50%" stop-color="#2b78ba"></stop>
<stop offset="100%" stop-color="#4d79a9"></stop>
</lineargradient>
<circle cx="25" cy="25" r="20" fill="url(#lg5)"></circle>
</svg>
</div>
Seems OK to me once I correct all the typos.
viewBox is missing a v in some places
units are missing from CSS sizes where they are mandatory
use createElementNS to create SVG elements and use an XML serializer rather than HTML serialization to get namespaces in the output.
while not necessary in this case I've fixed the URI encoding properly rather than using replace
const createElement = (tag, attributes) => {
const element = document.createElementNS('http://www.w3.org/2000/svg', tag);
if (attributes) Object.keys(attributes).forEach(key => element.setAttribute(key, attributes[key]));
return element;
}
let s = new XMLSerializer();
// Create background for first SVG using solid color fill:
const svg3bg = createElement('svg', { viewBox: '0 0 50 50', width: 50, height: 50 });
svg3bg.appendChild(createElement('circle', { cx: 25, cy: 25, r: 20, fill: '#00F' }));
const svg3 = document.getElementById('svg3');
svg3.style.backgroundImage = `url('data:image/svg+xml,${encodeURIComponent(s.serializeToString(svg3bg))}')`;
svg3.style.backgroundColor = 'palegreen';
// Create background for second SVG using linear gradient fill:
const svg4bg = createElement('svg', { viewBox: '0 0 50 50', width: 50, height: 50 });
const lg4 = svg4bg.appendChild(createElement('linearGradient', { id: "lg4" }))
lg4.appendChild(createElement('stop', { offset: "0%", 'stop-color': '#d67ef5' }))
lg4.appendChild(createElement('stop', { offset: "50%", 'stop-color': '#2b78ba' }))
lg4.appendChild(createElement('stop', { offset: "100%", 'stop-color': '#4d79a9' }))
svg4bg.appendChild(createElement('circle', { cx: 25, cy: 25, r: 20, fill: 'url(#lg4)' }));
const svg4 = document.getElementById('svg4');
svg4.style.backgroundImage = `url('data:image/svg+xml,${encodeURIComponent(s.serializeToString(svg4bg))}')`;
svg4.style.backgroundColor = 'palegreen';
This shows an SVG using another SVG (generated from JavaScript) of blue dots as its background image:
<div id="div3">
<svg id="svg3" viewBox="0 0 100 100" style="width: 150px; height: 150px;">
<rect x="10" y="10" width="80" height="80" style="stroke: black; fill: none; stroke-width: 4"></rect>
</svg>
</div><br>
When trying to do the same thing with a linear gradient to fill the object instead of a solid color, it does not
display:
<div id="div4">
<svg id="svg4" viewBox="0 0 100 100" style="width: 150px; height: 150px;">
<rect x="10" y="10" width="80" height="80" style="stroke: black; fill: none; stroke-width: 4"></rect>
</svg>
</div><br>
This shows what the background image with the linear gradient should look like:
<div id="div5">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50">
<linearGradient id="lg5">
<stop offset="0%" stop-color="#d67ef5"></stop>
<stop offset="50%" stop-color="#2b78ba"></stop>
<stop offset="100%" stop-color="#4d79a9"></stop>
</linearGradient>
<circle cx="25" cy="25" r="20" fill="url(#lg5)"></circle>
</svg>
</div>

Isolate section of SVG when mouse is hovered

I am attempting to build an interactive map from scratch. I have an SVG of the map of Canada that has separate layers for each province. I'd like to highlight a specific province/territory when the mouse is hovered over it.
I have tried using a function that gets the live update of the mouse coordinates, but I am unsure as to how to figure out which section of the image it is on. I am unsure as to if this is the best method of doing it.
Through some of my research, I have found a method of gathering the pointer coordinates:
let x = 0;
let y = 0;
function showCoords() {
x = event.clientX;
y = event.clientY;
}
And I call it around the SVG using:
<div onmousemove="showCoords()">
...SVG HERE
</div>
I can select the different layers inside of the SVG, but the question is if I can find a way of checking which layer my mouse is currently over.
Thank you!
Edit:
I have reached a solution that accomplishes my goal, but I am unsure as to if it is efficient.
Using CSS, I fill each group upon hover:
#canada {
fill: hsl(0, 0%, 29%);
}
#canada g {
transition: .3s;
}
#canada g:hover {
fill: hsl(189, 88%, 59%);
}
I am also using the onClick option on each group to pull up their dialogue.
Maybe something like this? Just keep "data-name" attribute on each <g> inside svg code.
let x = 0;
let y = 0;
let svgCountry = document.querySelector("#states svg");
let svgStates = svgCountry.querySelectorAll("[data-name]");
let resContainer = document.getElementById("state-hovered-is");
// init tooltip
function showCoords(event) {
let x = event.clientX;
let y = event.clientY;
resContainer.setAttribute("style", "left:" + (x + 15) + "px;" + "top:" + (y - 50) + "px;");
}
// close tooltip
function clearCoor() {
resContainer.innerHTML = "";
}
// clear everything
function clearAllOn() {
svgStates.forEach(function(el) {
el.classList.remove("hover");
resContainer.innerHTML = "";
console.clear();
});
}
// display current state in div
function displayState(el) {
var res = el.getAttribute("data-name");
el.classList.add("hover");
resContainer.innerHTML = "<p>You're at" + " " + res + "</p>";
console.log(res);
}
svgStates.forEach(function(el) {
// mouse events
el.addEventListener("mouseenter", function() {
displayState(el);
});
el.addEventListener("mouseleave", function() {
clearAllOn();
});
// touch events
el.addEventListener("touchstart", function() {
clearAllOn();
displayState(el);
});
});
body {
background-color: #fff;
font-family: Arial, Helvetica, sans-serif;
color: #333;
}
g.hover {
opacity: 0.5;
}
#states {
margin: 0 auto;
width: 600px;
max-width: 100%;
position: relative;
}
#state-hovered-is {
text-align: center;
min-height: 50px;
position: fixed;
pointer-events: none;
background-color: rgba(0, 0, 0, 0.76);
border-radius: 6px;
}
#state-hovered-is p {
color: #fff;
margin: 0;
padding: 15px;
width: 180px;
}
<div id="states" onmousemove="showCoords(event)" onmouseout="clearCoor()">
<!-- State name here -->
<div id="state-hovered-is"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 961.38 830.7">
<defs>
<style>
.cls-1 { fill: #fff;}
.cls-2 {fill: #b8c4e6;}
.cls-3 {fill: #ce8080;}
.cls-4 {fill: #e99bd2;}
.cls-5 {fill: #acac90;}
.cls-6 {fill: #e6c0c0;}
.cls-7 {fill: #4d6ac1;}
.cls-8 {fill: #c9e6b8;}
.cls-9 {fill: #f3f3db;}
.cls-10 {fill: #cece71;}
.cls-11 {fill: #7188ce;}
.cls-12 {fill: #daa0a0;}
.cls-13 {fill: #91916b;}
.cls-14 {fill: #dada94;}
.cls-15 {fill: #916b86;}
</style>
</defs>
<title>Canada</title>
<g id="Layer_1">
<ellipse class="cls-1" cx="480.69" cy="415.35" rx="679.8" ry="587.39" />
<path class="cls-1" d="M539.84,220.75c-2.45,5-6.57,8.18-10.72,11.7l2-9.56C534.53,224.17,537,221.84,539.84,220.75Z" transform="translate(-0.06 -0.26)" />
<path class="cls-1" d="M53,543.56c-1.09,2.13-2.18,4.23-3.52,6.84l-.51-10.68.56-.25Z" transform="translate(-0.06 -0.26)" />
<path class="cls-1" d="M771.19,558.14c-.32-2.18-.77-4.36-.89-6.56a3.15,3.15,0,0,1,1.31-2.05,1.76,1.76,0,0,1,1.64.49,4.19,4.19,0,0,1,.17,2.5c-.48,1.84-1.18,3.62-1.79,5.43Z" transform="translate(-0.06 -0.26)" />
<path class="cls-1" d="M40.77,527.77l-7-8.41.35-.18A76,76,0,0,1,40.4,524c.77.71.87,2.14,1.27,3.25Z" transform="translate(-0.06 -0.26)" />
<path class="cls-1" d="M493.56,95.47l3.41,6L485.7,105a30.91,30.91,0,0,1,2.81-2.42C491.7,100.51,493.64,100.2,493.56,95.47Z" transform="translate(-0.06 -0.26)" />
</g>
<g id="Yukon" data-name="Yukon">
<path class="cls-3" d="M174.12,185.61c.91,1.61.88,2.8-.63,4.31-4.21,4.21-8.16,8.68-12.2,13.07-.34.38-.78,1-.72,1.39.58,3.9-2,6.08-4.31,8.53a6.48,6.48,0,0,0-1.84,3.83,5.33,5.33,0,0,0,1.79,3.5c1.85,1.68,4.07,2.94,6,4.53,3.45,2.83,3.47,5.7.33,9.15-2.19,2.39-4.41,4.77-6.37,7.34-1.76,2.3-1.12,4.05,1.42,5.49,1.4.81,2.66,1.88,4.19,3-2.18,1.51-3.35,2.81-2.33,5.22.45,1.05,0,2.31-1.73,2.4a17.09,17.09,0,0,0-3.62.83c-4.36,1.21-5.4,4.72-5.53,8.56a57.14,57.14,0,0,0,.5,10c.23,1.57,1.5,3,2.39,4.63-2.26,2.84-2.38,6.32-1.6,10.12a46.41,46.41,0,0,1,.52,7.56,1.6,1.6,0,0,1-.82,1.17c-2.55,1.24-3,3.61-3.48,6a9.38,9.38,0,0,1-1.27,3.48,10.68,10.68,0,0,0-1.7,8.87,2.39,2.39,0,0,1-.44,1.48c-.6,1-1.32,2-2,2.93-1.42,2.18-1.43,4,.77,5.24,3.32,1.83,3.1,4.7,2.57,7.41-.72,3.66-.45,6.87,2,9.78,1.47,1.77,1.39,3.3-.37,4.95a7.72,7.72,0,0,0-1.45,3.08c-.28.81-.27,1.71-.5,2.53-1.52,5.43,1,6.26,4.74,7.61,1.41.5,2.57,1.66,3.93,2.34a26.86,26.86,0,0,0,4.63,1.87c1.72.5,3.51.73,5.24,1.06.05.25.15.5.1.53-3,2.14-3,5.28-2.81,8.48.09,2,0,4,0,6.25A575.11,575.11,0,0,1,48.14,298a7.87,7.87,0,0,1,.58-.75c3.2-3.33,3.13-5.09-.71-7.55a38.29,38.29,0,0,0-6.52-3.12c-2.14-.86-3.05-5-1.32-6.73q13.23-13,26.49-26c6.81-6.67,13.65-13.31,20.46-20q13.26-13,26.5-26,10.56-10.35,21.15-20.68,11.07-10.83,22.16-21.66c1.92-1.87,3.87-3.74,6-5.43a2.44,2.44,0,0,1,2.34-.08,12.63,12.63,0,0,1,4.51,7.68c.95,5.52,2.44,10.95,3.73,16.42A5.64,5.64,0,0,0,174.12,185.61Z" transform="translate(-0.06 -0.26)" />
</g>
<g id="British_Columiba" data-name="British Columiba">
<g>
<path class="cls-4" d="M190.26,405.28c.27.14.53.31,1.06.62-1,1.88-2,3.69-2.9,5.53-5.64,11.14-11.24,22.3-16.9,33.43-4.43,8.73-8.92,17.42-13.38,26.13l-19.37,37.93c-.21.42-.68.84-.65,1.24.17,2.7,0,5.24-2.52,6.95.78,2,1.25,4.14,2.45,5.8.82,1.15,1.83,1.89,1.89,3.54s.46,3.46,2.33,4.55c2.39,1.41,1.92,4.19,2.3,6.41.31,1.81-.17,3.77-.35,5.66s.8,3.35,2.22,4.62a2.72,2.72,0,0,1,.81,2.17,5.54,5.54,0,0,0,1.49,5.42c.88,1,1.18,2.44,1.69,3.71.82,2,1.6,4,2.38,6,1,2.51,2,5,2.9,7.55.32.88.14,2.18.72,2.67,3.23,2.74,2.75,6.63,3,10.1a15.41,15.41,0,0,0,3.74,8.9c3.16,3.57,2.61,7,1.68,10.73-.83,3.31-1.92,6.57-3,9.84s-.35,6.2,1.21,9.74c-5.31-2.27-10.13-4.28-14.9-6.38-10.53-4.64-21.08-9.23-31.54-14-8.14-3.72-16.25-7.52-24.19-11.65-8.81-4.6-17.41-9.61-26.09-14.47a2,2,0,0,1-1-1.12,65.21,65.21,0,0,1-1-7.47c-.16-3.6-1.05-5-4.37-5.94,0-1.19,0-2.34,0-3.5a3.82,3.82,0,0,0-2.71-3.76c-1.17-.5-3.27-.93-3.32-1.53a9.88,9.88,0,0,1,.91-5.44c3.08-5.49,3.08-7.06-1-11.44-2.29-2.47-4.78-4.79-6.82-7.46a9.16,9.16,0,0,1-1.44-4.76c-.2-2.61-1.08-4.69-3.49-5.72-3.27-1.39-4.67-4.2-5.48-7.23a5.27,5.27,0,0,1,1-4.36,5.48,5.48,0,0,0,1.59-5.2c-.48-3.26,1.93-4.89,4.78-5.55a19.58,19.58,0,0,0,3.83-1c2.43-1.12,2.65-3.06.7-4.87a7.78,7.78,0,0,1-2-9.22c1.46-3.4,1.33-5.05-1-6.15-1.19-.56-2.78-.29-4.19-.39-.47,0-.93-.05-1.65-.09,1.67-3,3-5.78,6.86-6.28a4.12,4.12,0,0,0,3.2-2.73c.72-1.68,2.44-2.95,3.74-4.38,1.14-1.23,1.82-2.81.52-4a5.8,5.8,0,0,0-4-1A30.06,30.06,0,0,0,44.62,459c-1.84-6.08-.47-11.9,1.17-17.65A3.74,3.74,0,0,1,48,439.05c7.2-1.55,10.53-7,13.68-12.85a30.35,30.35,0,0,1,3.83-4.91c1.69-2,2.72-4.14,1.8-6.84s-1.71-5.51-2.66-8.23A52.51,52.51,0,0,0,62,399.51c-1.34-2.62-.9-5.19-.39-7.83q2.15-11.08,4.26-22.15c1.08-5.61,2.21-11.21,3.21-16.84a9.48,9.48,0,0,0-.36-2.74c-.16-1.32-.33-2.65-.44-4-.14-1.58-.18-3.17-.36-4.74a11.92,11.92,0,0,1,1.16-7.34c1.92-3.53,1.66-7.9-.48-9.87l1.06-1.21c7.65,6.68,15.29,13.38,23.2,19.74,8.69,7,17.59,13.76,26.79,20,13.27,9,26.71,17.88,40.42,26.24C169.85,394.8,180.18,399.83,190.26,405.28Z" transform="translate(-0.06 -0.26)" />
<path class="cls-4" d="M67.71,323.4c-4.2-2.13-8.84-4.21-13.43-1.55-2.84,1.64-5.18.87-8.06.13,2.21-2.52,1.9-5.53,1.88-8.49s0-6.08,0-9.44a8.14,8.14,0,0,1,1.68.85c5.42,4.9,10.73,9.92,16.24,14.72l3.65,3.2L68.61,324A4,4,0,0,0,67.71,323.4Z" transform="translate(-0.06 -0.26)" />
<path class="cls-1" d="M52.34,580.17c.15,1.23-.68,2.57-1.25,4.47-2.23-1.77-4.17-2.89-5.53-4.5a75.63,75.63,0,0,1-5.85-8.23,3.32,3.32,0,0,1-.2-2.75c2.52-5.09,2.08-6.95-3.06-9.61-1.82-.94-2.5-1.94-2.32-4,.32-3.52.35-4.15-4.79-9.94,2-2.92,1.55-3.82-.24-7-1.32-2.35-1.69-5.31-2.07-8.06-.29-2.13-.63-4-2.58-5.25a2.26,2.26,0,0,1-.79-1.75c.24-3.45.6-6.89.93-10.33,2-.08,2.8,1.11,3.33,2.71A29.72,29.72,0,0,0,36,529,45.65,45.65,0,0,1,43,536.54c1.16,1.66,1.53,4.06,1.7,6.17a84.4,84.4,0,0,1,0,10.06c-.17,4.12,1.42,7.63,3.38,11.07a18,18,0,0,1,2.24,4.56A109.17,109.17,0,0,1,52.34,580.17Z" transform="translate(-0.06 -0.26)" />
<path class="cls-1" d="M17.57,426.81l6.17,8.48C16.39,441.78,11.81,449.73,11,459.7,10.41,448.18,12.87,437.39,17.57,426.81Z" transform="translate(-0.06 -0.26)" />
</g>
</g>
<g id="Alberta" data-name="Alberta">
<path class="cls-5" d="M194.56,407.63c27.17,14.46,55.83,25.35,85,35.57L214.1,643.67c-10.88-4-21.29-7.82-31.68-11.68-3.52-1.3-6.91-3-10.51-4s-5.08-3.41-6.18-6.74c-1.26-3.84-.43-7.18,1.12-10.59A26.88,26.88,0,0,0,169.13,597a4.52,4.52,0,0,0-1-2.58c-4.16-4.42-5.32-9.88-5.71-15.66-.07-1-.13-2.32-.75-2.88-2.84-2.56-2.45-6.26-3.65-9.38-.64-1.69-1.62-3.26-2.29-4.95-.84-2.14-1.52-4.35-2.27-6.53-.05-.15-.06-.35-.17-.44a6.25,6.25,0,0,1-2-7.07c.17-.6-1.07-1.75-1.85-2.43a2.33,2.33,0,0,1-1.08-2.43,28.92,28.92,0,0,0-.52-7.52c-.36-2.17,0-4.65-2.15-6.28-1.47-1.09-1.92-2.71-2.35-4.49-.35-1.45-1.6-2.69-2.47-4-.51-.77-1.07-1.51-1.72-2.42,2.55-1.41,2.87-3.59,2.69-6a5,5,0,0,1,.5-2.5q5-9.88,10-19.7c6.78-13.11,13.63-26.19,20.37-39.32,3.84-7.45,7.51-15,11.31-22.47C187.5,421.2,191,414.48,194.56,407.63Z" transform="translate(-0.06 -0.26)" />
</g>
</svg>
</div>
Here's how the full map looks: https://jsfiddle.net/darkosss/7umphzwn/

appears text when mouse is over D3

Hi everyone I am using sunburst of D3.js I want to include a text element inside each element.
For that my code is like this
var path = g.append("path");
if (data_key != "used"){
svg.selectAll("g").append("text")
.attr("dx", function(d){return -50})
.attr("dy", function(d){return 20})
.attr("class", "all_users")
.style("display", "none")
.text("text");
}
and it works my structure is like this
<g>
<path style="stroke: rgb(255, 255, 255); stroke-width: 1; fill: transparent; opacity: 0.3;" d="M0,63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,-63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,63.58917920822171Z"></path>
<text dx="-50" dy="20" class="all_users" style="display: none;">text</text>
</g>
I add display none to my text style, and I want to change the style (appears the text when the mouse is over this path)
for that purpose I use this
var g = gs.enter().append("g")
.on("mouseover", mostrar)
like this
function mostrar(d){
...
$(this).closest('text').css("display", "inherit");
}
but this $(this).closest('text') return an empty array []. Any idea how to get the text when my mouse is over this part of the plot.
Thanks in advances
First of all: this mix of D3 and jQuery is definitely not the best practice.
That being said, you can easily get the hovered element with this, and select the text with a simple selection. After that, set the style with style
d3.select(this).select("text").style("display", "inherit");
Here is a demo with your paths and texts:
var g = d3.selectAll("g");
g.on("mouseover", show).on("mouseout", hide);
function show() {
d3.select(this).select("text").style("display", "inherit");
}
function hide() {
d3.select(this).select("text").style("display", "none");
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<g transform="translate(50,75)">
<path style="stroke: black; stroke-width: 1; fill: transparent; opacity: 0.3;" d="M0,63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,-63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,63.58917920822171Z"></path>
<text dx="-50" dy="20" class="all_users" style="display: none;">text</text>
</g>
<g transform="translate(150,75)">
<path style="stroke: black; stroke-width: 1; fill: transparent; opacity: 0.3;" d="M0,63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,-63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,63.58917920822171Z"></path>
<text dx="-50" dy="20" class="all_users" style="display: none;">text</text>
</g>
<g transform="translate(250,75)">
<path style="stroke: black; stroke-width: 1; fill: transparent; opacity: 0.3;" d="M0,63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,-63.58917920822171A63.58917920822171,63.58917920822171 0 1,1 0,63.58917920822171Z"></path>
<text dx="-50" dy="20" class="all_users" style="display: none;">text</text>
</g>
</svg>

Replacing InnerHTML

I have a HTML file, which is then calling a javascript file. Basic function of the javascript file is to draw a svg file, and do modifications on it. for example
I am embedding the svg image in my JS file like this
this.my_object.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="img/gauge.png" width="122" height="127"/><g id="needle" transform="rotate(0,62,62)"><circle cx="62" cy="62" r="4" style="fill: #c00; stroke: none"/><rect transform="rotate(-130,62,62)" name="arrow" x="58" y="38" width="8" height="24" style="fill: #c00; stroke: none"/><polygon transform="rotate(-130,62,62)" points="58,39,66,39,62,30,58,39" style="fill: #c00; stroke: none"/></g><text id="value" x="35" y="103" focusable="false" editable="no" style="stroke:none; fill:#fff; font-family: monospace; font-size: 12px"></text></svg>';
Now, according to this post
Safari embeded SVG doctype
I cant inline svg image because then it wont work on safari. Now due to certain restrictions I cant embed svg file in html, it has to be accessed through javascript. Is there any way svg image can be used in javascript without using innerHTML, as finally the image has to be renedered on safari.
PS: This image has to be copied in the same folder when compiling.
https://sphotos-b.xx.fbcdn.net/hphotos-snc6/179594_10150982737360698_1827200234_n.jpg
I'm currently in Linux and can't test with Safari, but still will post the answer...
Try to do in this way.
HTML:
<div id="image-container"></div>​
JavaScript:
var container = document.getElementById('image-container'),
image = document.createElement('img');
image.src = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="img/gauge.png" width="122" height="127"/><g id="needle" transform="rotate(0,62,62)"><circle cx="62" cy="62" r="4" style="fill: #c00; stroke: none"/><rect transform="rotate(-130,62,62)" name="arrow" x="58" y="38" width="8" height="24" style="fill: #c00; stroke: none"/><polygon transform="rotate(-130,62,62)" points="58,39,66,39,62,30,58,39" style="fill: #c00; stroke: none"/></g><text id="value" x="35" y="103" focusable="false" editable="no" style="stroke:none; fill:#fff; font-family: monospace; font-size: 12px"></text></svg>';
container.appendChild(image);
​
UPDATE #1 - data URI encoding:
The usage of unencoded data URI might be failed in IE 8 and 9.
So you can determine the browser using navigator.userAgent and if it's IE >= 8,
then encode the string to Base64 before assigning it as value of image.src.
UPDATE #2 - using object tag:
var container = document.getElementById('image-container'),
imageObject = document.createElement('object');
imageObject.type = 'image/svg+xml';
imageObject.data = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="img/gauge.png" width="122" height="127"/><g id="needle" transform="rotate(0,62,62)"><circle cx="62" cy="62" r="4" style="fill: #c00; stroke: none"/><rect transform="rotate(-130,62,62)" name="arrow" x="58" y="38" width="8" height="24" style="fill: #c00; stroke: none"/><polygon transform="rotate(-130,62,62)" points="58,39,66,39,62,30,58,39" style="fill: #c00; stroke: none"/></g><text id="value" x="35" y="103" focusable="false" editable="no" style="stroke:none; fill:#fff; font-family: monospace; font-size: 12px"></text></svg>';
container.appendChild(imageObject);
​You can set either the data URI or direct link to .svg file location.
object DEMO
UPDATE #3 - CSS approach:
var container = document.getElementById('image-container');
container.style.width = '100px';
container.style.height = '100px';
container.style.backgroundPosition = 'center';
container.style.backgroundImage = 'url(\'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><image xlink:href="img/gauge.png" width="122" height="127"/><g id="needle" transform="rotate(0,62,62)"><circle cx="62" cy="62" r="4" style="fill: #c00; stroke: none"/><rect transform="rotate(-130,62,62)" name="arrow" x="58" y="38" width="8" height="24" style="fill: #c00; stroke: none"/><polygon transform="rotate(-130,62,62)" points="58,39,66,39,62,30,58,39" style="fill: #c00; stroke: none"/></g><text id="value" x="35" y="103" focusable="false" editable="no" style="stroke:none; fill:#fff; font-family: monospace; font-size: 12px"></text></svg>\')';
​
DEMO of CSS approach
UPDATE #4 - MIME type:
Comment by UnderDog:
I changed the datatype, and it worked.. but additionally I also had to
configure web.config file to add this:
<staticContent><mimeMap fileExtension=".svg" mimeType="image/svg+xml" /></staticContent>
The server should send correct Content-Type header.

Categories