Using SVG graphics as data labels in a HighChart stacked column chart

I am attempting to generate a stacked column chart in Highcharts with SVG images as x-axis labels, similar to the image displayed here:

https://i.stack.imgur.com/y5gL1.png

I have managed to achieve this with individual data points per label (non-stacked data), but when I switch to an array input, the data fails to render. This example is functional: https://jsfiddle.net/jakobhl/krx4e5pm/2/

var dataName = function(imgSrc) {
  return '<span><img src=' + imgSrc + ' ' + 'style="width: 40px; height: 40px;"/><br></span>';
};

var data2016 = [
  [11, dataName("https://image.flaticon.com/icons/svg/197/197571.svg")],
  [11, dataName("https://image.flaticon.com/icons/svg/197/197408.svg")],
  [11, dataName("https://image.flaticon.com/icons/svg/197/197375.svg")],
  [14, dataName("https://image.flaticon.com/icons/svg/197/197374.svg")],
  [12, dataName("https://image.flaticon.com/icons/svg/197/197484.svg")],
];


Highcharts.chart('container', {
  chart: {
    type: 'column'
  },
    plotOptions: {
        column: {
            stacking: 'normal',
            dataLabels: {
                enabled: true
            }
        }
    },
  xAxis: {
    tickmarkPlacement: 'on',
    lineWidth: 0,
    type: 'category',
    labels: {
      useHTML: true,
      align: 'center'
    }
  },

  series: [{
    keys: ['y', 'name'],
    data: data2016,
  }]
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>

<div id="container"></div>

However, the following does not work: https://jsfiddle.net/jakobhl/2rfa645x/3/

var dataName = function(imgSrc) {
  return '<span><img src=' + imgSrc + ' ' + 'style="width: 40px; height: 40px;"/><br></span>';
};

var data2016 = [
  [[11, 15], dataName("https://image.flaticon.com/icons/svg/197/197571.svg")],
  [[12, 15], dataName("https://image.flaticon.com/icons/svg/197/197408.svg")],
  [[13, 15], dataName("https://image.flaticon.com/icons/svg/197/197375.svg")],
  [[41, 15], dataName("https://image.flaticon.com/icons/svg/197/197374.svg")],
  [[11, 15], dataName("https://image.flaticon.com/icons/svg/197/197484.svg")],
];

Highcharts.chart('container', {
  chart: {
    type: 'column'
  },
    plotOptions: {
        column: {
            stacking: 'normal',
            dataLabels: {
                enabled: true
            }
        }
    },
  xAxis: {
    tickmarkPlacement: 'on',
    lineWidth: 0,
    type: 'category',
    labels: {
      useHTML: true,
      align: 'center'
    }
  },

  series: [{
    keys: ['y', 'name'],
    data: data2016,
  }]
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>

<div id="container"></div>

Is there a way to stack the data by country while still using SVGs as labels?

Credits and thanks go to the jsfiddle user BlackLabel for the inspiration.

Answer №1

If you want to include a new value, make sure to adjust the data format that Highcharts requires. For instance, if the additional value is labeled as x, follow these steps:

var newData = [
    [
        11, 15, dataLabel("https://image.flaticon.com/icons/svg/197/197571.svg")
    ],
    ...
];


Highcharts.chart('container', {
    ...,
    series: [{
        keys: ['y', 'x', 'name'],
        data: newData
    }]
});

Check out this live demo: https://jsfiddle.net/BlackLabel/vubjn8od/

For more information, refer to the API Reference: https://api.highcharts.com/highcharts/series.column.keys

Answer №2

I never did figure out why the initial solution wasn't working, but I found a successful workaround by utilizing categories instead of series: Check it out here

var dataName = function(imgSrc) {
  return '<span><img src=' + imgSrc + ' ' + 'style="width: 40px; height: 40px;"/><br></span>';
};

Highcharts.chart('container', {
    chart: {
        type: 'column'
    },
    title: {
        text: 'Stacked column chart'
    },
    xAxis: {
        labels: {
      useHTML: true,
      align: 'center'
    },
        categories: [dataName("https://image.flaticon.com/icons/svg/197/197571.svg"), dataName("https://image.flaticon.com/icons/svg/197/197408.svg"), dataName("https://image.flaticon.com/icons/svg/197/197375.svg"), dataName("https://image.flaticon.com/icons/svg/197/197374.svg"), dataName("https://image.flaticon.com/icons/svg/197/197484.svg")]
    },
    yAxis: {
        min: 0,
        title: {
            text: 'Total fruit consumption'
        },
        stackLabels: {
            enabled: true,
            style: {
                fontWeight: 'bold',
                color: ( // theme
                    Highcharts.defaultOptions.title.style &&
                    Highcharts.defaultOptions.title.style.color
                ) || 'gray'
            }
        }
    },
    legend: {
        align: 'right',
        x: -30,
        verticalAlign: 'top',
        y: 25,
        floating: true,
        backgroundColor:
            Highcharts.defaultOptions.legend.backgroundColor || 'white',
        borderColor: '#CCC',
        borderWidth: 1,
        shadow: false
    },
    tooltip: {
        headerFormat: '<b>{point.x}</b><br/>',
        pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
    },
    plotOptions: {
        column: {
            stacking: 'normal',
            dataLabels: {
                enabled: true
            }
        }
    },
    series: [{
        name: 'John',
        data: [5, 3, 4, 7, 2]
    }, {
        name: 'Jane',
        data: [2, 2, 3, 2, 1]
    }, {
        name: 'Joe',
        data: [3, 4, 4, 2, 5]
    }]
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>

<div id="container"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for keeping a div element at the top of the page

I am looking to have a div stick to the top of the page when someone scrolls down When the page is scrolled, the green div with class stickdiv should automatically stick to the top var left = document.getElementsByClassName("stickdiv"); for( var i = 0; ...

Using React with TypeScript to ensure that at least one key of a type is not null, even if all keys are optional

Within my Typescript code, I have defined an event type that includes various time parameters: export type EventRecord = { name: string; eta: string | null; assumed_time: string | null; indicated_time: string | null; }; I also have a func ...

Guide to ensuring modal box only appears once all criteria are satisfied

On my website, I have a form that requests the user's personal information. After filling out the form, a modal pops up with a "Thank you for signing up" message. The issue is that even if all fields are left blank and the button is clicked, the modal ...

I am attempting to trigger a mouseup event following a mousedown action

elements[0].onmousedown = function(){ console.log('screen clicked.'); triggerMouseUp(); }; I just need to incorporate a function in my code that simulates mouseup event, even when the user is still holding down the click button. e ...

finding the node version in a code repository

Is it possible to determine the targeted node version (4 or 6) of a Node.js application by examining its code? I'm currently reviewing this: https://github.com/jorditost/node-postgres-restapi ...

Sanity.io's selection of schema field types for efficient and convenient

Hey there, guys! I recently started using Sanity.io and I'm curious whether there's a way to enhance my code efficiency and reuse certain fields across different schemas. I had an idea that goes something like this: cars.ts: export default { ...

Exploring the best practices for loading state from local storage in VueJS/NuxtJS by leveraging the "useLocalStorage" utility

When attempting to utilize useLocalStorage from pinia, I am encountering an issue where the data in the store's state is not fetched from local storage and instead defaults to the default value. Below is the code snippet from my store method: import ...

Is there a way to use JavaScript or jQuery to identify if Firefox is blocking mixed content

Is there a way to detect when Firefox (or any browser) is blocking mixed content using JavaScript or jQuery? To learn more about Firefox's mixed content blocking feature, visit: The backstory: My company has an external vendor that handles the onli ...

Generate unique div elements randomly using jQuery and Javascript to populate a container

My website has a section that spans 100% width and is 450 pixels tall. This is the HTML structure... <section class="interactive-banner"> <figure></figure> </section> I am aiming for each 'figure' element to be 150 ...

The validations continue to function properly even when HTML has been removed

In my form, I have implemented an "addmore" functionality that allows users to dynamically add a set of HTML input fields. Users can also remove the added rows if needed. While everything is functioning correctly, I am encountering an issue where validatio ...

Running JavaScript within Electron is a straightforward process

Looking to create an Electron application that can take code entered into a text area, execute it, and display the result. Any advice on converting the text to JavaScript and running it? ...

Navigating efficiently with AngularJS directives

Hello, I am currently searching for a solution to dynamically modify the navigation links within the navigation bar based on whether a user is logged in or not. Of course, a logged-in user should have access to more pages. I have developed a UserService t ...

Exploring the Possibilities: Incorporating xlsx Files in Angular 5

Is there a way to read just the first three records from an xlsx file without causing the browser to crash? I need assistance with finding a solution that allows me to achieve this without storing all the data in memory during the parsing process. P.S: I ...

The dimensions of the d3 div remain constant despite any modifications to its attributes

In my angular application, I am trying to customize the width and height of div elements in d3 when I select a legend. Strangely, I am able to adjust the width and height of the svg element without any issues. Here is the issue illustrated: Below is the c ...

Characteristics within the primary template element of a directive

I'm having an issue with the following directive code: .directive('myDirective', function () { restrict: 'E', replace: true, transclude: true, scope: { label: '@', ngModel: '=', ...

Assigning a value to an attribute as either a "string" or null within JSON Schema while specifying a maximum length

I'm currently working on crafting a JSON schema that supports a nullable attribute. I am aiming to have the ability for specific JSON structures like this one be considered valid: { "some_name" : null } This is how my schema looks like: { "type" ...

I'm looking for assistance on how to set the minimum height using jQuery. Can anyone provide

My attempt to use the minHeight property in one of my divs is not successful, and I am unsure why... <div id="countries"> <div class="fixed"> <div class="country" style="marging-left:0px;"></div> <div class="country"&g ...

Execute a JavaScript function prior to initiating an AJAX request

To streamline the process of making AJAX calls in my .NET project, I have developed a function called checkConnection that checks for internet connectivity before each call. However, currently, I am manually calling this function on every button click that ...

Issue with Webpack: error message "Cannot read property 'readFile' of undefined" is causing no output files to be generated

When utilizing version webpack > 5, the configuration for my appDevMiddleware.js is as follows: const path = require('path'); const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware' ...

Can JavaScript values be passed into CSS styles?

I am currently working on dynamically updating the width of a CSS line based on a JavaScript value (a percentage). The line is currently set at 30%, but I would like to replace that hard-coded value with my JavaScript variable (c2_percent) to make it mor ...