如何在c3js中更改工具提示内容

How to change tooltip content in c3js

本文关键字:工具提示 c3js      更新时间:2023-09-26

我正在制作一个时间轴显示,并且我有想要在工具提示上显示的数据。目前,它只显示每次的值。我找不到改变它的方法。下面的示例显示了如何更改值的格式,但没有显示什么值

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
    }
}
});

取自http://c3js.org/samples/tooltip_format.html他们确实承认没有内容编辑的例子,但我在参考或论坛中找不到任何东西,但建议更改代码(在这里:https://github.com/masayuki0812/c3/blob/master/c3.js第300行)及以下:

__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>";
    })

有人试图这样做吗?开发了一些功能来促进这个过程?有什么正确的建议吗?我不知道如何以一种方式改变他们的代码,我可以使用更多的数据或数据不同于函数获得的d值。

如果您使用https://github.com/masayuki0812/c3/blob/master/src/tooltip.js#L27中的getTooltipContent函数并将其添加到图表声明中,在tooltip中。内容,您将拥有与默认内容相同的工具提示内容。

您可以对该代码进行更改并根据自己的喜好进行自定义。一个细节,因为CLASS在当前作用域中没有定义,但它是部分图表对象,我用CLASS代替$$.CLASS,也许你甚至不需要这个对象在你的代码中。

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>";
      }
  }
});

如果你想根据数据值控制工具提示呈现并使用默认呈现,你可以这样做:

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: {
        /**/
    }
}

在我的例子中,我必须在工具提示中添加日期值(x轴)的日期。最后,我想出了下面的解决方案

关于js和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>

当我们有一个堆叠的条形图,我们想要在工具提示中显示"Total"(而不是在图表中作为条形/堆栈),这是很方便的。

C3图表使用一个数组来存储工具提示的数据,在显示工具提示之前,我们正在添加总数(或根据我们的需求添加任何其他数据)。通过这样做,虽然总数不能作为堆栈使用,但它会在工具提示中显示。

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);
添加以上代码是为了确保total在 中可用。

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>";
                }
            }

可以在图表工具提示中添加额外的内容或非数值数据。

这建立在@supita的优秀答案http://stackoverflow.com/a/25750639/1003746之上。

在生成/更新图表时,可以在classes参数中插入关于每一行的额外元数据。然后可以将它们作为行添加到工具提示中。

这似乎不会影响图表——除非你正在使用数据。类特性。

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

获取配置中的元数据。

      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;

然后将以下行添加到表中以显示新属性。

               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>";

如果有人关心,这里是一个ClojureScript版本的上述算法(例如supita的答案),稍微简化(不支持配置)。(这可能不是OP要求的,但到目前为止,网上关于这个主题的资源很少,大多数人可能会在这里结束。)

: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>"))))}

你的问题是关于在c3js中改变工具提示的内容。

工具提示有3个变量

+----------------+
|      title     |
+----------------+
|  name  | value |
+----------------+

另外,您希望从其他变量中添加'name',而不是在'column'中使用的变量。

tooltip: {
        format: {
          title(x, index) { return ''; },
          name(name, ratio, id, index) { return lst[index + 1]; },
          value(value, ratio, id, index) { return value; }
        }
      },

这对我来说很有效,你可以随意摆弄这些参数,以得到你需要的。

我以前遇到过一个与c3的工具提示位置和样式相关的问题。为了在c3中自由地安排工具提示,我的建议是用d3来操纵工具提示。


// internal = chart.internal()
const mousePos = d3.mouse(internal.svg.node()); // find mouse position
const clientX = mousePos[0]; //for x
const clientY = mousePos[1]; //for y
const tooltip = d3.select("#tooltip"); //select tooltip div (apply your style)
tooltip.style("display", "initial");  //show tooltip
tooltip.style("left", clientX - mouseOffSet.X + "px"); // set position
tooltip.style("top", clientY - mouseOffSet.Y + "px");  // set position
tooltip.html("<span>" + content + "</span>");   
// you can arrange all content and style whatever you want
   
 <div
      id="tooltip"
      className="your-style"
      style={{ display: "none", position: "absolute" }}
    />
祝你好运! !