美文网首页
使用Gojs实现族谱

使用Gojs实现族谱

作者: woniuxia | 来源:发表于2020-03-14 13:52 被阅读0次

    效果图

    image.png

    介绍

    • 支持点击任何族人时,高亮显示该族人同一支的信息
    • 通过颜色区分族人属性, 属性包括: 男、女、死亡、在世
    • 前端go.js
    • 后端 python+Flask+sqlAlchemy+Jinja2

    变量解释

    参数名 必选 类型 说明
    clansmen_id Integer 族人id
    current_level string 当前辈分
    parent_id Integer 上辈族人id
    array string 上下级族人信息列表

    array列表单个元素数据格式

    参数名 必选 类型 说明
    clansmen_id Integer 族人id
    level Integer 族人辈分
    clansmen_name String 族人名称
    parent_id Integer 上辈族人id
    status String 族人状态 00-在世 01-去世
    companion_id Integer 老伴id
    companion_name String 老伴姓名
    companion_status String 老伴状态 00-在世 01-去世
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>红花堂</title>
        <meta name="description" content="A larger org chart with an Overview and searching capability."/>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script type="text/javascript" src="{{url_for('family_api.static', filename='js/go.js')}}"></script>
        <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
        <link rel="icon"
          type="image/png"
          href="{{url_for('family_api.static', filename='images/favicon.ico')}}">
        <style type="text/css">
            #myOverviewDiv {
                position: absolute;
                width: 200px;
                height: 100px;
                top: 10px;
                left: 10px;
                background-color: aliceblue;
                z-index: 300;
                /* make sure its in front */
                border: solid 1px blue;
            }
        </style>
    </head>
    
    <body style="background-color: #696969" >
    <div style="margin:0 auto;outline: rgba(50,50,50,0.8) ridge 1.5px;">
        <div id="sample" style="position: relative;">
            <div id="myDiagramDiv"
                 style="background-color: white; border: solid 1px black; width: 100%; min-height:100vh;"></div>
    <!--        <div id="myOverviewDiv"></div>-->
        </div>
    </div>
    
    <script>
    
            function invite(men_id) {
                if (isAndroid()) {
                    new ModelFactory("android", "invites", "backToAndroid").excuse({
                        'men_id': men_id
                    });
                } else if (isIOS()) {
                    window.webkit.messageHandlers.invite.postMessage({
                        'men_id': men_id
                    });
                } else {
                    return false;
                }
            }
            function get_men_info(men_id) {
                console.log(men_id);
                invite(men_id);
            };
    
            function isAndroid() {
                var u = navigator.userAgent,
                    app = navigator.appVersion;
                return u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
            }
    
            function isIOS() {
                var u = navigator.userAgent,
                    app = navigator.appVersion;
                return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
            }
            function ModelFactory(equipment, clz, method) {
                if (equipment == 'ios') {
                    this.modelObj = window.eval("window.webkit.messageHandlers." + method);
                    this.modelMethod = this.modelObj["postMessage"];
                } else if (equipment == 'android') {
                    this.modelObj = window[clz];
                    this.modelMethod = this.modelObj[method];
                } else {
                    window.location.href = 'error.html';
                }
    
                this.constructor.prototype.excuse = function (args) {
                    var jsonParams = JSON.stringify(args);
                    return this.modelMethod.call(this.modelObj, jsonParams);
                }
            }
    
    </script>
    
    <script type="text/javascript">
            window.onload = tree_init();
            function tree_init() {
                var myGoGrap = go.GraphObject.make;  // for conciseness in defining templates
                myDiagram = myGoGrap(go.Diagram, "myDiagramDiv",  // the DIV HTML element
                    {
                        // allowSelect: false,
                        isReadOnly: true, // 只读
                        allowDrop: false,
                        // hasHorizontalScrollbar:false,//去除水平滚动条
                        // hasVerticalScrollbar:false,//去除竖直滚动条
                        initialDocumentSpot: go.Spot.TopCenter,
                        // initialViewportSpot: go.Spot.TopCenter,
                        initialViewportSpot: go.Spot.TopCenter,
                        //initialContentAlignment: go.Spot.Center,
                        layout:
                            myGoGrap(go.TreeLayout,  // use a TreeLayout to position all of the nodes
                                {
                                    treeStyle: go.TreeLayout.StyleLastParents,
                                    arrangement: go.TreeLayout.ArrangementHorizontal,
                                    angle: 90,  // 角度   描述从父节点到子节点的生长方向  0/180 子节点形成垂直的层次-宽度是高度 深度是宽度;90/270 子节点形水平层
                                    layerSpacing: 25,   //父节点与子节点之间的距离 宽度是宽度 深度是高度
                                    alternateAngle: 90,
                                    alternateLayerSpacing: 35,
                                    alternateNodeSpacing: 20,
                                })
                    });
    
                /**判断第一行内容
                    儿子:夫
                    女儿:女
                */
                function oneInfoText(info) {
                    var str = "";
                    var name = "";
                    if (info.name != null) {
                        name = info.name;
                    }else{
                        name = "";
                    }
                    str = name;
                    //if (info.sex === "00") {
                    //    str = "夫:" + name;
                    //} else {
                    //    str = "女:" + name;
                    //}
                    //if (info.is_adoptive === "1") {
                    //    str = "【过】" + str
                    //}
                    return str;
                }
    
                /**判断第二行内容
                    儿媳:妻
                    女婿:婿
                */
                function twoInfoText(info) {
                    var str = "";
                    var name = "";
                    if (info.companion_name != null) {
                        name = info.companion_name;
                    }else{
                        name = "";
                    }
                    str = name;
                    //if (info.sex === "00") {
                    //    str = "妻:" + name;
                    //} else {
                    //    str = "婿:" + name;
                    //}
                    //if (info.is_ruzhui === "1") {
                    //    str = "【婿】" + str;
                    //}
                    return str;
                }
    
                /*判断第一行背景颜色
                 去世: 黑色
                 儿子-酒红色
                 女儿-粉红色
               */
                function oneInfobackground(info) {
                    var status = info.status;
                    if (status === null) {
                        status = '00';
                    }
                    if (info.sex === '00') {
                        //儿子
                        if (status === '00') {
                            //在世  酒红色
                            return '#99110f'
                        } else {
                            //去世
                            return 'black';
                        }
                    } else {
                        //女儿
                        if (status === '00') {
                            //在世 粉红色
                            return '#FF33CC'
                        } else {
                            //去世
                            return 'black';
                        }
                    }
                }
    
                /*判断第二行背景颜色
                去世: 黑色
                儿媳-酒红色
                女婿-粉红色
              */
                function twoInfobackground(info) {
                    if (info.companion_name === null || info.companion_name === "") {
                            return 'white';
                        }
                    var companion_status = info.companion_status;
                    if (companion_status === null) {
                        companion_status = '00';
                    }
                    if (info.sex === '01') {
                        //女婿
                        if (companion_status === '00') {
                            //在世  酒红色
                            return '#FF33CC'
                        } else {
                            //去世
                            return 'black';
                        }
                    } else {
                        //儿媳
                        if (companion_status === '00') {
                            //在世 粉红色
                            return '#99110f'
                        } else {
                            //去世
                            return 'black';
                        }
                    }
                }
    
                var node_item_arr = [];
                var current_node = "";
                /*
                * 子节点以及子节点连线高亮函数
                */
                function ergodicChildNode(node) {
                    var item = node.findTreeChildrenNodes().iterator;
                    if (node_item_arr.indexOf(item) > -1) {
                        item = node_item_arr.pop();
                    }
                    node.findTreeChildrenLinks().each(function (l) { l.isHighlighted = true; });
                    node.findTreeChildrenNodes().each(function (n) { n.isHighlighted = true; });
                    if (item.next()) {
                        current_node = item.value;
                        node_item_arr.push(item);
                        ergodicChildNode(current_node);
                    } else {
                        item = node_item_arr.pop();
                        if (item) {
                            if (item.next()) {
                                current_node = item.value;
                                node_item_arr.push(item);
                                ergodicChildNode(current_node);
                            } else {
                                ergodicChildNode(current_node);
                            }
                        }
                    }
    
                }
                //点击情况
                var click_bool = false;
                //当前选择的node
                var current_click_node = "";
                // define the Node template
                myDiagram.nodeTemplate =
                    myGoGrap(go.Node, "Auto",
                        { // when the user clicks on a Node, highlight all Links coming out of the node
                            // and all of the Nodes at the other ends of those Links.
                            click: function (e, node) {
                                if (current_click_node != node) {
                                    current_click_node = node;
                                    click_bool = false;
                                }
                                if(click_bool === false){
                                    // highlight all Links and Nodes coming out of a given Node
                                    var diagram = node.diagram;
                                    diagram.startTransaction("highlight");
                                    // remove any previous highlighting
                                    diagram.clearHighlighteds();
                                    //所有父级节点以及连接线高亮
                                    // console.log(node.findTreeParentChain());
                                    node.findTreeParentChain().each(function (n) { n.isHighlighted = true; });
                                    //所有子节点以及连接高亮
                                    ergodicChildNode(node);
                                    diagram.commitTransaction("highlight");
                                    click_bool = true;
                                }else{
                                    click_bool = false;
                                    get_men_info(node.data.key);
                                }
                            }
                        },
                        myGoGrap(
                            go.Shape,
                            "RoundedRectangle",
                            { stroke: "#9f201e", strokeWidth: 3, fill: "white", },
                            new go.Binding("stroke", "isHighlighted", function (h) { return h ? "#0080FF" : "#9f201e"; }).ofObject()
                        ),
                        myGoGrap(go.Panel, "Table",
                            {
                                margin: 2,
                                maxSize: new go.Size(120, NaN),
                            },
                            myGoGrap(go.RowColumnDefinition,
                                {
                                    column: 0,
                                    stretch: go.GraphObject.Horizontal,
                                    alignment: go.Spot.Center
                                }),
                            // the 夫
                            myGoGrap(go.TextBlock,
                                {
                                    row: 0,
                                    column: 0,
                                    width: 200,
                                    textAlign: 'center',
                                    graduatedSkip: false,
                                    stroke: 'white',
                                    maxSize: new go.Size(NaN, NaN),
                                    margin: 2,
                                    font: "400 25px Roboto, sans-serif",
                                    alignment: go.Spot.Center
                                },
                                new go.Binding("text", "", oneInfoText),
                                new go.Binding("background", "", oneInfobackground)),
                            myGoGrap(go.TextBlock,
                                {
                                    row: 1,
                                    column: 0,
                                    width: 200,
                                    textAlign: 'center',
                                    background: '#99110f',
                                    graduatedSkip: false,
                                    stroke: 'white',
                                    maxSize: new go.Size(NaN, NaN),
                                    margin: 2,
                                    font: "400 25px Roboto, sans-serif",
                                    alignment: go.Spot.Center
                                },
                                new go.Binding("text", "", twoInfoText),
                                new go.Binding("background", "", twoInfobackground)),
                        )  // end Table Panel
                    );  // end Node
    
                // define the Link template, a simple orthogonal line
                myDiagram.linkTemplate =
                    myGoGrap(
                        go.Link,
                        go.Link.Orthogonal,
                        { corner: 5, selectable: true, toShortLength: 0 },
                        myGoGrap(go.Shape,
                            // the Shape.stroke color depends on whether Link.isHighlighted is true
                            new go.Binding("stroke", "isHighlighted", function (h) { return h ? "#0080FF" : "#99110f"; })
                                .ofObject(),
                            // the Shape.strokeWidth depends on whether Link.isHighlighted is true
                            new go.Binding("strokeWidth", "isHighlighted", function (h) { return h ? 3 : 1; })
                                .ofObject(),
                        ),
                    );  // dark gray, rounded corner links
    
                var nodeDataArray_2;
                var current_node = "";
                var nodeObject = "";
                function get_tree_data() {
                    var tree_data;
                    $.ajax({
                        type: "POST",
                        url: "{{tree_data_url}}",
                        contentType: "application/json",
                        dataType: "json",
                        async: false,
                        data: JSON.stringify({
                            "method": "family.app.clansmen.all.data",
                            "biz_content": {
                                "clansmen_id": {{clansmen_id}},
                                "client_type": "h5",
                            }
                        }),
                        success: function (jsonResult) {
                            tree_data = jsonResult;
                        }
                    });
                    return tree_data;
                };
                nodeObject = get_tree_data();
                nodeDataArray_2 = nodeObject.resp_data.array;
                current_node = nodeObject.resp_data.clansmen_id;
                delete nodeDataArray_2[0].parent_id;
                // create the Model with data for the tree, and assign to the Diagram
                myDiagram.model =
                    myGoGrap(go.TreeModel,
                        {
                            nodeParentKeyProperty: "parent_id",  // this property refers to the parent node data
                            nodeDataArray: nodeDataArray_2
                        });
                // 当关系图第一次就绪时调用此事件处理程序 定位中心节点
                myDiagram.addDiagramListener("InitialLayoutCompleted", function (e) {
                    // pick a random node data
                    var cnt = 0;
                    for(cnt; cnt< nodeDataArray_2.length;cnt++){
                        if(current_node === nodeDataArray_2[cnt].key){
                            break;
                        }
                    }
                    var data = nodeDataArray_2[cnt];
                    // find the corresponding Node
                    var node = myDiagram.findNodeForData(data);
                    // and center it and select it
                    myDiagram.centerRect(node.actualBounds);
                    myDiagram.select(node);
                });
                myDiagram.click = function (e) {
                    e.diagram.commit(function (d) { d.clearHighlighteds(); }, "no highlighteds");
                };
                // Overview
                //myOverview =
                //    myGoGrap(go.Overview, "myOverviewDiv",  // the HTML DIV element for the Overview
                //        { observed: myDiagram, contentAlignment: go.Spot.Center });   // tell it which Diagram to show and pan
            }
    </script>
    
    </body>
    
    </html>
    

    相关文章

      网友评论

          本文标题:使用Gojs实现族谱

          本文链接:https://www.haomeiwen.com/subject/clebshtx.html