web-dev-qa-db-fra.com

Comment changer le contenu des info-bulles dans c3js

Je travaille sur un affichage chronologique et j'ai des données que je veux montrer sur l'info-bulle. actuellement, il ne montre que la valeur à chaque fois. et je ne peux pas trouver un moyen de le changer. l'exemple ci-dessous montre comment changer le format de la valeur mais pas les valeurs affichées

var chart = c3.generate({
data: {
    columns: [
        ['data1', 30000, 20000, 10000, 40000, 15000, 250000],
        ['data2', 100, 200, 100, 40, 150, 250]
    ],
    axes: {
        data2: 'y2'
    }
},
axis : {
    y : {
        tick: {
            format: d3.format("s")
        }
    },
    y2: {
        show: true,
        tick: {
            format: d3.format("$")
        }
    }
},
tooltip: {
    format: {
        title: function (d) { return 'Data ' + d; },
        value: function (value, ratio, id) {
            var format = id === 'data1' ? d3.format(',') : d3.format('$');
            return format(value);
        }
           //value: d3.format(',') // apply this format to both y and y2
    }
}
});

c'est tiré de http://c3js.org/samples/tooltip_format.html Ils admettent qu'il n'y a pas d'exemple pour l'édition de contenu mais je n'ai rien trouvé dans la référence ou les forums, une suggestion pour changer le code (ici: https://github.com/masayuki0812/c3/blob/master/c3.js à la ligne 300) et ci-dessous:

__tooltip_contents = getConfig(['tooltip', 'contents'], function (d, defaultTitleFormat, defaultValueFormat, color) {
        var titleFormat = __tooltip_format_title ? __tooltip_format_title : defaultTitleFormat,
            nameFormat = __tooltip_format_name ? __tooltip_format_name : function (name) { return name; },
            valueFormat = __tooltip_format_value ? __tooltip_format_value : defaultValueFormat,
            text, i, title, value, name, bgcolor;
        for (i = 0; i < d.length; i++) {
            if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }

            if (! text) {
                title = titleFormat ? titleFormat(d[i].x) : d[i].x;
                text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
            }

            name = nameFormat(d[i].name);
            value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
            bgcolor = levelColor ? levelColor(d[i].value) : color(d[i].id);

            text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
            text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
            text += "<td class='value'>" + value + "</td>";
            text += "</tr>";
        }
        return text + "</table>";
    })

quelqu'un a-t-il tenté de le faire? développé une fonction pour faciliter le processus? avez-vous des conseils sur la façon de le faire correctement? Je ne sais pas comment changer leur code de manière à utiliser plus de données ou des données différentes de la valeur d obtenue par la fonction.

18
Adi

Si vous utilisez la fonction getTooltipContent from https://github.com/masayuki0812/c3/blob/master/src/tooltip.js#L27 et l'ajoutez dans la déclaration de graphique, dans tooltip.contents, avoir le même contenu d'info-bulle que celui par défaut.

Vous pouvez apporter des modifications à ce code et le personnaliser à votre guise. Un détail, comme CLASS n'est pas défini dans l'étendue actuelle, mais c'est en partie un objet graphique, j'ai substitué CLASS à $$.CLASS, peut-être que vous n'avez même pas besoin de cet objet dans votre code.

var chart = c3.generate({
  /*...*/
  tooltip: {
      format: {
        /*...*/
      },
      contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
          var $$ = this, config = $$.config,
              titleFormat = config.tooltip_format_title || defaultTitleFormat,
              nameFormat = config.tooltip_format_name || function (name) { return name; },
              valueFormat = config.tooltip_format_value || defaultValueFormat,
              text, i, title, value, name, bgcolor;
          for (i = 0; i < d.length; i++) {
              if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }

              if (! text) {
                  title = titleFormat ? titleFormat(d[i].x) : d[i].x;
                  text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
              }

              name = nameFormat(d[i].name);
              value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
              bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);

              text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";
              text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
              text += "<td class='value'>" + value + "</td>";
              text += "</tr>";
          }
          return text + "</table>";
      }
  }
});
44
supita

Si vous souhaitez contrôler le rendu des info-bulles et utiliser le rendu par défaut en fonction de la valeur des données, vous pouvez utiliser quelque chose comme:

tooltip: {
    contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
        if (d[1].value > 0) {
            // Use default rendering
            return this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color);
        } else {
            return '<div>Show what you want</div>';
        }
    },
    format: {
        /**/
    }
}
7
Ivan

Dans mon cas, je devais ajouter le jour pour la valeur de date (axe x) dans l'info-bulle. Enfin je suis venu avec la solution ci-dessous 

Références pour js et css

https://code.jquery.com/jquery-3.2.1.js

https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.jshttps://cdnjs.cloudflare.com/ajax/libs/c3/ 0.4.10/c3.min.jshttps://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css

function toDate(dateStr)
{
    var numbers = dateStr.match(/\d+/g);
    return new Date(numbers[0], numbers[1]-1, numbers[2]);
}
function GetMonthFromString(month)
{
    var months = {'Jan' : '01','Feb' : '02','Mar':'03','Apr':'04',
    'May':'05','Jun':'06','Jul':'07','Aug':'08','Sep':'09',
    'Oct':'10','Nov':'11','Dec':'12'};
    return months[month];
}
function GetFullDayName(formatteddate)
{
    var weekday = new Array(7);
    weekday[0] = "Sunday";
    weekday[1] = "Monday";
    weekday[2] = "Tuesday";
    weekday[3] = "Wednesday";
    weekday[4] = "Thursday";
    weekday[5] = "Friday";
    weekday[6] = "Saturday";
    var dayofdate = weekday[formatteddate.getDay()];
    return dayofdate;
}

//Chart Data for x-axis, OnHours and AvgHours
function CollectChartData()
{
    var xData = new Array();
    var onHoursData = new Array();
    var averageHoursData = new Array();
    var instanceOccuringDatesArray =  ["2017-04-20","2017-04-21","2017-04-22","2017-04-23","2017-04-24","2017-04-25","2017-04-26","2017-04-27","2017-04-28","2017-04-29","2017-04-30","2017-05-01","2017-05-02","2017-05-03","2017-05-04","2017-05-05","2017-05-06","2017-05-07","2017-05-08","2017-05-09","2017-05-10","2017-05-11","2017-05-12","2017-05-13","2017-05-14","2017-05-15","2017-05-16","2017-05-17","2017-05-18","2017-05-19","2017-05-20"];
        var engineOnHoursArray =  ["4.01","14.38","0.10","0.12","0.01","0.24","0.03","6.56","0.15","0.00","1.15","0.00","1.21","2.06","8.55","1.41","0.03","1.42","0.00","3.35","0.02","3.44","0.05","5.41","4.06","0.02","0.04","7.26","1.02","5.09","0.00"];
        var avgUtilizationArray =  ["2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29","2.29"];
        xData.Push('x');
        onHoursData.Push('OnHours');
        averageHoursData.Push('Project Average');
        for(var index=0;index<instanceOccuringDatesArray.length;index++)
        {
            xData.Push(instanceOccuringDatesArray[index]);
        }
        for(var index=0;index<engineOnHoursArray.length;index++)
        {
            onHoursData.Push(engineOnHoursArray[index]);
        }
        for(var index=0;index<avgUtilizationArray.length;index++)
        {
            averageHoursData.Push(avgUtilizationArray[index]);
        }
        var Data = [xData, onHoursData, averageHoursData];
        return Data;
    }


function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
    var $$ = this, config = $$.config, CLASS = $$.CLASS,
        titleFormat = config.tooltip_format_title || defaultTitleFormat,
        nameFormat = config.tooltip_format_name || function (name) { return name; },
        valueFormat = config.tooltip_format_value || defaultValueFormat,
        text, i, title, value, name, bgcolor;

    // You can access all of data like this:
    //$$.data.targets;

    for (i = 0; i < d.length; i++) {
        if (! text) {
                title = titleFormat ? titleFormat(d[i].x) : d[i].x;
                var arr = title.split(" ");                
                var datestr = new Date().getFullYear().toString() + "-"+ GetMonthFromString(arr[1]) + "-"+ arr[0];                  
               var formatteddate = toDate(datestr);                   
               var dayname = GetFullDayName(formatteddate);
               title = title + " (" + dayname + ")";
                text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
            }

        name = nameFormat(d[i].name);
        var initialvalue = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
        if (initialvalue.toString().indexOf('.') > -1)
        {
            var arrval = initialvalue.toString().split(".");
            value = arrval[0] + "h " + arrval[1] + "m";
        }
        else
        {
            value = initialvalue + "h " + "00m";
        }
        bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);

        text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
        text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
        text += "<td class='value'>" + value + "</td>";
        text += "</tr>";
    }
    return text + "</table>";   
}
$(document).ready(function () {
     var Data = CollectChartData();
    var chart = c3.generate({
        data: {
                x: 'x',
                columns: Data
            },
            axis: {
                x: {
                    type: 'timeseries',
                    tick: {
                        rotate: 75,
                        //format: '%d-%m-%Y'
                        format: '%d %b'
                    }
                },
                y : {
                    tick : {
                        format: function (y) {
                            if (y < 0) {
                            }
                            return y;
                        }
                    },
                    min : 0,
                    padding : {
                        bottom : 0
                    }
                }
            },
            tooltip: {
                contents: tooltip_contents
            }
    });
});
   <script src="https://code.jquery.com/jquery-3.2.1.js"></script>    
   <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.js"></script>
   <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css" rel="stylesheet" />

<div id="chart"></div>

2
Chandan Kumar

Si cela vous intéresse, voici la version ClojureScript de l’algorithme ci-dessus (par exemple, réponse de supita ), légèrement simplifiée (sans prise en charge de la configuration). (Ce n'est probablement pas ce que le PO a demandé, mais à partir de maintenant, il existe si peu de ressources sur le net sur ce sujet que la plupart des gens pourraient se retrouver ici.)

:tooltip {
  :contents
    (fn [d default-title-format default-value-format color]
      (this-as this
        (let [this-CLASS         (js->clj (.-CLASS this) :keywordize-keys true)
              tooltip-name-class (:tooltipName this-CLASS)
              rows               (js->clj d :keywordize-keys true)
              title-row (->> (first rows) (#(str "<table class='" (:tooltip this-CLASS) 
                                                 "'><tr><th colspan='2'>" 
                                                 (default-title-format (:x %)) "</th></tr>")))
              data-rows (->> rows
                             (map #(str "<tr class='" tooltip-name-class "--" (:id %) "'>"
                                        "<td class='name'><span style='background-color:" 
                                        (color (:id %)) "'></span>" (:name %) "</td>"
                                        "<td class='value'>" (default-value-format (:value %)) "</td>"
                                        "</tr>")))]
              (str title-row (string/join data-rows) "</table>"))))}
0
ThomasH

Lorsque nous avons un graphique à barres empilées et que nous aimerions afficher "Total" dans l'info-bulle (mais pas dans le graphique sous forme de barre/pile), cela peut s'avérer utile.

Les graphiques C3 utilisent un tableau pour stocker les données pour les info-bulles. Avant d'afficher les info-bulles, nous ajoutons des totaux (ou toute autre donnée selon nos besoins). En faisant cela, bien que les totaux ne soient pas disponibles sous forme de pile, ils sont affichés dans l'info-bulle.

function key_for_sum(arr) {
    return arr.value; //value is the key
};

function sum(prev, next) {
    return prev + next;
}

var totals_object = {};
totals_object.x = d[0]['x'];
totals_object.value = d.map(key_for_sum).reduce(sum);
totals_object.name = 'total';
totals_object.index = d[0]['index'];
totals_object.id = 'total';
d.Push(totals_object);

Le code ci-dessus a été ajouté pour garantir que le total est disponible dans 

Infobulle du graphique à barres empilées C3.js

var chart = c3.generate({
            /*...*/
            tooltip: {
                format: {
                    /*...*/
                },
                contents: function (d, defaultTitleFormat, defaultValueFormat, color) {

                    function key_for_sum(arr) {
                        return arr.value; //value is the key
                    }

                    function sum(prev, next) {
                        return prev + next;
                    }

                    var totals_object = {};
                    totals_object.x = d[0]['x'];
                    totals_object.value = d.map(key_for_sum).reduce(sum);// sum func
                    totals_object.name = 'total';//total will be shown in tooltip
                    totals_object.index = d[0]['index'];
                    totals_object.id = 'total';//c3 will use this
                    d.Push(totals_object);

                    var $$ = this,
                        config = $$.config,
                        titleFormat = config.tooltip_format_title || defaultTitleFormat,
                        nameFormat = config.tooltip_format_name || function (name) {
                            return name;
                        },
                        valueFormat = config.tooltip_format_value || defaultValueFormat,
                        text, i, title, value, name, bgcolor;
                    for (i = 0; i < d.length; i++) {
                        if (!(d[i] && (d[i].value || d[i].value === 0))) {
                            continue;
                        }


                        if (!text) {
                            title = titleFormat ? titleFormat(d[i].x) : d[i].x;
                            text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
                        }

                        name = nameFormat(d[i].name);
                        value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
                        bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
                        text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";
                        text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
                        text += "<td class='value'>" + value + "</td>";
                        text += "</tr>";
                    }
                    return text + "</table>";
                }
            }
0
Alok

L'ajout de contenu supplémentaire ou de données non numériques dans les info-bulles du graphique peut être effectué.

Ceci s'appuie sur @ supita's excellente réponse http://stackoverflow.com/a/25750639/1003746 .

Il est possible d'insérer des métadonnées supplémentaires sur chaque ligne dans le paramètre classes lors de la génération/mise à jour du graphique. Ceux-ci peuvent ensuite être ajoutés sous forme de lignes à l'info-bulle. 

Cela ne semble pas affecter le graphique - sauf si vous utilisez la fonctionnalité data.classes.

data: {
  classes: {
    data1: [{prop1: 10, prop2: 20}, {prop1: 30, prop2: 40}],
    data2: [{prop1: 50, prop2: 60}'{prop1: 70, prop2: 80}]
  }
}

Pour récupérer les métadonnées dans la configuration.

      tooltip: {
        contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
           const $$ = this;
           const config = $$.config;
           const meta = config.data_classes;
           ...
           for (i = 0; i < d.length; i++) {
               if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
               if (! text) {
                       ...
                }
               const line = d[0].id;
               const properties = meta.classes[line];
               const property = properties? properties[i] : null;

Ajoutez ensuite les lignes suivantes à la table pour afficher les nouvelles propriétés.

               if (property ) {
                 text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";
                 text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>PROP1</td>";
                 text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + property.prop1 + "</td>";
                 text += "</tr>";
                 text += "<tr class='" + $$.CLASS.tooltipName + "-" + d[i].id + "'>";
                 text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>PROP2</td>";
                 text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" +
                         property.prop2+ " cm/s</td>";
0
intotecho