如何将onclick事件绑定到饼图段? [英] How do i bind onclick event to piechart segment?

查看:118
本文介绍了如何将onclick事件绑定到饼图段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何将onclick事件绑定到饼图段?

How do i bind onclick event to piechart segment?

https://github.com/sauminkirve/HTML5/blob/master/PieChart/piechart.html

推荐答案

饼图段实际上是一个楔子。你有几种方法来测试楔形。

A pie chart segment is really a wedge. You have several ways to hit-test a wedge.

一种方式是数学方式:


  • 测试鼠标是否在由楔形创建的圆的半径范围内。

  • Test if the mouse is within the radius of a circle created by the wedges.

如果半径测试为真,则计算角度鼠标与圆的中心点相对应。

If the radius test is true, then calculate the angle of the mouse versus the circle's centerpoint.

将该角度与每个楔形进行比较。如果角度在特定楔形弧的起始角度和结束角度之间,则鼠标位于该楔形内部。

Compare that angle to each wedge. If the angle is between the starting and ending angle of a specific wedge's arc, then the mouse is inside that wedge.

另一种方法是使用canvas的内置路径命中测试方法: isPointInPath

Another way is to use canvas's built in path hit-testing method: isPointInPath


  • 重新定义一个楔子。没有必要实际抚摸或填充那个楔子。只需执行从 beginPath closePath 的命令。

如果鼠标位于该楔形区域内,请使用 context.isPointInPath(mouseX,mouseY)进行测试。

Use context.isPointInPath(mouseX,mouseY) to hit-test if the mouse is inside that wedge.

如果isPointInPath返回true,你就发现了鼠标下的楔形。如果没有,那么重新定义&点击测试其他每个楔子。

If isPointInPath returns true, you've discovered the wedge under the mouse. If not, then redefine & hit-test each of the other wedges.

这是我在一段时间后编码的东西 - 测试楔子悬停时的饼图,单击楔形时将楔形移出饼图。

Here's something I coded a while back that hit-tests the wedges of a pie chart when hovering and moves the wedge out of the pie when a wedge is clicked.

它使用 isPointInPath 方法进行命中测试:

It uses the isPointInPath method to do the hit-testing:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.lineJoin = "round";

var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();

function Wedge(cx, cy, radius, startAngleDeg, endAngleDeg, fill, stroke, linewidth) {
  this.cx = cx;
  this.cy = cy;
  this.radius = radius;
  this.startAngle = startAngleDeg * Math.PI / 180;
  this.endAngle = endAngleDeg * Math.PI / 180;
  this.fill = fill;
  this.stroke = stroke;
  this.lineWidth = linewidth;
  this.offsetX = 0;
  this.offsetY = 0;
  this.rr = radius * radius;


  this.centerX = cx;
  this.centerY = cy;

  this.midAngle = this.startAngle + (this.endAngle - this.startAngle) / 2;
  this.offsetDistance = 15;
  this.explodeX = this.offsetDistance * Math.cos(this.midAngle);
  this.explodeY = this.offsetDistance * Math.sin(this.midAngle);
  this.isExploded = false;



};
Wedge.prototype.draw = function(fill, stroke) {
  this.define();
  this.fillStroke(fill, stroke);
  ctx.beginPath();
  ctx.arc(this.cx, this.cy, this.radius, 0, Math.PI * 2);
  ctx.closePath();
  ctx.lineWidth = 0.50;
  ctx.stroke();
}
Wedge.prototype.fillStroke = function(fill, stroke) {
  ctx.fillStyle = fill || this.fill;
  ctx.fill();
  ctx.strokeStyle = stroke, this.stroke;
  ctx.lineWidth = this.lineWidth;
  ctx.stroke();
}
Wedge.prototype.define = function() {
  var x = this.cx + this.offsetX;
  var y = this.cy + this.offsetY;
  ctx.beginPath();
  ctx.arc(x, y, this.radius, this.startAngle, this.endAngle);
  ctx.lineTo(x, y);
  ctx.closePath();
}
Wedge.prototype.ptAtAngle = function(radianAngle) {
  var xx = (this.cx + this.offsetX) + this.radius * Math.cos(radianAngle);
  var yy = (this.cy + this.offsetY) + this.radius * Math.sin(radianAngle);
  return ({
    x: x,
    y: y
  });
}
Wedge.prototype.explode = function(isExploded) {
  this.isExploded = isExploded;
  this.offsetX = isExploded ? this.explodeX : 0;
  this.offsetY = isExploded ? this.explodeY : 0;
  this.draw();
}
Wedge.prototype.isPointInside = function(x, y) {
  var dx = x - (this.cx + this.offsetX);
  var dy = y - (this.cy + this.offsetY);
  if (dx * dx + dy * dy > this.rr) {
    return (false);
  }
  var angle = (Math.atan2(dy, dx) + Math.PI * 2) % (Math.PI * 2);
  return (angle >= this.startAngle && angle <= this.endAngle);
}
Wedge.prototype.marker = function(pos) {
  ctx.beginPath();
  ctx.arc(pos.x, pos.y, 3, 0, Math.PI * 2);
  ctx.closePath();
  ctx.fillStyle = "red";
  ctx.fill();
}


function handleMouseDown(e) {
  e.preventDefault();
  mouseX = parseInt(e.clientX - offsetX);
  mouseY = parseInt(e.clientY - offsetY);

  clear();
  for (var i = 0; i < wedges.length; i++) {
    var wedge = wedges[i].wedge;
    if (wedge.isPointInside(mouseX, mouseY)) {
      wedge.explode(!wedge.isExploded);
    }
    wedge.draw();
  }
}

function handleMouseUp(e) {
  e.preventDefault();
  mouseX = parseInt(e.clientX - offsetX);
  mouseY = parseInt(e.clientY - offsetY);

  // Put your mouseup stuff here
  isDown = false;
}

function handleMouseOut(e) {
  e.preventDefault();
  mouseX = parseInt(e.clientX - offsetX);
  mouseY = parseInt(e.clientY - offsetY);

  // Put your mouseOut stuff here
  isDown = false;
}

function handleMouseMove(e) {
  e.preventDefault();
  mouseX = parseInt(e.clientX - offsetX);
  mouseY = parseInt(e.clientY - offsetY);

  for (var i = 0; i < wedges.length; i++) {
    var wedge = wedges[i].wedge;
    if (wedge.isPointInside(mouseX, mouseY)) {
      wedge.draw("black");
    } else {
      wedge.draw();
    }
  }


}

$("#canvas").mousedown(function(e) {
  handleMouseDown(e);
});
$("#canvas").mousemove(function(e) {
  handleMouseMove(e);
});
$("#canvas").mouseup(function(e) {
  handleMouseUp(e);
});
$("#canvas").mouseout(function(e) {
  handleMouseOut(e);
});

function clear() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

var PI2 = Math.PI * 2;
var cx = 150;
var cy = 150;
var r = 100;
var line = 2;
var stroke = "black";
var wedges = [];
wedges.push({
  percent: 18,
  fill: "red"
});
wedges.push({
  percent: 30,
  fill: "blue"
});
wedges.push({
  percent: 25,
  fill: "green"
});
wedges.push({
  percent: 13,
  fill: "purple"
});
wedges.push({
  percent: 14,
  fill: "gold"
});
var rAngle = 0;
for (var i = 0; i < wedges.length; i++) {
  var wedge = wedges[i];
  var angle = 360 * wedge.percent / 100;
  wedge.wedge = new Wedge(cx, cy, r, rAngle, rAngle + angle, wedge.fill, "black", 1);
  wedge.wedge.draw();
  rAngle += angle;
}

window.onscroll = function(e) {
  var BB = canvas.getBoundingClientRect();
  offsetX = BB.left;
  offsetY = BB.top;
}

body {
  background-color: ivory;
}
#canvas {
  border: 1px solid red;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Hover wedge to highlight it<br>Click wedge to explode that wedge</h4>
<canvas id="canvas" width=300 height=300></canvas>

这篇关于如何将onclick事件绑定到饼图段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆