Hey I have create a Duval Pentagon based on the post of creating duval triangle in canvas: how to create Duval Triangle in canvas.
My final result should be:
my current situation, is that I can created all the segments inside the pentagon,but I didn't figure out a way of placing labels of the gases around each corner(point) of my duval pentagon,any advice or help is welcome.
The creating of the duval pentagon process is like this:
1.creating outer pentagon.
2.creating all the segments in a loop.
3.creating the legend for the pentagon.
Update: I have tried to build again the the moleculeLabel according to @markE guidance lines. so far no so good tried, I am sure doing something wrong. :(
function moleculeLabel(V,P,text){
var dx=V.x-P.x;
var dy=V.y-P.y;
var rAngle=Math.atan2(dy,dx);
var padding=15; // == how far outside the pentagon you want to go
var outsideX=P.x+(P.radius+padding)*Math.cos(rAngle);
var outsideY=P.y+(P.radius+padding)*Math.sin(rAngle);
ctx.textAlign='center';
ctx.textBaseline='middle';
ctx.fillStyle='black';
ctx.fillText(text,outsideX,outsideY);
}`
$(function() {
//offset :
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var points = [{
x: 397,
y: 149
}, {
x: 318,
y: 346
}, {
x: 112,
y: 347
}, {
x: 44,
y: 147
}, {
x: 221,
y: 27
}, {
x: 397,
y: 149
}];
var cx = 0;
var cy = 0;
for (var i = 0; i < points.lenght; i++) {
cx = cx + points[i].x;
cy = cy + points[i].y;
}
cx = cx / points.lenght;
cy = cy / points.lenght;
var centerPoint = {
x: cy,
y: cy
};
// Define all your segments here
var segments = [{
points: [{
x: 61,
y: 191
}, {
x: 112,
y: 347
}, {
x: 190,
y: 223
}, {
x: 214,
y: 211
}, {
x: 217,
y: 198
}, {
x: 61,
y: 192
}],
fill: 'rgb(172,236,222)',
label: {
text: 'T1',
cx: 130,
cy: 250,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 61,
y: 191
}, {
x: 217,
y: 198
}, {
x: 220,
y: 26
}, {
x: 44,
y: 149
}],
fill: 'deepskyblue',
label: {
text: 'S',
cx: 140,
cy: 150,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 220,
y: 26
}, {
x: 217,
y: 198
}, {
x: 239,
y: 135
}, {
x: 365,
y: 230
}, {
x: 397,
y: 149
}, {
x: 221,
y: 27
}],
fill: 'lightCyan',
label: {
text: 'D1',
cx: 270,
cy: 110,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 214,
y: 211
}, {
x: 239,
y: 135
}, {
x: 365,
y: 231
}, {
x: 320,
y: 336
}, ],
fill: 'navajoWhite',
label: {
text: 'D2',
cx: 270,
cy: 210,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 190,
y: 223
}, {
x: 214,
y: 211
}, {
x: 320,
y: 336
}, {
x: 318,
y: 346
}, {
x: 223,
y: 346
}],
fill: 'tan',
label: {
text: 'T3',
cx: 250,
cy: 310,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 112,
y: 347
}, {
x: 190,
y: 223
}, {
x: 223,
y: 346
}],
fill: 'peru',
label: {
text: 'T2',
cx: 175,
cy: 300,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 210,
y: 105
}, {
x: 219,
y: 105
}, {
x: 219,
y: 68
}, {
x: 210,
y: 67
}],
fill: 'red',
label: {
text: 'PD',
cx: 170,
cy: 87,
withLine: true,
endX: 215,
endY: 88
},
}];
// label styles
var labelfontsize = 12;
var labelfontface = 'verdana';
var labelpadding = 3;
var legendTexts = ['PD = Partial Discharge', 'T1 = Thermal fault < 300 celcius', '...'];
// start drawing
/////////////////////
// draw pentagon
drawPentagon(points);
// draw colored segments inside pentagon
for (var i = 0; i < segments.length; i++) {
drawSegment(segments[i]);
}
moleculeLabel(points[0], centerPoint, 'CH4');
moleculeLabel(points[1], centerPoint, 'CH2');
moleculeLabel(points[2], centerPoint, 'H2');
// draw legend
drawLegend(legendTexts, 10, 10, 12.86);
// end drawing
/////////////////////
function drawSegment(s) {
// draw and fill the segment path
ctx.beginPath();
ctx.moveTo(s.points[0].x, s.points[0].y);
for (var i = 1; i < s.points.length; i++) {
ctx.lineTo(s.points[i].x, s.points[i].y);
}
ctx.closePath();
ctx.fillStyle = s.fill;
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = 'black';
ctx.stroke();
// draw segment's box label
if (s.label.withLine) {
lineBoxedLabel(s, labelfontsize, labelfontface, labelpadding);
} else {
boxedLabel(s, labelfontsize, labelfontface, labelpadding);
}
}
function boxedLabel(s, fontsize, fontface, padding) {
var centerX = s.label.cx;
var centerY = s.label.cy;
var text = s.label.text;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle'
ctx.font = fontsize + 'px ' + fontface
var textwidth = ctx.measureText(text).width;
var textheight = fontsize * 1.286;
var leftX = centerX - textwidth / 2 - padding;
var topY = centerY - textheight / 2 - padding;
ctx.fillStyle = 'white';
ctx.fillRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2);
ctx.lineWidth = 1;
ctx.strokeRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2);
ctx.fillStyle = 'black';
ctx.fillText(text, centerX, centerY);
}
function lineBoxedLabel(s, fontsize, fontface, padding) {
var centerX = s.label.cx;
var centerY = s.label.cy;
var text = s.label.text;
var lineToX = s.label.endX;
var lineToY = s.label.endY;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle'
ctx.font = fontsize + 'px ' + fontface
var textwidth = ctx.measureText(text).width;
var textheight = fontsize * 1.286;
var leftX = centerX - textwidth / 2 - padding;
var topY = centerY - textheight / 2 - padding;
// the line
ctx.beginPath();
ctx.moveTo(leftX, topY + textheight / 2);
ctx.lineTo(lineToX, topY + textheight / 2);
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.stroke();
// the boxed text
ctx.fillStyle = 'white';
ctx.fillRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2);
ctx.strokeRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2);
ctx.fillStyle = 'black';
ctx.fillText(text, centerX, centerY);
}
function moleculeLabel(V, P, text) {
var dx = V.x - P.x;
var dy = V.y - P.y;
var rAngle = Math.atan2(dy, dx);
var padding = 15; // == how far outside the pentagon you want to go
var outsideX = P.x + (P.radius + padding) * Math.cos(rAngle);
var outsideY = P.y + (P.radius + padding) * Math.sin(rAngle);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'black';
ctx.fillText(text, outsideX, outsideY);
}
/**
* draw basic pentagon.
**/
function drawPentagon(points) {
ctx.beginPath();
for (var i = 0; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.stroke();
ctx.closePath();
}
function drawLegend(texts, x, y, lineheight) {
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.fillStyle = 'black';
ctx.font = '12px arial';
for (var i = 0; i < texts.length; i++) {
ctx.fillText(texts[i], x, y + i * lineheight);
}
}
})
body {
background-color: ivory;
padding: 10px;
}
#canvas {
border: 1px solid red;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width=650 height=500></canvas>