如何以编程方式使折线图点活动/突出显示

时间:2016-01-08 14:23:42

标签: javascript chart.js

我正在使用chart.js 2.0 beta2并在页面和滑块上有几个折线图。我想突出显示与滑块位置匹配的每个折线图上的数据点(它们都具有相同的点数)。我无法弄清楚如何轻松地在代码中激活一个点。感谢您的任何提示。

3 个答案:

答案 0 :(得分:2)

2.0 BETA的解决方案

扩展您选择的图表控制器,并触发模拟的点击事件以显示工具提示。以下是一些适用于2.0(here is a fiddle)的代码:

var data = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
        {
            label: "My First dataset",
            fill: false,
            backgroundColor: "rgba(220,220,220,0.2)",
            borderColor: "rgba(220,220,220,1)",
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "rgba(220,220,220,1)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgba(220,220,220,1)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            tension: 0.1,
            data: [65, 59, 80, 81, 56, 55, 40]
        },
        {
            label: "My Second dataset",
            fill: true,
            backgroundColor: "rgba(220,220,220,0.2)",
            borderColor: "rgba(220,220,220,1)",
            pointBorderColor: "rgba(220,220,220,1)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 5,
            pointHoverBackgroundColor: "rgba(220,220,220,1)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            data: [28, 48, 40, 19, 86, 27, 90]
        }
    ]
};

var options = {
    responsive: false
};

Chart.helpers.extend(Chart.controllers.line.prototype, {
    fireSliderEvent: function(point, canvas, boundingRect){
        var mouseX = Math.round((boundingRect.left + point._view.x) / (boundingRect.right - boundingRect.left) * canvas.width / this.chart.chart.currentDevicePixelRatio);
        var mouseY = Math.round((boundingRect.top + point._view.y) / (boundingRect.bottom - boundingRect.top) * canvas.height / this.chart.chart.currentDevicePixelRatio);
        var oEvent = document.createEvent('MouseEvents');
        oEvent.initMouseEvent('click', true, true, document.defaultView,
            0, mouseX, mouseY, mouseX, mouseY,
            false, false, false, false, 0, canvas);
        canvas.dispatchEvent(oEvent);
    },
    highlightPoints: function(point){
        var canvas = this.chart.chart.canvas;
        var boundingRect = canvas.getBoundingClientRect();
        var points = this.getDataset().metaData;
        this.fireSliderEvent(points[point], canvas, boundingRect);
    }
});

var ctx = $("#canvas");
var myLine = new Chart(ctx, {
    type: 'line',
    data: data,
    options: options
});

var highlight = function(dataset, point){
    myLine.data.datasets[dataset].controller.highlightPoints(point);
}

$("#slider").slider({
    max: myLine.data.datasets[0].data.length-1,
    slide: function( event, ui ) { highlight(0, ui.value); }
});
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta/Chart.js"></script>

<div id="slider" style="width: 500px;"></div>
<canvas id="canvas" height="300" width="500"></canvas>

答案 1 :(得分:1)

1.x

的解决方案

您应该扩展图表类型并添加自己的方法来选择点。下面是一些代码,它们将根据滑块位置显示每个点的工具提示:

&#13;
&#13;
var lineChartData = {
    "datasets": [{
        "data": [
            "85",
            "87",
            "70",
            "80",
            "78",
            "69",
            "150",
            "93",
            "59",
            "88"],
            "pointStrokeColor": "#fff",
            "fillColor": "rgba(220,220,220,0.5)",
            "pointColor": "rgba(220,220,220,1)",
            "strokeColor": "rgba(220,220,220,1)"
    }],
        "labels": [
        "2013-01-01",
        "2013-01-04",
        "2013-01-15",
        "2013-02-03",
        "2013-03-25",
        "2013-04-03",
        "2013-04-14",
        "2013-05-27",
        "2013-05-27",
        "2013-08-03"],
};

var options = {showTooltips: false};

Chart.types.Line.extend({
    name: "LineAlt",
    highlightPoints: function(datasetIndex, pointIndexArray){
        var activePoints = [];
        var points = this.datasets[datasetIndex].points;
        for(i in pointIndexArray){
        	if(points[pointIndexArray[i]]){
          	activePoints.push(points[pointIndexArray[i]]);
          }
        }
        this.showTooltip(activePoints);
    }
});

var myLine = new Chart(document.getElementById("canvas").getContext("2d")).LineAlt(lineChartData, options);

var highlight = function(index){
	myLine.highlightPoints(0, [index]);
}

$("#slider").slider({
  max: lineChartData.datasets[0].data.length-1,
  slide: function( event, ui ) { highlight(ui.value); },
});
&#13;
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://www.chartjs.org/assets/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

<div id="slider" style="width: 500px;"></div>
<canvas id="canvas" height="300" width="500"></canvas>    
&#13;
&#13;
&#13;

答案 2 :(得分:0)

首先感谢JstnPwll ,为我带来了莫大的帮助!

ChartJS API发生了很大变化,而2.0 BETA无法正常工作 我需要在ReactJS中使用它以及“扩展”协调器的复杂性 超出了我的能力

这个更简单的方法适用于Chart.JS 2.9 原始点有时是数字有时是对象 所以我明确使用后缀num来阐明用法 只需调用fireSliderEvent(2,5);

fireSliderEvent = (datasetnum,pointnum)=>{

  let myLine=this.chartRef.current.chartInstance;
  //console.log(JSON.stringify(JSON.decycle(this.chartRef.current),null,2));

  var canvas = myLine.canvas;
  var boundingRect = canvas.getBoundingClientRect();

  var meta = myLine.getDatasetMeta(datasetnum);

  // https://stackoverflow.com/questions/6157929/how-to-simulate-a-mouse-click-using-javascript
  var mouseX = Math.round((boundingRect.left + meta.dataset._children[pointnum]._view.x) / (boundingRect.right - boundingRect.left) * canvas.width / myLine.currentDevicePixelRatio);
  
  var mouseY = Math.round((boundingRect.top + meta.dataset._children[pointnum]._view.y) / (boundingRect.bottom - boundingRect.top) * canvas.height / myLine.currentDevicePixelRatio);

  var oEvent = document.createEvent('MouseEvents');

  oEvent.initMouseEvent('click', true, true, document.defaultView,
         0, mouseX, mouseY, mouseX, mouseY,
         false, false, false, false, 0, canvas);

  canvas.dispatchEvent(oEvent);
}