Search code examples
kendo-uikendo-ui-angular2kendo-chartkendo-react-ui

Adding tooltip to each tile in a kendo stacked bar chart


I have created a stacked bar chart using Kendo UI. I want to show tooltip for each tile in stacked bar chart and use another array for this purpose which contains the values to be shown as tooltip.

For ex: When I hover over, USA for year 2000, tooltip should show, NYC: 60% & SFO: 40% (as shown in image).

Here is a fiddle.

This is what I am trying to achieve (in this case showing tooltip for year 2000 for USA): enter image description here

Problem is when I use series click or series hover events, I am not able to identify tile (inside the stacked bar chart) which is making it harder to show tooltip.

This is the code:

  • html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }

       <script src="https://kendo.cdn.telerik.com/2019.1.115/js/jquery.min.js"></script>
       <script src="https://kendo.cdn.telerik.com/2019.1.115/js/kendo.all.min.js"></script>
    

         var CityData = [{country: "USA", children:[{"NYC": ["60%", "70%", "80%"]}, {"SFO": ["40%", "30%", "20%"]}]},
    
                         {country: "Mexico", children:[{"Mexico City": ["80%", "80%", "80%"]}, {"Cancun": ["20%", "20%", "20%"]}]},
    
    
                            {country: "Canada", children:[{"Toronto": ["50%", "60%", "60%"]}, {"Vancouver": ["50%",
    

    "40%", "40%"]}]}

                             ];
    
           function createChart() {
    
    
               $("#chart").kendoChart({
                   title: {
                       text: "City data"
                   },
                   legend: {
                       visible: false
                   },
                   seriesDefaults: {
                       type: "column",
                       stack: {
                           type: "100%"
                       }
                   },
                   series: [{
                       name: "USA",
                       stack: {
                           group: "Country"
                       },
                       data: [854622, 925844, 984930]
                   }, {
                       name: "Canada",
                       stack: {
                           group: "Country"
                       },
                       data: [490550, 555695, 627763]
                   }, {
                       name: "Mexico",
                       stack: {
                           group: "Country"
                       },
                       data: [379788, 411217, 447201]
                   }
    
                    ],
                   seriesColors: ["yellow", "green", "red"],
                   valueAxis: {
                       line: {
                           visible: false
                       }
                   },
                   categoryAxis: {
                       categories: [2000, 2005, 2010],
                       majorGridLines: {
                           visible: false
                       }
                   },
                   tooltip: {
                       visible: true,
                       template: "#= series.stack.group #, city #= series.name #"
                   }
               });
           }
    
           $(document).ready(createChart);
           $(document).bind("kendo:skinChange", createChart);
       </script>
    


Solution

  • You need to set tooltip: { shared: true } and it will work, I included other customizable properties of tooltip below also.

    Working demo: https://dojo.telerik.com/OfeMiHUb/4

    Snippet:

     tooltip: {
                 shared: true,
                 visible: true,
                 background: "#000",
                 template: "#= series.stack.group #, city #= series.name #"
              }
    

    or you can try this if you want another template of your tooltip: https://dojo.telerik.com/OfeMiHUb/3

    UPDATE:

    What changed?:

    tooltip: { 
         template: `USA- #= cityData[0]
                                .children
                                     .map(itm => Object.keys(itm)[0]) #`
        }
    

    OP clarified further what he wanted, as per new information, please see new working example: https://dojo.telerik.com/OfeMiHUb/9

    You can retrieve your city-data through indexing the keys of the children-object like this: cityData[0].children.map(itm => Object.keys(itm)[0])

    Possible additions:

    • If you want the series.name to be dynamically added to the tooltip, instead of explicitly typing it in. You can use: series.name.

    Like this:

    tooltip: { 
       template: `#= series.name # - #=
       cityData[0]
           .children
               .map(itm => Object.keys(itm)[0]) #`}
    

    Change the ArrayIndex of cityData[index] to select a nations cities.

    i.e.

    0: USA
    1: Canada 
    2: Mexico
    

    UPDATE 2:

    After reading through what you wrote (3000x) + looking at the image, I am interpreting that u also want the percentage showing (even tho it seems like in the clarifying comment below that u dont?). Anyhow:

            series: [{
                name: "USA",
                stack: {
                    group: "Country"
                },
                tooltip: {template: `#= series.name # - #=
                cityData[0]
                    .children
                        .map(itm => '[' + Object.keys(itm)[0] + ']' + ' : ' + Object.values(itm)[0][0]) #`},
                data: [854622, 925844, 984930]
            }, {
                name: "Canada",
                stack: {
                    group: "Country"
                },
                tooltip: {template: `#= series.name # - #=
                cityData[1]
                    .children
                        .map(itm => '[' + Object.keys(itm)[0] + ']' + ' : ' + Object.values(itm)[0][0]) #`},
                data: [490550, 555695, 627763]
            }, {
                name: "Mexico",
                stack: {
                    group: "Country"
                },
                                tooltip: {template: `#= series.name # - #=
                cityData[2]
                    .children
                        .map(itm => '[' + Object.keys(itm)[0] + ']' + ' : ' + Object.values(itm)[0][0]) #`},
                data:[379788, 411217, 447201]
            }
    
             ],
    

    Almost got the percentage / series working.

    Right now I'm struggling with extracting the series-index in this selector: Object.values(itm)[0][SERIES_INDEX_SHOULD_BE_HERE]

    TO BE CONTINUED...