canvas绘制质控图

来源:互联网 发布:唐装连衣裙长款淘宝 编辑:程序博客网 时间:2024/06/15 17:08
document.getElementById("canvas1").clearAttributes;
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");


function LoadData()
{
    var value = 0.05;
    var pingfangcha = 0.0;
    var rows = [];
    for (var i = 0; i < 20; i++) {
        var id = i;
        var random = (Math.random() * 0.5 - 0.05).toFixed(4);
        var c = parseFloat(value) + parseFloat(random);
        rows.push(CreateJson(id, c.toFixed(4)));
    }
}




//画坐标轴
var ox = 50;
var oy = canvas.height - 50;
ctx.beginPath();
ctx.moveTo(ox, oy);
ctx.lineTo(canvas.width - ox, oy);
ctx.moveTo(ox, oy);
ctx.lineTo(ox, canvas.height - oy);


//辅助线
//平均值
drawDashLine(ctx, ox, canvas.height / 2, canvas.width - 60, canvas.height / 2, 5, "gray");
ctx.beginPath();
ctx.font = "15px Courier New";
//设置字体填充颜色
ctx.fillStyle = "blue";
ctx.fillText("平均值", canvas.width - ox, canvas.height / 2-10);
ctx.stroke();


ctx.beginPath();
drawDashLine(ctx, ox, canvas.height / 2 - canvas.height /12, canvas.width - ox, canvas.height / 2 - canvas.height /12, 5, "yellow");
ctx.fillText("上辅助线", canvas.width -  60, canvas.height / 2 - canvas.height /12 - 10);
drawDashLine(ctx, ox, canvas.height / 2 + canvas.height /12, canvas.width - ox, canvas.height / 2 + canvas.height /12, 5, "yellow");
ctx.fillText("下辅助线", canvas.width - 60, canvas.height / 2 + canvas.height /12 - 10);
ctx.stroke();
ctx.beginPath();
drawDashLine(ctx, ox, canvas.height / 2 - 2 * canvas.height /12, canvas.width - ox, canvas.height / 2 - 2 * canvas.height /12, 5, "green");
ctx.fillText("上警戒线", canvas.width - 60, canvas.height / 2 - 2 * canvas.height /12 - 10);
drawDashLine(ctx, ox, canvas.height / 2 + 2 * canvas.height /12, canvas.width - ox, canvas.height / 2 + 2 * canvas.height /12, 5, "green");
ctx.fillText("下警戒线", canvas.width - 60, canvas.height / 2 + 2 * canvas.height /12 - 10);
ctx.stroke();
ctx.beginPath();
drawDashLine(ctx, ox, canvas.height / 2 - 3 * canvas.height / 12, canvas.width - ox, canvas.height / 2 - 3 * canvas.height / 12, 5, "red");
ctx.fillText("上控制线", canvas.width - 60, canvas.height / 2 - 3 * canvas.height / 12 - 10);
drawDashLine(ctx, ox, canvas.height / 2 + 3 * canvas.height / 12, canvas.width - ox, canvas.height / 2 + 3 * canvas.height / 12, 5, "red");
ctx.fillText("下控制线", canvas.width - 60, canvas.height / 2 + 3 * canvas.height / 12 - 10);
ctx.stroke();


//求斜边长度  
function getBeveling(x, y) {
    return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
function drawDashLine(context, x1, y1, x2, y2, dashLen,color) {
    dashLen = dashLen === undefined ? 5 : dashLen;
    //得到斜边的总长度  
    var beveling = getBeveling(x2 - x1, y2 - y1);
    //计算有多少个线段  
    var num = Math.floor(beveling / dashLen);


    for (var i = 0 ; i < num; i++) {
        context[i % 2 == 0 ? 'moveTo' : 'lineTo'](x1 + (x2 - x1) / num * i, y1 + (y2 - y1) / num * i);
    }
    context.strokeStyle = color;
    context.stroke();
}


var value = 0.05;
var pingfangcha = 0.0;
var rows = [];
for (var i = 0; i < 20; i++)
{
    var id = i;
    var random = (Math.random()*0.5-0.05).toFixed(4);
    var c = parseFloat(value) + parseFloat(random);
    rows.push(CreateJson(id, c.toFixed(4)));
}
rows.push(CreateJson(21, (50).toFixed(4)));


function CreateJson(id, value) //JS 里面是不需要参数属性的
{
    var jsonStr = {};
    jsonStr.id = id;
    jsonStr.value = value;
    
    return jsonStr;
}


//计算标准差
var mean = Mean(rows);
var deviations = Deviations(rows,mean);
var stddev = Stddev(deviations);


function Mean(rows) {
    var sum = 0;
    for (var i = 0; i < rows.length; i++) {
        sum += parseFloat(rows[i].value);
    }
    return sum / rows.length;
}
function Deviations(rows, mean) {
    var sq = 0;
    for (var i = 0; i < rows.length; i++)
    {
       sq += (parseFloat(rows[i].value) - parseFloat(mean)) * (parseFloat(rows[i].value) - parseFloat(mean));
    }
    return sq / rows.length;
}
function Stddev(deviations) {
    return Math.sqrt(deviations).toFixed(4);
}


ctx.beginPath();
ctx.fillText(mean.toFixed(3), 5, canvas.height / 2);
ctx.fillText((parseFloat(mean) + parseFloat(stddev)).toFixed(3), 0, canvas.height / 2 - canvas.height /12);
ctx.fillText((parseFloat(mean) + 2 * parseFloat(stddev)).toFixed(3), 0, canvas.height / 2 - 2 * canvas.height /12);
ctx.fillText((parseFloat(mean) - parseFloat(stddev)).toFixed(3), 0, canvas.height / 2 + canvas.height /12);
ctx.fillText((parseFloat(mean) - 2 * parseFloat(stddev)).toFixed(3), 0, canvas.height / 2 + 2 * canvas.height / 12);
ctx.fillText((parseFloat(mean) + 3 * parseFloat(stddev)).toFixed(3), 0, canvas.height / 2 - 3 * canvas.height / 12);
ctx.fillText((parseFloat(mean) - 3 * parseFloat(stddev)).toFixed(3), 0, canvas.height / 2 + 3 * canvas.height / 12);
ctx.stroke();


//画数据
var length = (canvas.height /12) / stddev;
var p_width = (canvas.width - 2*ox) / rows.length;
ctx.beginPath();
ctx.moveTo(ox, canvas.height / 2 - (rows[0].value - mean) * length);
ctx.stroke();
// 保存画布上所有的圆圈
var circles = [];
for (var i = 0; i < rows.length; i++) {
    ctx.lineTo(ox + i * p_width, canvas.height / 2 - (rows[i].value - mean) * length);
    ctx.stroke();
    ctx.beginPath();
    var circle = new Circle(ox + i * p_width, canvas.height / 2 - (rows[i].value - mean) * length,4);
    ctx.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI);
    ctx.fill();
    ctx.stroke();
    circles.push(circle);
}


ctx.beginPath();
ctx.strokeStyle = "black";
//画刻度
for (var i = 4; i <= rows.length; i+=5) {
    ctx.moveTo(ox + i * p_width, oy);
    ctx.lineTo(ox + i * p_width, oy - 5);
    ctx.fillText(i+1,ox + i * p_width, oy + 20);
}
ctx.moveTo(ox + (rows.length-1) * p_width, oy);
ctx.lineTo(ox + (rows.length-1) * p_width, oy - 5);
ctx.fillText((rows.length), ox + (rows.length-1) * p_width, oy + 20);
ctx.stroke();


//记录数据点位的圆
function Circle(x, y, radius) {
    this.x = x;
    this.y = y;
    this.radius = radius;
}


$("#canvas1").click(function() {
    // 取得画布上被单击的点
    var clickX = event.pageX - canvas.offsetLeft;
    var clickY = event.pageY - canvas.offsetTop;
    // 查找被单击的圆圈
    for (var i = circles.length - 1; i >= 0; i--) {
        var circle = circles[i];
        //使用勾股定理计算这个点与圆心之间的距离
        var distanceFromCenter = Math.sqrt(Math.pow((circle.x) - (clickX), 2)
            + Math.pow((circle.y) - (clickY), 2))
        // 判断这个点是否在圆圈中
        if (distanceFromCenter <= circle.radius) {
            //选择新圆圈
            circle.isSelected = true;
            alert(rows[i].value);
            //停止搜索
            return;
        }
    }
});
原创粉丝点击