html

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>canvas test</title>
    <script src="test.js" language="javascript" type=""></script>
  </head>
  <body onload="main()" style="background-color:darkgray">
    <canvas id="canvas" width="500px" height="500px" style="background-color:gray"/>
  </body>
</html>

javascript

var NodePaddingW = 3;
var NodePaddingH = 3;
var NodeMarginW = 15;
var NodeMarginH = 3;
var NodeRadius = 5;
var NodeFontHeight = 15;
var NodeBGColor = "yellow";
var NodeTextColor = "black";

var RootNode = {"text":"hello html5", "child":[{"text":"html5 is gooooooood", "child":null}
                                           , {"text":"this is true", "child":[{"text":"beonit", "child":null}
                                                                              , {"text":"enoch", "child":[{"text":"beonit", "child":null}
                                                                                                          , {"text":"loves", "child":null}]
                                                                                }
                                                                              , {"text":"loves", "child":null}]
                                              
                                             }, {"text":"test", "child":null}]
           };


function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
    if (typeof stroke == "undefined" ) {
        stroke = true;
    }
    if (typeof radius === "undefined") {
        radius = 5;
    }
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
    if (stroke) {
        ctx.stroke();
    }
    if (fill) {
        ctx.fill();
    }        
}

function measureNode(node){
    node["height"] = 0;
    // no child
    if( node.child == null ){
        node.height = NodeFontHeight + NodePaddingH * 2 + NodeMarginH * 2;
        console.log("text:" + node.text + " nodeHeight:", node.height);
        return node.height;
    }
    // has child
    var childLen = node.child.length;
    for( var i in node.child ){
        node.height += measureNode(node.child[i]);
    }
    console.log("text:" + node.text + " nodeHeight:", node.height);
    return node.height;
}

function nodeDraw(ctx, x, y, node){
    // calc rect
    var calcRt = ctx.measureText(node.text);
    // console.log("text:" + node.text + " pos:" + x + ", " + y + " width:" + calcRt.width + " height:" + node.height);
    // draw rect
    ctx.fillStyle = NodeBGColor;
    roundRect(ctx, x-NodePaddingW, y-NodePaddingH, calcRt.width + NodePaddingW*2, NodeFontHeight + NodePaddingH*2, NodeRadius, true, true);
    // draw text
    ctx.fillStyle = NodeTextColor;
    ctx.fillText(node.text, x, y);
    // draw child
    if( node.child == null )
        return NodeFontHeight + NodePaddingH * 2 + NodeMarginH * 2;
    var childLen = node.child.length;
    var startY = y - node.height/2 + NodeMarginH * 2;
    var childHeight = 0;
    for( var i in node.child ){
        childHeight = node.child[i].height;
        console.log(node.text, "child", childLen, "startY", startY, "childHeight", childHeight);
        nodeDraw(ctx, x + calcRt.width + NodePaddingW * 2 + NodeMarginW, startY + childHeight/2, node.child[i]);
        startY += childHeight;
    }
}

function main(){
    var canvas = document.getElementById('canvas');
    if (!canvas.getContext){  
        return;
    }
    var ctx = canvas.getContext('2d');
    ctx.font = NodeFontHeight + "px sans-serif";
    ctx.textBaseline = "top";
    ctx.fillStyle = "yellow";
    console.log("make node start");
    console.log("measure node start");
    measureNode(RootNode);
    console.log("draw node start");
    nodeDraw(ctx, 100, 100, RootNode);
}
Retrieved from http://wiki.zeropage.org/wiki.php/html5practice/계층형자료구조그리기
last modified 2021-02-07 05:31:41