如何在图的悬停转折点上显示Y轴值 [英] How To Show Y-axis value, on hover turning point of graph
本文介绍了如何在图的悬停转折点上显示Y轴值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我使用java脚本和画布创建图形。以下是jsfiddle链接
- 创建一个div作为工具提示(工具提示div)。
- 最初隐藏工具提示div。
- 收听mousemove事件。
- 在mousemove处理程序中,点击测试鼠标是否在任何数据点内。
-
如果鼠标在数据点内,
- 在工具提示div中设置所需的文本,
- 使用CSS在数据点上移动工具提示div,
- 显示工具提示div。
以下是注释代码和演示:
maxYValue)maxYValue = data.dataPoints [i] .y ; }}; var renderBackground = function(){var lingrad = ctx.createLinearGradient(margin.left,margin.top,xMax - margin.right,yMax); lingrad.addColorStop(0.0,'#ffffff'); lingrad.addColorStop(0.2,'#fff'); lingrad.addColorStop(0.8,'#fff'); lingrad.addColorStop(1,'#ffffff'); ctx.fillStyle = lingrad; ctx.fillRect(margin.left,margin.top,xMax - margin.left,yMax - margin.top); ctx.fillStyle ='#6A6A6A'; }; var renderText = function(){var labelFont =(data.labelFont!= null)? data.labelFont:'20pt Arial'; ctx.font = labelFont; ctx.textAlign =center; // Title var txtSize = ctx.measureText(data.title); ctx.fillText(data.title,(chartWidth / 2),(margin.top / 2)); // X-axis text txtSize = ctx.measureText(data.xLabel); ctx.fillText(data.xLabel,margin.left +(xMax / 2) - (txtSize.width / 2),yMax +(margin.bottom / 1.2)); // Y轴文本ctx.save(); ctx.rotate(-Math.PI / 2); ctx.font = labelFont; ctx.fillText(data.yLabel,(yMax / 2)* -1,margin.left / 4); ctx.restore(); }; var renderLinesAndLabels = function(){//垂直向导var yInc = yMax / data.dataPoints.length; var yPos = 0; var yLabelInc =(maxYValue * ratio)/ data.dataPoints.length; var xInc = getXInc(); var xPos = margin.left; for(var i = 0; i
body {background-color:ivory; } #canvas {border:1px solid red; margin:0 auto; }
< script src =https:// ajax .googleapis.com / ajax / libs / jquery / 1.9.1 / jquery.min.js>< / script>< canvas id =canvaswidth = 300 height = 300& code>
I am making a graph using java script and canvas. below is the jsfiddle link
http://jsfiddle.net/ghan_123/n0r796ae/
I want to show values on hover bubble(turning points) like
price 2100 on 1-aug
java script
var CanvasChart = function () {
var ctx;
var margin = { top: 40, left: 75, right: 0, bottom: 75 };
var chartHeight, chartWidth, yMax, xMax, data;
var maxYValue = 0;
var ratio = 0;
var renderType = { lines: 'lines', points: 'points' };
var render = function(canvasId, dataObj) {
data = dataObj;
getMaxDataYValue();
var canvas = document.getElementById(canvasId);
chartHeight = canvas.getAttribute('height');
chartWidth = canvas.getAttribute('width');
xMax = chartWidth - (margin.left + margin.right);
yMax = chartHeight - (margin.top + margin.bottom);
ratio = yMax / maxYValue;
ctx = canvas.getContext("2d");
renderChart();
};
var renderChart = function () {
renderBackground();
renderText();
renderLinesAndLabels();
//render data based upon type of renderType(s) that client supplies
if (data.renderTypes == undefined || data.renderTypes == null) data.renderTypes = [renderType.lines];
for (var i = 0; i < data.renderTypes.length; i++) {
renderData(data.renderTypes[i]);
}
};
var getMaxDataYValue = function () {
for (var i = 0; i < data.dataPoints.length; i++) {
if (data.dataPoints[i].y > maxYValue) maxYValue = data.dataPoints[i].y;
}
};
var renderBackground = function() {
var lingrad = ctx.createLinearGradient(margin.left, margin.top, xMax - margin.right, yMax);
lingrad.addColorStop(0.0, '#ffffff');
lingrad.addColorStop(0.2, '#fff');
lingrad.addColorStop(0.8, '#fff');
lingrad.addColorStop(1, '#ffffff');
ctx.fillStyle = lingrad;
ctx.fillRect(margin.left, margin.top, xMax - margin.left, yMax - margin.top);
ctx.fillStyle = '#6A6A6A';
};
var renderText = function() {
var labelFont = (data.labelFont != null) ? data.labelFont : '20pt Arial';
ctx.font = labelFont;
ctx.textAlign = "center";
//Title
var txtSize = ctx.measureText(data.title);
ctx.fillText(data.title, (chartWidth / 2), (margin.top / 2));
//X-axis text
txtSize = ctx.measureText(data.xLabel);
ctx.fillText(data.xLabel, margin.left + (xMax / 2) - (txtSize.width / 2), yMax + (margin.bottom / 1.2));
//Y-axis text
ctx.save();
ctx.rotate(-Math.PI / 2);
ctx.font = labelFont;
ctx.fillText(data.yLabel, (yMax / 2) * -1, margin.left / 4);
ctx.restore();
};
var renderLinesAndLabels = function () {
//Vertical guide lines
var yInc = yMax / data.dataPoints.length;
var yPos = 0;
var yLabelInc = (maxYValue * ratio) / data.dataPoints.length;
var xInc = getXInc();
var xPos = margin.left;
for (var i = 0; i < data.dataPoints.length; i++) {
yPos += (i == 0) ? margin.top : yInc;
//Draw horizontal lines
drawLine(margin.left, yPos, xMax, yPos, '#E8E8E8');
//y axis labels
ctx.font = (data.dataPointFont != null) ? data.dataPointFont : '10pt Calibri';
var txt = Math.round(maxYValue - ((i == 0) ? 0 : yPos / ratio));
var txtSize = ctx.measureText(txt);
ctx.fillText(txt, margin.left - ((txtSize.width >= 14) ? txtSize.width : 10) - 7, yPos + 4);
//x axis labels
txt = data.dataPoints[i].x;
txtSize = ctx.measureText(txt);
ctx.fillText(txt, xPos, yMax + (margin.bottom / 3));
xPos += xInc;
}
//Vertical line
drawLine(margin.left, margin.top, margin.left, yMax, 'black');
//Horizontal Line
drawLine(margin.left, yMax, xMax, yMax, 'black');
};
var renderData = function(type) {
var xInc = getXInc();
var prevX = 0,
prevY = 0;
for (var i = 0; i < data.dataPoints.length; i++) {
var pt = data.dataPoints[i];
var ptY = (maxYValue - pt.y) * ratio;
if (ptY < margin.top) ptY = margin.top;
var ptX = (i * xInc) + margin.left;
if (i > 0 && type == renderType.lines) {
//Draw connecting lines
drawLine(ptX, ptY, prevX, prevY, '#309FB2', 2);
}
if (type == renderType.points) {
var radgrad = ctx.createRadialGradient(ptX, ptY, 8, ptX - 5, ptY - 5, 0);
radgrad.addColorStop(0, '#309FB2');
radgrad.addColorStop(0.9, 'White');
ctx.beginPath();
ctx.fillStyle = radgrad;
//Render circle
ctx.arc(ptX, ptY, 8, 0, 2 * Math.PI, false)
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = '#000';
ctx.stroke();
ctx.closePath();
}
prevX = ptX;
prevY = ptY;
}
};
var getXInc = function() {
return Math.round(xMax / data.dataPoints.length) - 1;
};
var drawLine = function(startX, startY, endX, endY, strokeStyle, lineWidth) {
if (strokeStyle != null) ctx.strokeStyle = strokeStyle;
if (lineWidth != null) ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
ctx.closePath();
};
return {
renderType: renderType,
render: render
};
} ();
$(document).ready(function () {
var dataDef = { title: "US Population Chart",
xLabel: 'Date',
yLabel: 'Price',
labelFont: '19pt Arial',
dataPointFont: '10pt Arial',
renderTypes: [CanvasChart.renderType.lines, CanvasChart.renderType.points],
dataPoints: [{ x: '1-aug', y: 2100 },
{ x: '2-aug', y: 2000 },
{ x: '3-aug', y: 2200 },
{ x: '4-aug', y: 1800 },
{ x: '5-aug', y: 1500 },
{ x: '6-aug', y: 3000 },
]
};
CanvasChart.render('canvas', dataDef);
});
HTML part
<body style="margin-left:50px;margin-top:50px;">
<canvas id="canvas" width="500" height="300"></canvas>
解决方案
Here's a simple way to use a plain-old DIV as a tooltip.
- Create a div to use as the tooltip (the tooltip-div).
- Initially hide the tooltip-div.
- Listen for mousemove events.
- In the mousemove handler, hit-test if the mouse is inside any data point.
If the mouse is inside a data point,
- Set the desired text in the tooltip-div,
- Use CSS to move the tooltip-div over the data point,
- Show the tooltip-div.
Here's annotated code and a Demo:
var CanvasChart = function () {
var ctx;
var margin = { top: 40, left: 75, right: 0, bottom: 75 };
var chartHeight, chartWidth, yMax, xMax, data;
var maxYValue = 0;
var ratio = 0;
var renderType = { lines: 'lines', points: 'points' };
// addition
var dataXY=[];
var render = function(canvasId, dataObj) {
data = dataObj;
getMaxDataYValue();
var canvas = document.getElementById(canvasId);
chartHeight = canvas.getAttribute('height');
chartWidth = canvas.getAttribute('width');
xMax = chartWidth - (margin.left + margin.right);
yMax = chartHeight - (margin.top + margin.bottom);
ratio = yMax / maxYValue;
ctx = canvas.getContext("2d");
renderChart();
};
var renderChart = function () {
renderBackground();
renderText();
renderLinesAndLabels();
//render data based upon type of renderType(s) that client supplies
if (data.renderTypes == undefined || data.renderTypes == null) data.renderTypes = [renderType.lines];
for (var i = 0; i < data.renderTypes.length; i++) {
renderData(data.renderTypes[i]);
}
};
var getMaxDataYValue = function () {
for (var i = 0; i < data.dataPoints.length; i++) {
if (data.dataPoints[i].y > maxYValue) maxYValue = data.dataPoints[i].y;
}
};
var renderBackground = function() {
var lingrad = ctx.createLinearGradient(margin.left, margin.top, xMax - margin.right, yMax);
lingrad.addColorStop(0.0, '#ffffff');
lingrad.addColorStop(0.2, '#fff');
lingrad.addColorStop(0.8, '#fff');
lingrad.addColorStop(1, '#ffffff');
ctx.fillStyle = lingrad;
ctx.fillRect(margin.left, margin.top, xMax - margin.left, yMax - margin.top);
ctx.fillStyle = '#6A6A6A';
};
var renderText = function() {
var labelFont = (data.labelFont != null) ? data.labelFont : '20pt Arial';
ctx.font = labelFont;
ctx.textAlign = "center";
//Title
var txtSize = ctx.measureText(data.title);
ctx.fillText(data.title, (chartWidth / 2), (margin.top / 2));
//X-axis text
txtSize = ctx.measureText(data.xLabel);
ctx.fillText(data.xLabel, margin.left + (xMax / 2) - (txtSize.width / 2), yMax + (margin.bottom / 1.2));
//Y-axis text
ctx.save();
ctx.rotate(-Math.PI / 2);
ctx.font = labelFont;
ctx.fillText(data.yLabel, (yMax / 2) * -1, margin.left / 4);
ctx.restore();
};
var renderLinesAndLabels = function () {
//Vertical guide lines
var yInc = yMax / data.dataPoints.length;
var yPos = 0;
var yLabelInc = (maxYValue * ratio) / data.dataPoints.length;
var xInc = getXInc();
var xPos = margin.left;
for (var i = 0; i < data.dataPoints.length; i++) {
yPos += (i == 0) ? margin.top : yInc;
//Draw horizontal lines
drawLine(margin.left, yPos, xMax, yPos, '#E8E8E8');
//y axis labels
ctx.font = (data.dataPointFont != null) ? data.dataPointFont : '10pt Calibri';
var txt = Math.round(maxYValue - ((i == 0) ? 0 : yPos / ratio));
var txtSize = ctx.measureText(txt);
ctx.fillText(txt, margin.left - ((txtSize.width >= 14) ? txtSize.width : 10) - 7, yPos + 4);
//x axis labels
txt = data.dataPoints[i].x;
txtSize = ctx.measureText(txt);
ctx.fillText(txt, xPos, yMax + (margin.bottom / 3));
xPos += xInc;
}
//Vertical line
drawLine(margin.left, margin.top, margin.left, yMax, 'black');
//Horizontal Line
drawLine(margin.left, yMax, xMax, yMax, 'black');
};
var renderData = function(type) {
var xInc = getXInc();
var prevX = 0,
prevY = 0;
// addition
dataXY.length=0;
for (var i = 0; i < data.dataPoints.length; i++) {
var pt = data.dataPoints[i];
var ptY = (maxYValue - pt.y) * ratio;
if (ptY < margin.top) ptY = margin.top;
var ptX = (i * xInc) + margin.left;
if (i > 0 && type == renderType.lines) {
//Draw connecting lines
drawLine(ptX, ptY, prevX, prevY, '#309FB2', 2);
}
if (type == renderType.points) {
var radgrad = ctx.createRadialGradient(ptX, ptY, 8, ptX - 5, ptY - 5, 0);
radgrad.addColorStop(0, '#309FB2');
radgrad.addColorStop(0.9, 'White');
ctx.beginPath();
ctx.fillStyle = radgrad;
//Render circle
ctx.arc(ptX, ptY, 8, 0, 2 * Math.PI, false)
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = '#000';
ctx.stroke();
ctx.closePath();
// addition
dataXY.push({cx:ptX,cy:ptY,r:8,tipText:'Price='+pt.y+' on '+pt.x});
}
prevX = ptX;
prevY = ptY;
}
};
var getXInc = function() {
return Math.round(xMax / data.dataPoints.length) - 1;
};
var drawLine = function(startX, startY, endX, endY, strokeStyle, lineWidth) {
if (strokeStyle != null) ctx.strokeStyle = strokeStyle;
if (lineWidth != null) ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
ctx.closePath();
};
return {
renderType: renderType,
render: render, // added comma
// addition
dataXY: dataXY
};
} ();
//
// end CanvasChart
/////////////////////////////
// addition
var CanvasTooltip=(function(){
// ctor
function CanvasTooltip(canvasId,targets){
var that=this;
this.$canvas=$("#"+canvasId);
this.targets=targets;
this.openTooltipIndex=-1;
// add tip elements
this.init();
this.$tip=$('#canvasTip').hide();
// eventing
this.offsetX,this.offsetY;
this.reOffset();
this.$canvas.on('mousemove',function(e){ that.handleMouseMove(e); });
$(window).on('scroll',function(e){ that.reOffset(); });
}
CanvasTooltip.prototype.reOffset=function(){
var BB=this.$canvas[0].getBoundingClientRect();
this.offsetX=BB.left;
this.offsetY=BB.top;
};
CanvasTooltip.prototype.init=function(){
this.$canvas.wrap('<div id="canvasTipWrapper"></div>');
$('#canvasTipWrapper').css({'position':'relative'});
$('<div id="canvasTip"></div>')
.css({
'position':'absolute',
'border':'1px solid gray',
'border-left-width':'7px',
'border-left-color':'maroon',
'margin-bottom':'20px',
'background':'rgba(255,255,255,1.00)',
'padding-left':'5px',
'padding-right':'5px',
'max-width':'150px'
})
.appendTo('#canvasTipWrapper');
};
CanvasTooltip.prototype.handleMouseMove =function(e){
e.preventDefault();
e.stopPropagation();
var mouseX=parseInt(e.clientX-this.offsetX);
var mouseY=parseInt(e.clientY-this.offsetY);
// hit-test each target
var hit=-1;
for(var i=0;i<this.targets.length;i++){
var t=this.targets[i];
if(t.cx){
var dx=mouseX-t.cx;
var dy=mouseY-t.cy;
var r=t.r;
if(dx*dx+dy*dy<r*r){
hit=i;
if(hit!==this.openTooltipIndex){
// configure & open the tooltip
this.openTooltipIndex=hit;
this.$tip
.text(t.tipText)
.css({left:t.cx,top:t.cy-t.r-10-this.$tip.height()})
.show();
}
}
}
}
// hide the tip if no target was hit
if(hit==-1 && this.openTooltipIndex!==-1){
this.$tip.hide();
this.openTooltipIndex=-1;
}
}
return(CanvasTooltip);
})(); // end CanvasTooltip
//
// end CanvasTooltip
////////////////////////////
var dataDef = { title: "US Population Chart",
xLabel: 'Date',
yLabel: 'Price',
labelFont: '19pt Arial',
dataPointFont: '10pt Arial',
renderTypes: [CanvasChart.renderType.lines, CanvasChart.renderType.points],
dataPoints: [{ x: '1-aug', y: 2100 },
{ x: '2-aug', y: 2000 },
{ x: '3-aug', y: 2200 },
{ x: '4-aug', y: 1800 },
{ x: '5-aug', y: 1500 },
{ x: '6-aug', y: 3000 },
]
};
CanvasChart.render('canvas', dataDef);
// addition
var tooltip=new CanvasTooltip('canvas',CanvasChart.dataXY);
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="canvas" width=300 height=300></canvas>
这篇关于如何在图的悬停转折点上显示Y轴值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文