ChartJS - 在工具提示中显示单行数据

时间:2015-10-06 15:21:53

标签: javascript jquery chart.js

我正在使用chartJS库,并尝试弄清楚我需要做些什么才能在工具提示中显示单行数据。

例如, Wrong

我在这里的蓝线上空盘旋,看到那个标记处的每个数据点。我想做的是仅查看蓝线的所有三个数据点。

我从chart js tooltip how to control the data that show

取得了一些进展
    getPointsAtEvent: function(e) {
        var pointsArray = [], eventPosition = helpers.getRelativePosition(e);
        var breakLoop = 0;
        helpers.each(this.datasets, function(dataset) {
            helpers.each(dataset.points, function(point) {
                if (point.inRange(eventPosition.x, eventPosition.y) && point.showTooltip && !point.ignore)  {
                    if(eventPosition.y + 2 >= point.y && eventPosition.y - 2 <= point.y) {
                        pointsArray.push(point);
                        breakLoop = 1;
                        return false;
                    }
                }
            });
            if(breakLoop) {
                return false;
            }
        }, this);
        //console.log(pointsArray);
        return pointsArray;
    },

我的图表修改是否会在图表上返回1个数据点。我假设下一步是覆盖showToolTip方法。

2 个答案:

答案 0 :(得分:0)

如果您扩展折线图,请使用我上面的代码,并且下面粘贴的代码可以在某种程度上获得所需的效果。

    showTooltip: function(ChartElements, forceRedraw) { //custom edit

        //we will get value from ChartElements (which should be only 1 element long in this case) and use it to match the line row we want to see.
        try {
            var numMatch = ChartElements[0].value;
        }
        catch(err) {
            var isChanged = (function(Elements) {
                var changed = true;
                return changed;
            }).call(this, ChartElements);
        }

        // Only redraw the chart if we've actually changed what we're hovering on.
        if (typeof this.activeElements === 'undefined') this.activeElements = [];

        var isChanged = (function(Elements) {
            var changed = false;

            if (Elements.length !== this.activeElements.length) {
                changed = true;
                return changed;
            }

            helpers.each(Elements, function(element, index) {
                if (element !== this.activeElements[index]) {
                    changed = true;
                }
            }, this);
            return changed;
        }).call(this, ChartElements);

        if (!isChanged && !forceRedraw) {
            return;
        } else {
            this.activeElements = ChartElements;
        }
        this.draw();
        if (this.options.customTooltips) {
            this.options.customTooltips(false);
        }
        if (ChartElements.length > 0) {
            // If we have multiple datasets, show a MultiTooltip for all of the data points at that index
            if (this.datasets && this.datasets.length > 1) {
                var dataArray,
                    dataIndex;

                for (var i = this.datasets.length - 1; i >= 0; i--) {
                    dataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;
                    dataIndex = helpers.indexOf(dataArray, ChartElements[0]);
                    if (dataIndex !== -1) {
                        break;
                    }
                }

                var eleLast = "";
                var eleFirst = "";
                var tooltipLabels = [],
                    tooltipColors = [],
                    medianPosition = (function(index) {

                        // Get all the points at that particular index
                        var Elements = [],
                            dataCollection,
                            xPositions = [],
                            yPositions = [],
                            xMax,
                            yMax,
                            xMin,
                            yMin;
                        helpers.each(this.datasets, function(dataset) {
                            dataCollection = dataset.points || dataset.bars || dataset.segments;
                            //console.log(dataset);
                            for(i = 0; i < dataset.points.length; i++) {
                                if(dataset.points[i].value === numMatch) {
                                    for(var k = 0; k < dataset.points.length; k++) {
                                        Elements.push(dataset.points[k]);
                                    }
                                }
                            }
                        });

                        //save elements last label string
                        eleLast = Elements[Elements.length-1].label;
                        eleFirst = Elements[0].label;

                        //console.log(Elements);
                        helpers.each(Elements, function(element) {
                            if(element.value === numMatch) {
                                xPositions.push(element.x);
                                yPositions.push(element.y);
                            }


                            //Include any colour information about the element
                            tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
                            tooltipColors.push({
                                fill: element._saved.fillColor || element.fillColor,
                                stroke: element._saved.strokeColor || element.strokeColor
                            });

                        }, this);

                        yMin = helpers.min(yPositions);
                        yMax = helpers.max(yPositions);

                        xMin = helpers.min(xPositions);
                        xMax = helpers.max(xPositions);

                        return {
                            x: (xMin > this.chart.width / 2) ? xMin : xMax,
                            y: (yMin + yMax) / 2
                        };
                    }).call(this, dataIndex);

                var newLabel = eleFirst + " to " + eleLast;

                new Chart.MultiTooltip({
                    x: medianPosition.x,
                    y: medianPosition.y,
                    xPadding: this.options.tooltipXPadding,
                    yPadding: this.options.tooltipYPadding,
                    xOffset: this.options.tooltipXOffset,
                    fillColor: this.options.tooltipFillColor,
                    textColor: this.options.tooltipFontColor,
                    fontFamily: this.options.tooltipFontFamily,
                    fontStyle: this.options.tooltipFontStyle,
                    fontSize: this.options.tooltipFontSize,
                    titleTextColor: this.options.tooltipTitleFontColor,
                    titleFontFamily: this.options.tooltipTitleFontFamily,
                    titleFontStyle: this.options.tooltipTitleFontStyle,
                    titleFontSize: this.options.tooltipTitleFontSize,
                    cornerRadius: this.options.tooltipCornerRadius,
                    labels: tooltipLabels,
                    legendColors: tooltipColors,
                    legendColorBackground: this.options.multiTooltipKeyBackground,
                    title: newLabel,
                    chart: this.chart,
                    ctx: this.chart.ctx,
                    custom: this.options.customTooltips
                }).draw();

            } else {
                helpers.each(ChartElements, function(Element) {
                    var tooltipPosition = Element.tooltipPosition();
                    new Chart.Tooltip({
                        x: Math.round(tooltipPosition.x),
                        y: Math.round(tooltipPosition.y),
                        xPadding: this.options.tooltipXPadding,
                        yPadding: this.options.tooltipYPadding,
                        fillColor: this.options.tooltipFillColor,
                        textColor: this.options.tooltipFontColor,
                        fontFamily: this.options.tooltipFontFamily,
                        fontStyle: this.options.tooltipFontStyle,
                        fontSize: this.options.tooltipFontSize,
                        caretHeight: this.options.tooltipCaretSize,
                        cornerRadius: this.options.tooltipCornerRadius,
                        text: helpers.template(this.options.tooltipTemplate, Element),
                        chart: this.chart,
                        custom: this.options.customTooltips
                    }).draw();
                }, this);
            }
        }
        return this;
    },

显然,这只是一个快速而肮脏的修复,如果我有更多时间来处理它,我希望每个数据点都显示其相应的值。enter image description here

答案 1 :(得分:0)

如果这是您拥有的唯一图表(即因为以下代码更改了某些全局chart.js元素),您可以使用以下代码

var originalMultiTooltip = Chart.MultiTooltip;
Chart.MultiTooltip = function () {
    var argument = arguments[0];
    // locate the series using the active point
    var activeDatasetLabel = myChart.activeElements[0].datasetLabel;
    myChart.datasets.forEach(function (dataset) {
        if (dataset.label === activeDatasetLabel) {
            // swap out the labels and colors in arguments
            argument.labels = dataset.points.map(function (point) { return point.value; });
            argument.legendColors = dataset.points.map(function (point) {
                return {
                    fill: point._saved.fillColor || point.fillColor,
                    stroke: point._saved.strokeColor || point.strokeColor
                };
            });
            argument.title = activeDatasetLabel;
            // position it near the active point
            argument.y = myChart.activeElements[0].y;
        }
    })
    return new originalMultiTooltip(arguments[0]);
}

// this distance function returns the square of the distance if within detection range, otherwise it returns Infinity
var distance = function (chartX, chartY) {
    var hitDetectionRange = this.hitDetectionRadius + this.radius;
    var distance = Math.pow(chartX - this.x, 2) + Math.pow(chartY - this.y, 2);
    return (distance < Math.pow(hitDetectionRange, 2)) ? distance : Infinity;
}
myChart.getPointsAtEvent = function (e) {
    var pointsArray = [],
        eventPosition = Chart.helpers.getRelativePosition(e);

    var leastDistance = Infinity;
    Chart.helpers.each(myChart.datasets, function (dataset) {
        Chart.helpers.each(dataset.points, function (point) {
            // our active point is the one closest to the hover event
            var pointDistance = distance.call(point, eventPosition.x, eventPosition.y)
            if (isFinite(pointDistance) && pointDistance < leastDistance) {
                leastDistance = pointDistance;
                pointsArray = [ point ];
            }
        });
    }, myChart);

    return pointsArray;
}

它做了两件事

  • 取代getPointsAtEvent只选择一个点
  • 包装MultiTooltip构造函数以换出与活动点系列中的所有值一起传递的值列表。

小提琴 - http://jsfiddle.net/h93pyavk/