3

I'm adding an SVG-based graphic to my chart by way of chart.renderer.image() as shown in this jsfiddle example:

$(function () {
    $('#container').highcharts({

        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },

        series: [{
            data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
        }]

    }, function (chart) { // on complete

    chart.renderer.image('https://cloud3squared.com/files/example.svg', 100, 100, 70, 70)
            .add();
    });
});

In the original SVG file itself, I can change the fill colour of the graphic in the SVG with the following:

style="fill:#ffffff;fill-opacity:1"

That changes it from black to white. But I'd like to be able to set this colour dynamically, in the code. I've tried various ways without success. Any ideas?

drmrbrewer
  • 11,491
  • 21
  • 85
  • 181
  • Not possible with an image. – Robert Longson Apr 09 '16 at 09:03
  • But it's not really an image. It's SVG, with elements that I'm hoping are dynamically modifiable either on adding the SVG, or after. For example, something like http://stackoverflow.com/a/13225606/4070848 – drmrbrewer Apr 09 '16 at 09:07
  • The function name implies it's an image and the documentation confirms it's an image: http://api.highcharts.com/highcharts#Renderer – Robert Longson Apr 09 '16 at 09:10
  • Are you certain that the SVG is not preserved on adding via `image()`? Is it really converted to a bitmap? Any other way of adding the SVG to the chart without losing the SVG and hence the ability to modify the elements programatically? – drmrbrewer Apr 09 '16 at 09:16
  • As far as external access is concerned it might as well be a raster. There are lots of ways, but they are not necessarily available through highcharts. – Robert Longson Apr 09 '16 at 09:21
  • highcharts renderer api also has a 'g' and a 'path' method, with a little workaround you can use these to add the svg – maioman Apr 09 '16 at 11:12

1 Answers1

3

If you are adding image using Highcharts Renderer, then an image will be added. To add SVG element that will be able to dynamically change its attributes use another Renderer methods that are creating SVG elements like:

etc.

Your image is a set of paths, so it should be easy to do. Example: http://jsfiddle.net/32Lqpe14/

If you want you could add all elements to a custom group.

EDIT: It is possible to recreate SVG elements from an original SVG image using Highcharts Renderer. You could load SVG dynamically using jQuery, but CORS problem might be an issue, so it is also possible to use SVG from HTML:

Demo: http://jsfiddle.net/2mch6ja3/

(For more info see comments below.)

Kacper Madej
  • 7,846
  • 22
  • 36
  • However, where you have (lots) of existing SVG graphics, are you suggesting that you port all of those into 'native' highcharts path commands? Is there any way of using the existing SVG, somehow embedding that SVG direct? – drmrbrewer Apr 11 '16 at 12:38
  • @drmrbrewer Unfortunately there is no default API in Highcharts that would allow including an external SVG as a part of chart's SVG. However, you could try to appendChild if you have SVG element(s) - more info: http://stackoverflow.com/questions/16488884/add-svg-element-to-existing-svg-using-dom – Kacper Madej Apr 11 '16 at 14:55
  • What about sticking with `renderer.image()` and using something like this: http://stackoverflow.com/a/11978996/4070848 (or this equivalent post: http://stackoverflow.com/a/24933495/4070848) – drmrbrewer Apr 11 '16 at 15:31
  • 1
    I am getting filed $.get loading and CORS error: `"XMLHttpRequest cannot load http://cloud3squared.com/files/example.svg. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access."`, but if you load the SVG from your/same server there shouldn't be a problem. I am using Chrome ["Allow-Control-Allow-Origin: *"](https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en) plugin to resolve it in the jsFiddle. I load SVG via jQuery and rebuild path by path using 1/2 – Kacper Madej Apr 12 '16 at 08:54
  • (regarding removed comment: ) Access-Control-Allow-Origin issue doesn't appear to be fixed - same error in console. With mentioned plugin all is fine. If the file is loaded into web page, then it is also possible to use it in Highcharts - http://jsfiddle.net/2mch6ja3/ – Kacper Madej Apr 12 '16 at 11:07
  • Yes, I realised after posting my comment that the access control issue hadn't been fixed... but hopefully it now has (even without using the plugin). And WOW the jsfiddle works very well... exactly the sort of thing I was looking for. It would be great if you could add that solution (loading the svg and converting into "native" highcharts path) to your answer, and I will mark it as correct. Thanks so much. I'll see how it performs in my "real world" code, but it looks promising. – drmrbrewer Apr 12 '16 at 12:09
  • For a bonus point: would be great if the example jsfiddle would take into account the `width`, `height` and `viewBox` attributes in the original SVG. Particularly the `viewBox` attribute, since that's an important property in determining what, within the `width`x`height` box, is intended to be shown. – drmrbrewer Apr 13 '16 at 08:44
  • @drmrbrewer You could try to play with grouping, clippaths and transforming. Note than using all will have consequences like transforming after clipping - see example: http://jsfiddle.net/srkzrfg9/ – Kacper Madej Apr 13 '16 at 11:26
  • OK, thanks for the hints. Got it working nicely now. – drmrbrewer Apr 13 '16 at 15:26