Вставить html FlameGraph в Azure вики - PullRequest
0 голосов
/ 27 апреля 2020

Мне нужно встроить приложение Flame Graph в Azure вики-страницу Devops.

FlameGraph - это визуализация стека вызовов приложения в очень простой и понятной форме. Физически это SVG-изображение, которое отображается браузером следующим образом (кликабельно):

Однако я хочу встроить не обычный FlameGraph, но HTML график, представляющий собой огромный отрезок из 70K + HTML и JS линий. Рендеринг кода выглядит полностью как SVG, вот пример

<g id="" class="func_g" onmouseover="s(this, '', 'perf')" onmouseout="c('', 'perf')" 
onclick="zoom(this, 'perf')" >
<title>consular_function</title>
<rect x="531.6" y="398" width="0.6" height="15.0" fill="rgb(220,220,220)" rx="2.2" ry="2.2" />
<text text-anchor="" x="534.61" y="408.5" font-size="12" font-family="Verdana" fill="rgb(0,0,0)"  > 
</text>
</g>
<g id="" class="func_g" onmouseover="s(this, '', 'perf')" onmouseout="c('', 'perf')" 
onclick="zoom(this, 'perf')" >
<title>db_function</title>
<rect x="1367.2" y="446" width="0.1" height="15.0" fill="rgb(130,202,250)" rx="2.2" ry="2.2" />
<text text-anchor="" x="1370.18" y="456.5" font-size="12" font-family="Verdana" fill="rgb(0,0,0)"  > 
</text>
</g>
<g id="" class="func_g" onmouseover="s(this, '', 'perf')" onmouseout="c('', 'perf')" onclick="zoom(this, 'perf')" > 
<title>db_function</title>
<rect x="1402.0" y="414" width="1.7" height="15.0" fill="rgb(130,202,250)" rx="2.2" ry="2.2" />
<text text-anchor="" x="1405.03" y="424.5" font-size="12" font-family="Verdana" fill="rgb(0,0,0)"  > 
</text>
</g>
<g id="" class="func_g" onmouseover="s(this, '', 'perf')" onmouseout="c('', 'perf')" 
onclick="zoom(this, 'perf')" >
<title>consular_function</title>
<rect x="1037.6" y="302" width="4.6" height="15.0" fill="rgb(220,220,220)" rx="2.2" ry="2.2" />
<text text-anchor="" x="1040.59" y="312.5" font-size="12" font-family="Verdana" fill="rgb(0,0,0)"  > 
</text>
</g>
<g id="" class="func_g" onmouseover="s(this, '', 'perf')" onmouseout="c('', 'perf')" 
onclick="zoom(this, 'perf')" >
<title>moduled_function (3,218 us, 0,04%)</title>
<rect x="10.8" y="494" width="0.7" height="15.0" fill="rgb(237,110,36)" rx="2.2" ry="2.2" />
<text text-anchor="" x="13.78" y="504.5" font-size="12" font-family="Verdana" fill="rgb(0,0,0)"  > 
</text>
</g>
<defs >
    <linearGradient id="background_mem" y1="0" y2="1" x1="0" x2="0" >
        <stop stop-color="#eeeeef" offset="10%" />
        <stop stop-color="#eeeee0" offset="90%" />
    </linearGradient>
</defs>
<style type="text/css">
    .func_g:hover { stroke:black; stroke-width:0.5; cursor:pointer; }
</style>


</svg>

<script type="text/ecmascript">
    // Javascript for svg file
    // Used to control flame graph operations, e.g. zoom in/out, search, etc
    if(typeof window.flameGraph == "undefined") window.flameGraph={};                     // global flame graph elements (contained width, it is a hashmap for each svgId)
    if(typeof window.searchButton == "undefined") window.searchButton={};                 // global searching button hashmap for each svgId
    if(typeof window.detailedTextField == "undefined") window.detailedTextField={};       // global detailed text box (on the bottom of graph) hashmap for each svgId
    if(typeof window.matchedTextField == "undefined") window.matchedTextField={};         // global matched text box (on the right of detailed text box) hashmap for each svgId
    if(typeof window.isSearching == "undefined") window.isSearching={};                   // global hashmap for each svg whether it is in searching mode or not
    if(typeof window.revertGraph == "undefined") window.revertGraph={};                   // global hashmap for each svg whether the flame graph is reverted or not

    revertGraph['mem'] = 0;
    function init(evt, hlString, svgId) { //init function used to initialize the variables
        if(svgId == undefined) return;
        flameGraph[svgId] = document.getElementById(svgId).getAttribute("svg_width");   // get flame graph width by internal svg label "svg_width"
        searchButton[svgId] = document.getElementById(svgId + "_search");               // get search button
        detailedTextField[svgId] = document.getElementById(svgId + "_details").firstChild;      // get details text box
        matchedTextField[svgId] = document.getElementById(svgId + "_matched");  // get matched text box 
        isSearching[svgId] = 0;        // not searching
        if(hlString.length != 0) search(hlString, svgId); // if needed -> highlight string with search function when creating flame graph 
    }
    init(null, '', 'mem'); 

    function jumpToPage(title) { // jump to formatted dev trace page
        var reg = new RegExp('(?<=w)([0-9]+)(?=\\s\\()');
        var pageNo = reg.exec(title);
        if(pageNo == null) {alert('target not found.'); return;}
        showDevTrace('' + pageNo[0] + '_html');
    }
    function s(node, id, svgId) { // mouse-over action
        detailedTextField[svgId].nodeValue = "" + getTitleText(node);  // show the text of current choosing node
        if(id.length != 0) window.parent.highlightFrame(id);
    }
    function c(id, svgId) { // mouse-out action
        detailedTextField[svgId].nodeValue = ' ';
        if(id.length != 0) window.parent.unhighlightFrame(id);
    }
    function getTitleText(e) { //return the title string of the e node
        var text = findChild(e, "title").firstChild.nodeValue;
        return (text);
    }
    function findChild(e, name, attr) { // looking for the child (of e) whose name is equal to "name"
        var children = e.childNodes;
        for(var i=0; i<children.length;i++) {
            if(children[i].tagName == name) { 
                if(attr == undefined) return children[i]; //return the child node
                else children[i].attributes[attr].value; // if attr is inputed, return the attr value of this child node
            }
        }
        return;
    }

table, th, td {
    background-color: #FFFFF1;
    padding: 7px;
    border: 1px solid black;
    border-collapse: collapse;
    overflow: visible;
    font-size: 12px;
    alig: left;
}
<style></body>
</html>

полный код слишком велик, поэтому я положил полный рабочий образец в скрипку .

I попытался поместить строки HTML / JS непосредственно в Azure страницу, но он не отображает этот код, отображая его как обычный текст, для простых HTML подобных таблиц и списков Azure работает, хотя.

Как вставить этот кусок в Azure? Я знаю, что iframe по-прежнему не поддерживается , но, может быть, есть другой способ?

PS Может быть, есть способ конвертировать html визуализированный граф в SVG, Azure визуализирует такой SVG правильно?

...