dansan
Posts: 23
Joined: Mon Nov 28, 2022 2:23 pm

Reducing size of inline SVG path for maps

Hello!

I have a custom built SVG map of Europe, but it is quite detailed, and measures a whopping 600 kB (230 ~ gzipped).
I can run it through SVG Optimizer (SVGO), and reduce the size to 70 kB gzipped, however Highmaps doesn't support the resulting path in that case.
The only way to reduce the size that I've found working is to decrease decimal accuracy, but it also reduces the quality quite a bit.

Note: It's a custom map with some custom regions, and therefore I cannot use an existing low detail map.

So a few questions:

  • Is there a way to make Highmaps support the result from round/rewrite paths of SVGO?
  • If not, what's the proper way to minimize SVGs for Highmaps, decimal accuracy only?
  • Should I be converting the SVG somehow, use another format for example?
  • Should I just rebuild the map and reduce the size?
User avatar
KacperMadej
Posts: 4632
Joined: Mon Sep 15, 2014 12:43 pm

Re: Reducing size of inline SVG path for maps

Hello,

Why the resulting path is not supported? Please provide more details and a file/code example.

In general, the size of the same map in SVG is larger than in GeoJSON and TopoJSON is the smallest.
By size: SVG > GeoJSON > TopoJSON

If the map that you have is having a lot of small parts you could consider using drill down feature and loading the smaller regions for the zoomed-in / drilled-into area. Demo: https://www.highcharts.com/demo/maps/map-drilldown

Best regards,
Kacper Madej
Highcharts Developer
dansan
Posts: 23
Joined: Mon Nov 28, 2022 2:23 pm

Re: Reducing size of inline SVG path for maps

Hi!

I realize GeoJSON and TopoJSON might be smaller in size, but I have no idea how to convert my SVGs to these formats.
Is it possible to generate the GeoJSON/TopoJSON based on an image/svg? My maps use custom regions, so there wouldn't be any existing maps exactly like mine. Thanks for the info regarding drill down, I didn't know about it. Unfortunately it wouldn't fit my needs. I don't have a lot of small parts, just high detail for the SVGs.

The compressed SVG works everywhere else, but not in Highmaps, so I assume it has to do with how Highmaps works with modern SVGs.

I created two random examples to demonstrate my issue.
This one works:

Code: Select all

<svg width="646" height="646" viewBox="0 0 646 646" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="#D9D9D9" d="M226 99C245 30 339 -32 389 19C417 47 382 91 410 120C453 165 537 45 568 99C593 141 515 172 531 219C547 269 628 243 643 294C663 360 539 362 531 431C524 481 600 511 568 556C536 602 466 556 509 612C552 668 461 645 410 612C359 580 365 511 429 489C494 468 410 431 330 431C250 431 330 511 330 511C330 511 295 556 242 511C188 465 289 442 226 447C163 452 116 377 44 431C-29 484 4 326 44 294C84 262 140 345 163 277C185 209 240 258 258 219C278 175 212 145 226 99Z"/></svg>
This is the same SVG, ran through SVGO compression to reduce its size, and it doesn't work in Highmaps:
(NOTE: it rewrites/rounds paths)

Code: Select all

<svg width="646" height="646" viewBox="0 0 646 646" fill="none" xmlns="http://www.w3.org/2000/svg" ><path fill="#D9D9D9" d="M226 99c19-69 113-131 163-80 28 28-7 72 21 101 43 45 127-75 158-21 25 42-53 73-37 120 16 50 97 24 112 75 20 66-104 68-112 137-7 50 69 80 37 125-32 46-102 0-59 56s-48 33-99 0c-51-32-45-101 19-123 65-21-19-58-99-58s0 80 0 80-35 45-88 0c-54-46 47-69-16-64s-110-70-182-16c-73 53-40-105 0-137s96 51 119-17c22-68 77-19 95-58 20-44-46-74-32-120Z"/></svg>
In Highmaps I include the paths with the format:

Code: Select all

data:{[name, value, path]}
Examples:

Code: Select all

{
  name: "Default path map",
  value: 100,
  path: "M226 99C245 30 339 -32 389 19C417 47 382 ...",
}
However, this version doesn't seem to work:

Code: Select all

{
  name: "Compressed path map",
  value: 100,
  path: "M226 99c19-69 113-131 163-80 28 28-7 72 21 101 43 ...",
}
User avatar
KacperMadej
Posts: 4632
Joined: Mon Sep 15, 2014 12:43 pm

Re: Reducing size of inline SVG path for maps

There are some limitations for the path value, namely "For compatibily with old IE, not all SVG path definitions are supported, but M, L and C operators are safe." (source: https://api.highcharts.com/highmaps/ser ... .data.path). There is currently a work being done towards removing any old IE dependency or build-in support and this limitation is planned to be removed in Highcharts version 11.
Kacper Madej
Highcharts Developer
dansan
Posts: 23
Joined: Mon Nov 28, 2022 2:23 pm

Re: Reducing size of inline SVG path for maps

KacperMadej wrote: Thu Dec 22, 2022 2:14 pm There are some limitations for the path value, namely "For compatibily with old IE, not all SVG path definitions are supported, but M, L and C operators are safe." (source: https://api.highcharts.com/highmaps/ser ... .data.path). There is currently a work being done towards removing any old IE dependency or build-in support and this limitation is planned to be removed in Highcharts version 11.
Hello!

I was wondering, now that version 11 is out, why it still doesn't work?
I'm getting some of the same errors, and I was kinda hoping this version would fix the issue.
EG. "ghmaps.src.js:9674 Error: <path> attribute d: Expected number, "…9 6 5 v -4 c -1 Z".
User avatar
KacperMadej
Posts: 4632
Joined: Mon Sep 15, 2014 12:43 pm

Re: Reducing size of inline SVG path for maps

Hi,

The operators are working better now but the script that is processing the path is not handling the lack of spaces between path elements (mostly or only the lack of space before the minus sign when numbers are given as e.g. "19-69" instead of "19 -69"). If there are spaces added in between each operator and value then it seems to be working fine - https://jsfiddle.net/BlackLabel/dygpu1sz/

This should work correctly out of the box but if you need this to work now then this could be a workaround solution for you.

As this should work here's a bug report: https://github.com/highcharts/highcharts/issues/18949
You could track it to see the future progress about solving it.

Best regards,
Kacper Madej
Highcharts Developer
dansan
Posts: 23
Joined: Mon Nov 28, 2022 2:23 pm

Re: Reducing size of inline SVG path for maps

Hi,

If I remove all but the edited map from your fiddle then it still doesn't work. I believe your example is only showing the original, uncompressed path, but with the labels from the compressed one for some reason. Can you verify?
dansan
Posts: 23
Joined: Mon Nov 28, 2022 2:23 pm

Re: Reducing size of inline SVG path for maps

See fiddle for example with space between values (no map gets drawn):
https://jsfiddle.net/sxnLtb89/
User avatar
KacperMadej
Posts: 4632
Joined: Mon Sep 15, 2014 12:43 pm

Re: Reducing size of inline SVG path for maps

Looks like a different, but connected, problem - reported a bug here: https://github.com/highcharts/highcharts/issues/18972

This could be resolved by parsing the SVG path in JS code after it is loaded into the page so you could still have the option to load a smaller file for the map. The conversion from relative to absolute SVG commands is not supported and would have to be done via a 3rd party code.

This requires some additional custom code that is not stable but could be used as a workaround until there is a proper fix provided.
Demo: https://jsfiddle.net/BlackLabel/xdhgr7jn/1/

Instead of changing the relative to the absolute commands the bounds is hard coded and could be adjusted manually - so if you have a limited number of maps then it should be a usable workaround.
Kacper Madej
Highcharts Developer

Return to “Highcharts Maps”