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

查看:15
本文介绍了如何将 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.

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

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

使用 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天全站免登陆