Reputation: 97
I've got an SVG map and I want to show a specific city using ID in HTML with specified width and height. How can I accomplish this?
Here is the SVG Image:
<?xml version="1.0" encoding="utf-8"?>
<!-- (c) ammap.com | SVG map of Afghanistan - High -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:amcharts="http://amcharts.com/ammap" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
>
<defs>
<style type="text/css">
.land
{
fill: #CCCCCC;
fill-opacity: 1;
stroke:white;
stroke-opacity: 1;
stroke-width:0.5;
}
</style>
<amcharts:ammap projection="mercator" leftLongitude="60.517000" topLatitude="38.490877" rightLongitude="74.889862" bottomLatitude="29.377200"></amcharts:ammap>
</defs>
<g>
<path id="AF-PIA" title="Paktya" class="land" d="M457.09,266.51L454.16,264.78L453.82,264.65L453.52,264.58L453.25,264.56L452.99,264.64L452.7,264.83L451.01,266.9L448.31,268.59L447.77,268.79L447.19,268.77L447.02,268.56L447.01,268.17L447.07,267.74L447.1,267.38L447.03,267.09L446.86,266.89L446.48,266.67L446.04,266.5L444.39,266.1L442.23,265.94L441.63,266L440.81,265.99L440.34,266.07L439.88,266.22L438.81,266.89L438.5,267.21L438.11,268.39L437.39,269.89L436.89,270.59L436.07,271.52L435.53,272L434.94,272.34L433.05,274L432.78,274.28L430.19,277.03L429.84,277.74L429.57,278.1L428.03,279.16L423.18,281.44L418.47,284.98L417.81,285.49L417.21,286.12L416.45,287.68L415.91,289.28L414.98,290.96L414.34,291.52L414.02,291.74L413.46,292.02L412.81,292.24L412.05,292.36L411.47,292.36L410.47,291.94L409.71,291.8L402.52,291.74L402.35,293.86L402.44,295.92L402.56,297L402.75,297.7L403.33,298.79L403.76,299.84L403.87,300.41L403.81,300.91L402.63,303.52L402.35,304.52L405.89,303.21L407.14,303L408.05,303.51L408.56,303.61L408.92,303.52L409.29,303.36L409.56,303.33L409.81,303.37L410.89,303.86L411.16,304.07L411.35,304.28L411.87,305.3L412.64,306.36L412.8,306.68L412.87,307.07L412.88,307.67L412.68,310.41L412.72,311.59L413.14,315L413.12,315.31L413.07,315.59L413.06,316.08L413.25,316.72L413.5,318.04L413.73,318.42L413.87,318.45L414.03,318.44L414.34,318.39L415.06,318.09L415.74,317.66L417.05,316.41L419.02,315.24L421.41,314.16L423.07,313.11L423.47,312.7L423.49,312.54L423.47,312.38L423.43,312.2L423.39,311.96L423.38,311.6L423.49,311.45L423.64,311.38L423.93,311.4L424.25,311.48L424.44,311.57L424.64,311.72L424.78,311.86L425.17,312.18L426.63,313.34L427.64,313.54L428.52,313.41L430.74,312.62L431.52,312.54L431.86,312.71L432.05,312.83L433.02,313.15L433.26,311.96L433.42,311.68L434.08,310.94L434.93,309.91L435.13,309.19L435.26,308.56L435.51,308.17L438.13,305.82L439.25,305.15L439.56,304.77L440.02,304.04L440.29,303.35L441.43,299.65L440.61,298.76L440.56,298.05L440.83,297.36L441.61,295.85L441.87,295.14L443.36,293.89L444.1,293.43L444.83,293.07L447.82,292.16L451.16,291.83L451.29,291.85L451.36,291.89L452.16,292.51L453.62,290.29L453.88,290.06L454.33,289.76L454.71,289.71L455.86,289.3L456.66,288.79L457.78,288.3L459.18,287.45L460.38,287.06L460.71,286.84L461.52,285.94L461.75,285.48L461.88,285.07L461.89,284.22L460.73,284.06L460,283.6L459.5,282.48L459.16,281.34L458.73,280.46L457.58,278.76L457.15,277.83L456.5,275.62L456.07,274.85L454.65,273.42L454.35,272.56L454.99,271.71L455.85,270.82L455.94,269.95L455.78,269.07L455.88,268.15L456.69,267.33L457.47,267.06L457.09,266.51z"/>
<path id="AF-WAR" title="Wardak" class="land" d="M384.44,232.47L383.52,232.32L383.24,232.24L383.03,231.97L382.86,231.71L382.55,229.98L382.47,229.09L382.33,228.63L382.09,228.07L379.59,225.53L379.38,225.05L379.18,224.38L379.08,223.22L378.77,222.11L373.18,225.02L371.81,226.05L371.11,227.21L370.1,228.31L369.57,228.75L369.18,228.91L368.64,228.6L368.28,228.5L367.86,228.51L367.3,228.64L366.95,228.86L366.62,229.22L366.3,229.71L365.35,230.8L365.15,231.1L364.9,231.84L363.81,234.16L360.83,233.82L351.91,231.29L350.78,231.09L348.95,231.34L347.56,231.3L346.76,231.18L345.83,230.9L344.34,230.76L343.94,230.64L343.71,230.41L343.47,230.11L343.08,229.79L342.15,229.38L341.6,229.21L341.15,229.14L340.86,229.18L340.57,229.28L339.2,230.12L338.89,230.25L334.64,231.11L331.94,231.48L331.54,231.62L331.06,231.86L330.89,232.09L330.64,232.73L331.12,234.37L331.63,235.1L333.08,236.32L333.36,236.74L333.47,237.19L333.41,238.21L333.32,238.56L333.15,238.81L332.31,239.48L332.07,239.6L331.8,239.67L330.5,239.81L330.19,239.93L329.89,240.12L329.64,240.37L329.4,240.7L329.15,241.14L328.91,241.72L328.6,242.66L328.61,243.38L328.73,243.88L329,244.23L329.31,244.48L329.65,244.66L329.98,244.79L333.36,245.1L335.49,244.99L335.98,245.03L336.43,245.17L336.92,245.55L337.16,245.94L337.29,246.35L337.34,246.72L337.33,247.1L337.27,247.41L337.15,247.64L337,247.82L336.79,247.95L336.61,248.04L336.22,248.15L335.14,248.76L335.03,248.99L335,249.3L335.18,249.45L335.46,249.55L337.02,249.74L337.62,249.91L342.4,252.09L342.97,252.54L343.14,252.88L342.66,253.39L341.96,254.34L341.81,254.66L341.6,255.23L341.47,255.42L341.27,255.58L337.37,257.09L337.03,257.42L336.71,257.92L336.41,259.11L336.41,259.73L336.61,260.23L337.48,261.04L339.77,261.35L340.58,261.34L342.09,260.82L342.33,260.64L342.43,260.45L342.72,259.11L342.91,258.82L343.23,258.5L343.85,258.01L344.28,257.78L344.67,257.65L347.96,256.95L349.18,256.89L350.67,257.23L352.47,257.92L353.97,258.96L355.19,260.12L355.72,260.39L356.38,260.55L358.62,260.72L359.26,260.68L360,260.53L363.09,259.45L364.48,258.71L365.18,258.13L365.44,258.04L365.78,257.85L365.94,257.71L366.63,257.26L367.69,257.51L368.41,258L369.87,259.38L370.26,259.98L370.51,260.53L370.99,263.15L371.02,263.6L370.94,264.45L370.96,264.94L371.02,265.45L371.18,266.09L371.23,266.52L371.21,266.95L371.14,267.33L371.17,267.84L371.29,268.43L371.72,269.89L371.75,270.71L372.1,271.71L372.59,272.03L373.2,272.2L376.23,273.43L376.48,273.63L376.98,274.49L379.31,275.94L380.02,276.71L380.2,277L384.34,281.37L384.66,281.65L384.95,281.8L385.19,281.81L385.67,281.77L386.1,281.67L387.18,281.63L387.63,282.91L387.62,283.24L387.57,283.7L387.17,284.87L386.94,285.83L386.93,286.34L387,286.71L387.09,286.84L387.22,286.99L387.65,287.29L388.27,287.57L390.21,288.05L390.72,288.05L391.52,287.96L391.94,287.79L396.04,285.38L396.37,285.11L398.42,282.56L399.58,281.42L401.21,279.57L401.41,279.23L401.79,278.36L402.11,276.27L402.03,275.83L401.86,275.29L401.36,274.66L401.28,274.5L401.26,274.41L401.38,274.25L402.02,273.01L402.57,272.26L403.76,271.24L404.42,270.88L405.11,270.6L407.44,270.12L407.87,269.97L408.07,269.8L408.13,269.57L408.13,269.46L408.04,269.13L407.34,267.38L407.13,267.14L406.62,266.7L406.01,266.3L404.89,265.29L404.42,264.6L404.18,263.94L404.35,261.84L404.81,259.85L405.84,257.61L406.7,256.46L407.73,255.5L408.4,255.04L409.83,251.64L410.79,250.14L412.06,248.68L411.8,247.79L410.95,244.93L409.29,243.69L408.95,243.52L407.4,243.12L407.13,243L406.92,242.77L406.75,242.39L406.5,241.62L406.28,241.11L406.07,240.74L405.89,240.24L405.8,239.53L405.88,237.92L406.38,235.96L406.3,234.66L406.9,232.62L406.28,232.8L405.52,232.66L404.03,231.99L402.35,231.51L401.64,231.15L401.26,231.1L399.79,231.19L399.15,231.12L398.45,230.85L397.58,230.18L397.34,230.04L397.13,229.95L396.28,229.72L395.6,229.41L392.02,228.53L391.54,228.54L390.85,228.83L387.99,230.71L386.5,231.46L385.7,231.71L385.44,231.87L385.03,232.3L384.78,232.43L384.44,232.47z"/>
</g>
</svg>
I want to display a city by ID from the above map. The result should look like the following image for ID="AF-PIA":
I've tried the following but failed to get a city:
<object data="/assets/img/illustrations/afghanistan.svg#AF-PIA" type="image/svg+xml"
width="100%" height="100%">
NOTE: I have limited the number of cities to two in the above SVG code.
Upvotes: 2
Views: 3711
Reputation: 21183
Taking all comments and answers:
:not
selector to hide unwanted citiesgetBBox()
to get city dimensionsviewBox
with BBox values<display-city code="DAY">
<style>
you want (in the SVG), and it doesn't bleed to other components.<template>
for brevitystroke-width
differences, because the viewBox dimensions differ !!<style>
display-city { display: block; background: pink }
cities{ /*abusing an "UknownElement, just because we can" */
display:grid; grid-template-columns:repeat(3,1fr); gap:5px;
}
</style>
<cities>
<display-city code="PAR"></display-city>
<display-city code="DAY"></display-city>
<display-city code="KAB"></display-city>
</cities>
<script>
customElements.define("display-city", class extends HTMLElement {
connectedCallback() {
setTimeout(() => { // make sure all DOM is parsed
let country = document.querySelector(`#AF`).content.cloneNode(true);
let code = this.getAttribute("code");
this.attachShadow({mode:"open"})
.innerHTML = `<style>path:not([id="AF-${code}"]){display:none}</style>`;
this.shadowRoot.append(country);
let svg = this.shadowRoot.querySelector("svg");
let {x,y,width,height} = svg.querySelector(`#AF-${code}`).getBBox();
svg.setAttribute("viewBox", `${x} ${y} ${width} ${height}`);
})
}
});
</script>
<template id="AF">
<style>
path {
fill: #CCCCCC;
fill-opacity: 1;
stroke: white;
stroke-opacity: 1;
stroke-width: 0.5;
}
</style>
<svg viewBox="0 0 700 535">
<path id="AF-PAR" d="m424 186-1-1-2 1v1l-1 1-3 1-1 2-1 1-2 1h-1v1l-3 2-3-2-1 1h-1l-1 1v1l-1 1-1 1v1l-4 2v1h-3v2h1l-1 1-1 1h-10l-4-1-1 1-1 1-2 1h-1v1l3 2v9l1 1h1v3l1 1 2 2v1l1 1v2h3l1-1h1l3-2h5v1h2v1h4v1h2l2 1h1l1-3-1-2 2-3v-1l2-4 2-3v-1l3 1h1l4 1 2-1h1l1 1 1 1 2 1v2l2 2v1l1 1h1l1 1 1 2 1 3v2l1 1 2-1h1l1-1v-2h3v-3l-1-1-1-1v-10l-2-1-2-1h-3l-1-1-1-2h-1v-1h-2l-1-1h-1v-3l1-3-1-2h-2v-2l1-1v-12h-2z" />
<path id="AF-KAP" d="m434 201-2-1h-4l-1 1 1 2-1 3v3h1l1 1h2v1h1l1 2 1 1h3l2 1 2 1v10l1 1 1 1v3l1 1 3-1h2v-2l2-6h1l2-1 1-1h1v-1l1-1 1-1v-2l-1-1-1-3-1-1v-2l-2-1-1-2-1-2-1-2-1-1h-3l-2-1-3 1h-7z" />
<path id="AF-KAB" d="m416 217-3-1v1l-2 3-2 4v1l-2 3 1 2-1 3-1 2v6l1 1v1l2 1 2 1 1 3v1l7 2h4l4-3h1l1 2 1 1v1l1 1 2 2v1l1 1v1l1 1 1 2 1-1v-3l1-1 3-1 3-3 1-3 1-1v-2h1l6-1v-5h1v-4l-1-1 1-1 1-1v-5h1l2-2v-1h1v-2l-2-4-1 1v1h-1l-1 1-2 1h-1l-2 6v2h-2l-3 1-1-1h-3v2l-1 1h-1l-2 1-1-1v-2l-1-3-1-2-1-1h-1l-1-1v-1l-2-2v-2l-2-1-1-1-1-1h-1l-2 1-4-1h-1z" />
<path id="AF-DAY" d="M284 247h-1v-1h-1l-3-1h-1v1h-1l-1 2h-8v1h-1v1h-5l-7-1h-10l-1 2v3l-1 1v3h1v1l-1 1v2l-1 1v2h1v2h2v4h-1v1l-1 1v1l-1 1h-1l-2 1v3h1l1 1v1h1l1 1v1l1 2v3l1 1h1v1l1 1 1 1h-1l-1 1-1 1-2 2-2 1-1 2h-1l-1 1-1 1v1h1v1l-2 1h-3l-1 1-2 1 1 1 1 1h2v2l1 2 1 1 1 1v6h-1v2h2l1 1h1v-1h2l1 1v-3l-1-1h6l3 2h6v-1l1-1h1l2 2 1 1 6 1 2 1h1v-3l1-3v-1l1-1 1-1h3l5-5h1l1-1h1l1 1h1l3-1h1l1 1v1l1 1v1h1l1 1 3-2 2-1h2l1-1 1-1v1l1 1v1h2l1-1 1-3v-4l1-1v-2l-2-4v-2l1-1 1-1 5-2 2-1h2l4-1 1-1h1l1-1 1-1v-1l4-3 1-1 1-2 1-1 1-1-1-2v-2h-1v-1h-1 1v-1h1v-3l-1-1v1h-1v1h-4l-2 1-1 1v1h-1v-1h-3l-3 2-2-1-1-1-9-2h-3v1h-1l-2 1h-1l-2-2-3-3h-1v-5l2-2v-1l-1-2v-3l1-1h1v-1l-1-1-2-1h-2v-1l1-2h-1l-6 1h-1z" />
</svg>
</template>
Upvotes: 0
Reputation: 21821
Define a <svg>
element inside your HTML page, giving it the desired size, and reference the path from the external SVG:
<style>
#city-wrapper {
width: 500px;
height: 500px;
fill: #CCCCCC;
}
</style>
<svg id="city-wrapper" viewBox="402.35 264.55 59.54 53.89">
<use href="/assets/img/illustrations/afghanistan.svg#AF-PIA" />
</svg>
Note that you will need the viewBox
in advance of writing that code. Paul LeBeau's answer told you how to to that. The viewBox makes sure the path is blown up to fill the wrapper element, otherwise it would remain so small that the rest of the map would also fit.
If you are willing to write a bit of Javascript, you can also leave out the viewBox
attribute initially and add it after the reference has been loaded. The needed bounding box can then be queried by script:
window.addEventListener('load', function() {
const svg = document.querySelector('#city-wrapper');
const {x, y, width, height} = svg.querySelector('use').getBBox();
svg.setAttribute('viewBox', [x, y, width, height].join(' '));
});
Upvotes: 3
Reputation: 101830
The 17.3 Linking into SVG content: IRI fragments and SVG views section of the SVG specification may contain what you need.
For instance, you can get the bounds of the SVG element(s) you want to focus on and use a link such as:
data="/assets/img/illustrations/afghanistan.svg#viewBox(402.35,264.55,59.54,53.89)
You can get the bounds by highlighting the element in the web inspector. Then type $0.getBBox()
into the console.
That's what I did to get the values I've used above. These bounds values are for #AF-PIA
.
Upvotes: 0