{"id":3535,"date":"2024-10-08T11:37:49","date_gmt":"2024-10-08T03:37:49","guid":{"rendered":"https:\/\/blog.zengqq.com.cn\/?p=3535"},"modified":"2024-10-08T11:37:49","modified_gmt":"2024-10-08T03:37:49","slug":"3535","status":"publish","type":"post","link":"https:\/\/blog.zengqq.com.cn\/?p=3535","title":{"rendered":""},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html>\n\n&lt;head>\n    &lt;meta charset='utf-8'>\n    &lt;meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\">\n    &lt;meta name=\"description\" content=\"Online Ishikava \/ Fishbone diagram\">\n    &lt;link rel=\"stylesheet\" type=\"text\/css\" media=\"screen\" href=\"stylesheet.css\">\n    &lt;title>Online Ishikava \/ Fishbone diagram&lt;\/title>\n    &lt;style>\n        html, body{ margin: 0; padding: 0; overflow: hidden;background: none}\n\n        *{ font-family: monospace; }\n\n        .note {color:gray;font-size: 0.8em;}\n\n        .label-0{ font-size: 2em; }\n        .label-1{ font-size: 1.5em; fill: #111; }\n        .label-2{ font-size: 1em; fill: #444; }\n        .label-3{ font-size: .9em; fill: #888; }\n        .label-4{ font-size: .8em; fill: #aaa; }\n        .label-5{ font-size: .8em; fill: #aaa; }\n        .label-6{ font-size: .8em; fill: #aaa; }\n\n        .link-0{ stroke: #000; stroke-width: 2px}\n        .link-1{ stroke: #333; stroke-width: 1px}\n        .link-2,\n        .link-3,\n        .link-4,\n        .link-5,\n        .link-6{ stroke: #666; stroke-width: .5px; }\n\n        .link-positive { stroke: blue; }\n        .link-negative { stroke: red; }\n\n        .positive { fill: green; stroke: green; }\n        .negative { fill: red; stroke: red; }\n    &lt;\/style>\n    &lt;script src=\"http:\/\/code.jquery.com\/jquery-1.11.3.min.js\">&lt;\/script>\n    &lt;script src=\"http:\/\/cdnjs.cloudflare.com\/ajax\/libs\/d3\/3.4.1\/d3.min.js\" charset=\"utf-8\">&lt;\/script>\n    &lt;script src=\".\/d3.fishbone.js\" charset=\"utf-8\">&lt;\/script>\n    &lt;script src=\".\/underscore-min.js\" charset=\"utf-8\">&lt;\/script>\n    &lt;script src=\".\/underscore.string.min.js\" charset=\"utf-8\">&lt;\/script>\n&lt;\/head>\n\n&lt;body>\n\n&lt;!-- HEADER -->\n&lt;div id=\"header_wrap\" class=\"outer\">\n    &lt;header class=\"inner\">\n        &lt;h2 id=\"project_tagline\">Online Ishikava \/ Fishbone diagram&lt;\/h2>\n    &lt;\/header>\n&lt;\/div>\n\n&lt;div style=\"padding: 2px;width: 24%;float:left;min-height: 1000px;\">\n    &lt;p class=\"note\">- Type brainstorm protocol below&lt;\/p>\n    &lt;p class=\"note\">- Redraw happens on Enter or use &lt;button id=\"refresh\">Refresh&lt;\/button>&lt;\/p>\n    &lt;p class=\"note\">- Use double-click on node to drill down&lt;\/p>\n    &lt;p class=\"note\">- Click to &lt;a href=\"#\">get back to root&lt;\/a>&lt;\/p>\n&lt;textarea id=\"structure\" style=\"width:100%; min-height: 600px;\">\nA Problem\n- People\n-- Fatigue\n--- Why?\n---- Why?\n     ! Comment node with exclamation \/ @author \/ + for pros\n     ! Comment node with exclamation \/ @author \/ - for cons\n\n- Interactions\n-- Precedent\n--- Why?\n\n- Processes\n-- A lot of meetings\n--- Why?\n\n- Materials\n-- Slow server\n--- Why?\n\n- Environment\n-- Market is down\n--- Why?\n\n- Requirements\n-- Too large stories\n--- Why?\n&lt;\/textarea>\n&lt;\/div>\n\n&lt;div id=\"target\" style=\"border: dotted 1px #000; min-height: 1000px; width: 75%;float:right\">&lt;\/div>\n\n&lt;script>\n\n    var drawInContext = function() {\n\n        var srcData = getData();\n\n        var k = ((window.location.hash || '').substr(1) || srcData&#91;0].k);\n\n        var rec = srcData.filter(function (row) {\n            return row.k === k;\n        });\n\n        if (rec.length === 0) {\n            return &#91;];\n        }\n\n        var path = rec&#91;0].path + '\/' + rec&#91;0].k;\n\n        var subX = srcData.filter(function (row) {\n            return row.path.indexOf(path) === 0;\n        });\n\n        srcData = rec.concat(subX);\n\n        drawFishbone(srcData);\n    };\n\n    $('#structure').on('keypress', function (e) {\n        if (e.keyCode === 13) {\n            parseSrc();\n            drawInContext();\n        }\n    });\n\n    $('#refresh').on('click', function (e) {\n        parseSrc();\n        drawInContext();\n    });\n\n    var size = (function () {\n        var g = window.document.documentElement;\n        return {\n            width: $('#target').width(),\n            height: g.clientHeight - 65\n        };\n    });\n\n    var times = function (num) {\n        var r = &#91;];\n        for (var i = 0; i &lt; num; i++) r.push(i);\n        return r;\n    };\n\n    var svg;\n    var fishbone;\n    var srcData = &#91;];\n    var feedback = &#91;];\n\n    function parseTokenRow(str, i) {\n        var c = -1;\n        while (str.charAt(++c) === '-');\n        var token = str.substr(c).trim();\n        var parts = token.split('\/');\n        return {\n            level: c,\n            key: (parts&#91;0] + i),\n            name: (parts&#91;0]),\n            rate: ((parts&#91;1] === '+') ? (+1) : (-1))};\n    }\n\n    function parseCommentRow(str) {\n        return str\n                .trim()\n                .substr(1) \/\/ remove !\n                .split('\/')\n                .map(function (p) {\n                    return p.trim();\n                })\n                .reduce(function (memo, p) {\n                    var c = p.charAt(0);\n                    if (c === '+') {\n                        memo.rate = (+1);\n                    } else if (c === '-') {\n                        memo.rate = (-1);\n                    } else if (c === '@') {\n                        memo.author = p.substr(1);\n                    } else {\n                        memo.comment = p;\n                    }\n                    return memo;\n                }, {});\n    }\n\n    function parseSrc() {\n\n        var v = $('#structure').val();\n        var t = v.split('\\n');\n\n        var path = &#91;];\n        feedback = &#91;];\n        srcData = &#91;];\n        t\n                .filter(function (rowStr) {\n                    return !!rowStr.trim();\n                })\n                .forEach(function (rowStr, i) {\n                    var s = rowStr.trim();\n                    if (s.charAt(0) === '!') {\n                        \/\/ comment\n                        var c = parseCommentRow(s);\n                        feedback.push({\n                            k: path&#91;path.length - 1],\n                            rate: (c.rate || -1),\n                            comment: c.comment,\n                            author: c.author\n                        });\n                    } else {\n                        \/\/ structure\n                        var o = parseTokenRow(s, i);\n                        var lvl = o.level;\n                        var key = o.key;\n                        var name = o.name;\n                        var rate = o.rate;\n                        path&#91;lvl] = key;\n                        path = path.slice(0, (lvl + 1));\n                        srcData.push({\n                            \"k\": key,\n                            \"name\": name,\n                            \"path\": &#91;'.'].concat(path.slice(0, lvl)).join('\/'),\n                            \"rate\": rate\n                        });\n                    }\n                });\n    }\n\n    parseSrc();\n\n    var forceLayout = function () {\n        var s = size();\n        var force = fishbone.force();\n        force.size(&#91;s.width, s.height]);\n        force.start();\n        times(250).forEach(force.tick.bind(force));\n        force.stop();\n\n        force.start();\n    };\n\n    var onDblClickBranch = function (row) {\n        window.location.hash = ('#' + row.k);\n    };\n\n    var getData = function () {\n        return JSON.parse(JSON.stringify(srcData));\n    };\n\n    var drawFishbone = function (data) {\n\n        \/\/ create the configurable selection modifier\n        fishbone = d3.fishbone(\n                size(),\n                function () {\n                    return data;\n                },\n                function () {\n                    return feedback;\n                },\n                onDblClickBranch,\n                function () {});\n\n        var target = d3.select('#target');\n        target.select('svg').remove();\n        svg = target\n                .append('svg')\n                .attr(size())\n                .call(fishbone.defaultArrow)\n                .call(fishbone);\n\n        forceLayout();\n    };\n\n    $(window).on('hashchange', drawInContext);\n    drawInContext();\n\n    \/\/ handle resizing the window\n    d3\n        .select(window)\n        .on(\"resize\", function () {\n            forceLayout();\n            svg.attr(size());\n        });\n&lt;\/script>\n&lt;script>\n    (function(i,s,o,g,r,a,m){i&#91;'GoogleAnalyticsObject']=r;i&#91;r]=i&#91;r]||function(){\n                (i&#91;r].q=i&#91;r].q||&#91;]).push(arguments)},i&#91;r].l=1*new Date();a=s.createElement(o),\n            m=s.getElementsByTagName(o)&#91;0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n    })(window,document,'script','\/\/www.google-analytics.com\/analytics.js','ga');\n\n    ga('create', 'UA-67431368-1', 'auto');\n    ga('send', 'pageview');\n\n&lt;\/script>\n&lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[89],"tags":[],"class_list":["post-3535","post","type-post","status-publish","format-standard","hentry","category-live"],"_links":{"self":[{"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/3535","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3535"}],"version-history":[{"count":3,"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/3535\/revisions"}],"predecessor-version":[{"id":3538,"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/3535\/revisions\/3538"}],"wp:attachment":[{"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3535"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zengqq.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}