js绘图库raphael实例

模拟微步

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
    text-align: center;
}
#canvas {
    background-color: pink;
    margin: 0 auto;
    width: 80%;
    height: 100px;
}
</style>
<script type="text/javascript" src="raphael.js"></script>
<script type="text/javascript">
var canvas = null;
var paper = null;
var nodes = [];
var links = [];
var col_width = 100;
var row_height = 100;
var node_count = 100;
window.onload = function() {
    canvas = document.getElementById('canvas');
    paper = Raphael('canvas');
    initNodes();
    initLinks();
    func1();
};
window.onresize = function() {
    func1();
};
function initNodes() {
    for (var i = 0; i < node_count; i++) {
        var node = {};
        node.shape = paper.circle(50, 50, 20, 20);
        node.text = paper.text(50, 50, i);
        nodes.push(node);
    }
}
function initLinks() {
    for (var i = 0; i < nodes.length; i++) {
        if (i == nodes.length - 1) break;
        var n = nodes[i];
        var n1 = nodes[i+1];
        var path = [
            ["M", n.shape.attr("cx"), n.shape.attr("cy")],
            ["L", n1.shape.attr("cx"), n1.shape.attr("cy")]
        ];
        links.push(paper.path(path).attr({stroke: "green", "stroke-width": 2}));
    }
}
function setNodes() {
    for (var i = 0; i < nodes.length; i++) {
        var n = nodes[i];
        //n.shape.translate(i*50, 50);
        //n.text.translate(i*50, 50);
        n.shape.attr({cx: i*50, cy: 50});
        n.text.attr({x: i*50, y: 50});
    }
}
function setLinks() {
    for (var i = 0; i < nodes.length; i++) {
        if (i == nodes.length - 1) break;
        var n = nodes[i];
        var n1 = nodes[i+1];
        var path = [
            ["M", n.shape.attr("cx"), n.shape.attr("cy")],
            ["L", n1.shape.attr("cx"), n1.shape.attr("cy")]
        ];
        links[i].attr({path: path});
    }
}
function func1() {
    var canvas_width = canvas.offsetWidth;
    var row_node_count = parseInt(canvas_width / col_width);
    var row_count = parseInt(node_count / row_node_count) + 1;
    var canvas_height = row_height * row_count;
    //alert(canvas_width);
    canvas.style.height = canvas_height + 'px';
    paper.setSize(canvas_width, canvas_height);
    //paper.clear();
    //paper.rect(10, 10, canvas_width-40, canvas_height-20);
    var k = 0;
    for (var i = 0; i < row_count; i++) {
        if (i % 2 == 0) {
            for (var j = 0; j < row_node_count; j++) {
                if (k == node_count) break;
                nodes[k].shape.attr({cx: j*col_width + col_width/2, cy: i*row_height + row_height/2});
                nodes[k].text.attr({x: j*col_width + col_width/2, y: i*row_height + row_height/2});
                k++;
            }
        } else {
            for (var j = row_node_count-1; j >= 0; j--) {
                if (k == node_count) break;
                nodes[k].shape.attr({cx: j*col_width + col_width/2, cy: i*row_height + row_height/2});
                nodes[k].text.attr({x: j*col_width + col_width/2, y: i*row_height + row_height/2});
                k++;
            }
        }
    }
    setLinks();
}
</script>
</head>
<body>
<div id="canvas">
</div>
</body>
</html>
View Code

 拖动连线跟随

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>raphael拖动</title>
<style type="text/css">
#holder {
    top: 0px;
    left: 0px;
    right: 0px;
    bottom: 0px;
    position: absolute;
    z-index: 999;
    //background-color: pink;
}
.test {
    position: absolute;
    width: 80px;
    height: 30px;
    top: 0px;
    z-index: 0;
    //background-color: purple;
}
</style>
<script type="text/javascript" src="raphael.js"></script>
<script>
Raphael.fn.drawArr = function(obj) {
    var point = getStartEnd(obj.obj1, obj.obj2);
    var path1 = getArr(point.start.x, point.start.y, point.end.x, point.end.y, 8);
    if (obj.arrPath) {
        obj.arrPath.attr({path: path1});
    } else {
        obj.arrPath = this.path(path1);
    }
    return obj;
};
function getStartEnd(obj1, obj2) {
    var bb1 = obj1.getBBox(),
        bb2 = obj2.getBBox();
    var p = [
    {x: bb1.x + bb1.width / 2, y: bb1.y - 1},
    {x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1},
    {x: bb1.x - 1, y: bb1.y + bb1.height / 2},
    {x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2},
    {x: bb2.x + bb2.width / 2, y: bb2.y - 1},
    {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1},
    {x: bb2.x - 1, y: bb2.y + bb2.height / 2},
    {x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2},
    ];
    var d = {}, dis = [];
    for (var i = 0; i < 4; i++) {
        for (var j = 4; j < 8; j++) {
            var dx = Math.abs(p[i].x - p[j].x),
                dy = Math.abs(p[i].y - p[j].y);
            if (
                    (i == j - 4) ||
                    (((i != 3 && j != 6) || p[i].x < p[j].x) &&
                     ((i != 2 && j != 7) || p[i].x > p[j].x) &&
                     ((i != 0 && j != 5) || p[i].y > p[j].y) &&
                     ((i != 1 && j != 4) || p[i].y < p[j].y))
               ) {
                dis.push(dx + dy);
                d[dis[dis.length - 1]] = [i, j];
            }
        }
    }
    if (dis.length == 0) {
        var res = [0, 4];
    } else {
        res = d[Math.min.apply(Math, dis)];
    }
    var result = {};
    result.start = {};
    result.end = {};
    result.start.x = p[res[0]].x;
    result.start.y = p[res[0]].y;
    result.end.x = p[res[1]].x;
    result.end.y = p[res[1]].y;
    return result;
}
function getArr(x1, y1, x2, y2, size) {
    var angle = Raphael.angle(x1, y1, x2, y2);
    var a45 = Raphael.rad(angle - 45);
    var a45m = Raphael.rad(angle + 45);
    var x2a = x2 + Math.cos(a45) * size;
    var y2a = y2 + Math.sin(a45) * size;
    var x2b = x2 + Math.cos(a45m) * size;
    var y2b = y2 + Math.sin(a45m) * size;
    var result = ["M", x1, y1, "L", x2, y2, "L", x2a, y2a, "M", x2, y2, "L", x2b, y2b];
    return result;
}
</script>
</head>
<body>
<div id="holder"></div>
<div id="test1" class="test">测试1</div>
<div id="test2" class="test">测试2</div>
<div id="test3" class="test">测试3</div>
<div id="test4" class="test">测试4</div>
</body>
<script>
window.onload = function() {
        var connections = [];
        var dragger = function() {
            this.ox = this.attr("x");
            this.oy = this.attr("y");
            this.animate({"fill-opacity": .2}, 500);
        };
        var move = function(dx, dy) {
            var att = {x: this.ox + dx, y: this.oy + dy};
            this.attr(att);
            //$("#test" + this.id).offset({top: this.oy + dy + 10, left: this.ox + dx + 10});
            var $t = document.getElementById('test' + this.id);
            $t.style.top = (this.oy+dy+10) + 'px';
            $t.style.left = (this.ox+dx+10) + 'px';
            for (var i = connections.length; i--;) {
                r.drawArr(connections[i]);
            }
        };
        var up = function() {
            this.animate({"fill-opacity": 0}, 500);
        };
        var $h = document.getElementById('holder');
        var r = Raphael("holder", $h.offsetWidth, $h.offsetHeight);
        var shapes = [
                r.rect(190, 100, 60, 40, 4),
                r.rect(290, 80, 60, 40, 4),
                r.rect(290, 180, 60, 40, 4),
                r.rect(450, 100, 60, 40, 4)
                ];
        //$("#test1").offset({top: 100 + 10, left: 190 + 10});
        //$("#test2").offset({top: 80 + 10, left: 290 + 10});
        //$("#test3").offset({top: 180 + 10, left: 290 + 10});
        //$("#test4").offset({top: 100 + 10, left: 450 + 10});
        var $t1 = document.getElementById('test1');
        var $t2 = document.getElementById('test2');
        var $t3 = document.getElementById('test3');
        var $t4 = document.getElementById('test4');
        $t1.style.top = (100+10) + 'px';
        $t1.style.left = (190+10) + 'px';
        $t2.style.top = (80+10) + 'px';
        $t2.style.left = (290+10) + 'px';
        $t3.style.top = (180+10) + 'px';
        $t3.style.left = (290+10) + 'px';
        $t4.style.top = (100+10) + 'px';
        $t4.style.left = (450+10) + 'px';
        for (var i = 0, ii = shapes.length; i < ii; i++) {
            var color = Raphael.getColor();
            shapes[i].attr({fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move"});
            shapes[i].id = i + 1;
            shapes[i].drag(move, dragger, up);
            shapes[i].dblclick(function() {alert(this.id);});
        }
        connections.push(r.drawArr({obj1: shapes[0], obj2: shapes[1]}));
        connections.push(r.drawArr({obj1: shapes[1], obj2: shapes[2]}));
        connections.push(r.drawArr({obj1: shapes[2], obj2: shapes[3]}));
};
</script>
</html>
View Code

 模拟微步2

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="raphael.js"></script>
</head>
<body>
<div id="holder"></div>
</body>
</html>
<script>
var busIcon = "M30.171,7.314c-0.025-0.274-0.215-0.498-0.421-0.498s-0.375-0.169-0.375-0.375s-0.222-0.337-0.493-0.292L27.41,6.399C27.114,4.607,26.67,3.486,26,2.816c-2-2-18-2-20,0C5.331,3.486,4.886,4.607,4.589,6.399L3.118,6.15C2.847,6.104,2.625,6.235,2.625,6.441S2.456,6.816,2.25,6.816S1.854,7.041,1.829,7.314l-0.47,5.066c-0.025,0.274,0.179,0.498,0.454,0.498h1.062c0.275,0,0.521-0.224,0.546-0.498l0.393-4.232c0.025-0.274,0.268-0.46,0.54-0.415l0.054,0.009C4.007,11.396,4,29.684,4,29.684c0,0.553,0.14,1,0.313,1h2.562c0.173,0,0.313-0.447,0.313-1v-1.893c4.643,0.698,12.982,0.698,17.625,0v1.889c0,0.553,0.141,1,0.312,1h2.562c0.172,0,0.312-0.447,0.312-1c0,0-0.007-18.283-0.407-21.937l0.054-0.009c0.271-0.046,0.514,0.141,0.539,0.415l0.394,4.232c0.025,0.274,0.271,0.498,0.546,0.498h1.062c0.275,0,0.479-0.224,0.454-0.498L30.171,7.314zM7.125,23.371c-1.001,0-1.812-0.812-1.812-1.812s0.812-1.812,1.812-1.812s1.812,0.812,1.812,1.812S8.126,23.371,7.125,23.371zM5.042,15.977C5.143,8.542,5.491,4.739,6.707,3.523C7.194,3.037,10.484,2.316,16,2.316c5.516,0,8.806,0.72,9.293,1.207c1.217,1.216,1.564,5.02,1.665,12.455c-1.175,0.473-4.904,1.025-10.958,1.025C9.951,17.004,6.222,16.452,5.042,15.977zM23.062,21.559c0-1.001,0.812-1.812,1.812-1.812s1.812,0.812,1.812,1.812s-0.812,1.812-1.812,1.812S23.062,22.56,23.062,21.559z";
var stationList = [
    {name: '车站00', distance: 0},
    {name: '车站01', distance: 10},
    {name: '车站02', distance: 20},
    {name: '车站03', distance: 30},
    {name: '车站04', distance: 40},
    {name: '车站05', distance: 50},
    {name: '车站06', distance: 60},
    {name: '车站07', distance: 70},
    {name: '车站08', distance: 80},
    {name: '车站09', distance: 90},
    {name: '车站10', distance: 100},
    {name: '车站11', distance: 110},
    {name: '车站12', distance: 120},
    {name: '车站13', distance: 130},
    {name: '车站14', distance: 140},
    {name: '车站15', distance: 150},
    {name: '车站16', distance: 160},
    {name: '车站17', distance: 170},
    {name: '车站18', distance: 180},
    {name: '车站19', distance: 190},
    {name: '车站20', distance: 200},
    {name: '车站21', distance: 210},
    {name: '车站22', distance: 220},
    {name: '车站23', distance: 230},
    {name: '车站24', distance: 240},
    {name: '车站25', distance: 250},
    {name: '车站26', distance: 260},
    {name: '车站27', distance: 270},
    {name: '车站28', distance: 280},
    {name: '车站29', distance: 290}
];
var r = Raphael('holder', 800, 600);
var nodeList = [];
var k = 0;
for (var i = 0; i < 4; i++) {
    if (i%2 == 0)
        for (var j = 0; j < 8; j++) {
            if (k == stationList.length) break;
            var s = stationList[k++].name;
            var node = {};
            node.shape = r.circle(j*100+50, i*100+50, 15).attr({'stroke': '#aaa', 'stroke-width': 2});
            node.text = r.text(j*100+50, i*100+50, s).attr({'stroke': '#211551', 'transform': 't0,10'});
            nodeList.push(node);
        }
    else
        for (var j = 7; j >= 0; j--) {
            if (k == stationList.length) break;
            var s = stationList[k++].name;
            var node = {};
            node.shape = r.circle(j*100+50, i*100+50, 15).attr({'stroke': '#aaa', 'stroke-width': 2});
            node.text = r.text(j*100+50, i*100+50, s).attr({'stroke': '#211551', 'transform': 't0,10'});
            nodeList.push(node);
        }
}
var linkList = [];
for (var i = 0; i < nodeList.length; i++) {
    if (i == nodeList.length-1) break;
    var n1 = nodeList[i];
    var n2 = nodeList[i+1];
    var p = [
        ["M", n1.shape.attr('cx'), n1.shape.attr('cy')],
        ["L", n2.shape.attr('cx'), n2.shape.attr('cy')]
            ];
    linkList.push(r.path(p).attr({'stroke': '#f0f', 'stroke-width': 4}).toBack());
}
var busInfo = {'speed': 0, 'distance': 0};
//var bus = r.path(busIcon).attr({'fill': '#0f0', 'stroke': 'none'});
//bus.translate(40, 20);
var bus1 = r.image('img/bus-green.png', 50, 30, 30, 40);
var c1 =  r.circle(50, 50, 20).attr({'stroke': 'orange', 'stroke-width': '3'});
console.log(bus1);
var distance = 0;
var speed = 0;
var status = '时速0公里,正常行驶';
var t1 = r.text(50, 20, status).attr({'stroke': 'blue', 'text-anchor': 'start'});
k = 1;
var lastp = 0;
var inter = window.setInterval(function() {
        speed = parseInt(Math.random()*100);
        distance += parseInt(Math.random()*11);
        if (distance > 300) window.clearInterval(inter);
        if (k < stationList.length - 1) {
            if (distance > stationList[k].distance) {
                k++;
                lastp = 0;
            }
            var percent = (distance - stationList[k-1].distance) / (stationList[k].distance - stationList[k-1].distance);
            //bus.translate((percent-lastp)*(nodeList[k].shape.attr('cx')-nodeList[k-1].shape.attr('cx')), (percent-lastp)*(nodeList[k].shape.attr('cy')-nodeList[k-1].shape.attr('cy')));
            bus1.attr({x: nodeList[k-1].shape.attr('cx')+percent*(nodeList[k].shape.attr('cx')-nodeList[k-1].shape.attr('cx')), y: nodeList[k-1].shape.attr('cy')+percent*(nodeList[k].shape.attr('cy')-nodeList[k-1].shape.attr('cy')) - 20});
            lastp = percent;
            if (speed > 70) {
                status = '时速' + speed + '公里,超速行驶';
                bus1.attr({src: 'img/bus-red.png'});
            } else {
                status = '时速' + speed + '公里,正常行驶';
                bus1.attr({src: 'img/bus-green.png'});
            }
            c1.attr({cx: nodeList[k].shape.attr('cx'), cy: nodeList[k].shape.attr('cy')});
            t1.attr({text: status, x: bus1.attr('x'), y: bus1.attr('y')-10});
            //nodeList[k-1].shape.attr({fill: 'cyan'});
        //console.log(k);
        }
    }, 1000);
</script>
View Code
原文地址:https://www.cnblogs.com/feilv/p/4503951.html