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

时间:2014-07-15 09:13:51

标签: javascript d3.js c3.js

我正在制作时间轴显示,我想要在工具提示中显示数据。目前它只显示每次的值。我无法找到改变它的方法。下面的示例显示了如何更改值的格式,而不是显示的值

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 他们承认没有内容编辑的例子,但我在参考或论坛中找不到任何内容,但建议更改代码(它在这里:第300行https://github.com/masayuki0812/c3/blob/master/c3.js)及以下内容:< / p>

__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值的更多数据或数据。

8 个答案:

答案 0 :(得分:44)

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

您可以对此代码进行更改并根据需要进行自定义。一个详细信息,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>";
      }
  }
});

答案 1 :(得分:7)

如果您想控制工具提示渲染并根据数据值使用默认渲染,您可以使用以下内容:

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

答案 2 :(得分:2)

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

js和css的引用

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

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

&#13;
&#13;
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
            }
    });
});
&#13;
   <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>
&#13;
&#13;
&#13;

答案 3 :(得分:0)

可以在图表工具提示中添加其他内容或非数字数据。

这基于@supita's出色的答案http://stackoverflow.com/a/25750639/1003746

在生成/更新图表时,可以在classes参数中插入有关每行的其他元数据。然后可以将这些作为行添加到工具提示中。

这似乎不会影响图表 - 除非您使用的是data.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>";

答案 4 :(得分:0)

如果有人关心,这里是上述算法的 ClojureScript版本(例如supita's answer),略微简化(不支持配置)。 (这可能不是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>"))))}

答案 5 :(得分:0)

当我们有堆积的条形图并且希望在工具提示中显示“总计”时(而不是在条形图/堆栈中显示在图表中),这很方便。

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

添加了以上代码,以确保总计

中可用
  

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

答案 6 :(得分:0)

您的问题是关于更改c3js中工具提示的内容。

工具提示包含3个变量

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

此外,您想从其他变量中添加“名称”,而不是“列”中使用的变量。

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

这对我有用,可以随便摆弄参数,以获取所需的东西。

答案 7 :(得分:0)

我以前遇到过一个与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" }}
    />
Good luck!!