Related
I try this code:
assert 1=2, "<table>....</table>"
table not showing in details, but strings in the details
how to show html tag with assert error message
i assert two file with difflib and show the message with htmlcontent
self = <test_assert.TestAssert object at 0x00000178F8534748>
def test_assert_match(self):
# with open('c1.json', 'w') as f1:
# json.dump(content1,f1, indent =4, sort_keys = True, separators = (',',':'))
content1 = self.readfile(os.path.join(curr,'1.json'))
content2 = self.readfile(os.path.join(curr,'2.json'))
> MyAssert.assertMatch(content1, content2, True)
Testcases\test_assert.py:34:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
expect = ['{', ' "a": "123"', '}'], actual = ['{', ' "a": "123",', ' "b": "22"', '}'], isHtml = True
#staticmethod
def assertMatch(expect, actual, isHtml = False):
msg = ''
if isHtml:
d = difflib.HtmlDiff()
msg = d.make_file(expect,actual)
with open('diff.html','w') as f:
f.write(msg)
else:
d = difflib.Differ()
diff = d.compare(expect,actual)
msg = "\n".join(list(diff))
> assert expect == actual, msg
E AssertionError:
E <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
E "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
E
E <html>
E
E <head>
E <meta http-equiv="Content-Type"
E content="text/html; charset=utf-8" />
E <title></title>
E <style type="text/css">
E table.diff {font-family:Courier; border:medium;}
E .diff_header {background-color:#e0e0e0}
E td.diff_header {text-align:right}
E .diff_next {background-color:#c0c0c0}
E .diff_add {background-color:#aaffaa}
E .diff_chg {background-color:#ffff77}
E .diff_sub {background-color:#ffaaaa}
E </style>
E </head>
E
E <body>
E
E <table class="diff" id="difflib_chg_to0__top"
E cellspacing="0" cellpadding="0" rules="groups" >
E <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
E <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup>
E
E <tbody>
E <tr><td class="diff_next" id="difflib_chg_to0__0">f</td><td class="diff_header" id="from0_1">1</td><td nowrap="nowrap">{</td><td class="diff_next">f</td><td class="diff_header" id="to0_1">1</td><td nowrap="nowrap">{</td></tr>
E <tr><td class="diff_next">t</td><td class="diff_header" id="from0_2">2</td><td nowrap="nowrap"> "a": "123"</td><td class="diff_next">t</td><td class="diff_header" id="to0_2">2</td><td nowrap="nowrap"> "a": "123"<span class="diff_add">,</span></td></tr>
E <tr><td class="diff_next"></td><td class="diff_header"></td><td nowrap="nowrap"></td><td class="diff_next"></td><td class="diff_header" id="to0_3">3</td><td nowrap="nowrap"><span class="diff_add"> "b": "22"</span></td></tr>
E <tr><td class="diff_next"></td><td class="diff_header" id="from0_3">3</td><td nowrap="nowrap">}</td><td class="diff_next"></td><td class="diff_header" id="to0_4">4</td><td nowrap="nowrap">}</td></tr>
E </tbody>
E </table>
E <table class="diff" summary="Legends">
E <tr> <th colspan="2"> Legends </th> </tr>
E <tr> <td> <table border="" summary="Colors">
E <tr><th> Colors </th> </tr>
E <tr><td class="diff_add"> Added </td></tr>
E <tr><td class="diff_chg">Changed</td> </tr>
E <tr><td class="diff_sub">Deleted</td> </tr>
E </table></td>
E <td> <table border="" summary="Links">
E <tr><th colspan="2"> Links </th> </tr>
E <tr><td>(f)irst change</td> </tr>
E <tr><td>(n)ext change</td> </tr>
E <tr><td>(t)op</td> </tr>
E </table></td> </tr>
E </table>
E </body>
E
E </html>
Testcases\myAssert.py:50: AssertionError
i want to show the html in the details not strings..
I am trying to display a graph with images and labels with GraphViz. I would like to display the label under the image (see labelloc="b" option on the graph) but somehow it doesn't not work. Label and image are overlapped.
Any idea what I am missing?
Below is the DOT code I am using, and the current result.
Thanks!
digraph {
graph [compound=true, labelloc="b"];
node [shape=box];
edge [dir=none];
Label1[label="Label1",image="images/Avatar1.png"];
Label2[label="Label2",image="images/Avatar2.png"];
Label3[label="Label3",image="images/Avatar3.png"];
{
rank=same;
Label1 -> h0 -> Label2;
h0[shape=circle,label="",height=0.01,width=0.01];
}
{
h0_0;
h0_0[shape=circle,label="",height=0.01,width=0.01];
}
h0 -> h0_0;
h0_0 -> Label3;
}
UPD: You need just to add an imagepos attribute to your solution with height:
digraph {
graph [compound=true, labelloc="b"];
node [shape=box];
edge [dir=none];
Label1[
label="Label1"
height="2.1"
imagepos="tc"
labelloc="b"
image="images/Avatar1.png"
];
Label2[
label="Label2"
height="2.1"
imagepos="tc"
labelloc="b"
image="images/Avatar2.png"
];
Label3[
label="Label3"
height="2.1"
imagepos="tc"
labelloc="b"
image="images/Avatar3.png"
];
{
rank=same;
Label1 -> h0 -> Label2;
h0[shape=circle,label="",height=0.01,width=0.01];
}
{
h0_0;
h0_0[shape=circle,label="",height=0.01,width=0.01];
}
h0 -> h0_0;
h0_0 -> Label3;
}
Result:
Or you may also use HTML-like labels, and specifically, tables:
digraph {
graph [compound=true, labelloc="b"];
node [shape=box];
edge [dir=none];
Label1 [
shape=plain
label=<
<table cellspacing="0" border="0" cellborder="1">
<tr><td><img src="images/Avatar1.png" /></td></tr>
<tr><td>Label1</td></tr>
</table>
>
];
Label2 [
shape=plain
label=<
<table cellspacing="0" border="0" cellborder="1">
<tr><td><img src="images/Avatar2.png" /></td></tr>
<tr><td>Label2</td></tr>
</table>
>
];
Label3 [
shape=plain
label=<
<table cellspacing="0" border="0" cellborder="1">
<tr><td><img src="images/Avatar3.png" /></td></tr>
<tr><td>Label3</td></tr>
</table>
>
];
{
rank=same;
Label1 -> h0 -> Label2;
h0[shape=circle,label="",height=0.01,width=0.01];
}
{
h0_0;
h0_0[shape=circle,label="",height=0.01,width=0.01];
}
h0 -> h0_0;
h0_0 -> Label3;
}
The code is a bit more complex (at first glance), but as a bonus you get more flexible control over the borders.
Result:
By specifying a "height" (warning, those are "inches") for the nodes, I get the "labelloc" to work and I can thus move the label out of the picture. I would prefer if the box didn't have that white place at the top, but it's better than before.
I'm testing a plugin for dataTables called SearchPane, it works fine, but when i filter the table using the pane, the values keep stuck, not reflecting the values from the filtered table.
What i need is: after click on some value from the searchPane filter, the filter update values based on values of (filtered) updated table.
The documentation says something about it but not explain how apply it.
searchPane Documentation
The documentation have this information:
API - When the data in the table is updated, you'll want the search
panes to reflect this updated data - which can be done with the
searchPanes.rebuild() method - e.g.:
var table = $('#example').DataTable( {
searchPane: true
} );
table.row.add( ... ).draw();
table.searchPanes.rebuild();
but i don't know how to apply this in a working example.
my code:
$('#example').DataTable( {
searchPane: true
} )
<link href="https://cdn.datatables.net/1.10.11/css/jquery.dataTables.min.css" rel="stylesheet"/>
<link href="https://cdn.datatables.net/plug-ins/preview/searchPane/dataTables.searchPane.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/plug-ins/preview/searchPane/dataTables.searchPane.min.js"></script>
<div class="container">
<table cellpadding="0" cellspacing="0" border="0" class="dataTable" id="example">
<thead>
<tr>
<th>Rendering engine</th>
<th>Browser</th>
<th>Platform(s)</th>
<th>Engine version</th>
<th>CSS grade</th>
</tr>
</thead>
<tbody>
<tr>
<td>Trident</td>
<td>Internet
Explorer 4.0</td>
<td>Win 95+</td>
<td> 4</td>
<td>X</td>
</tr>
<tr>
<td>Trident</td>
<td>Internet
Explorer 5.0</td>
<td>Win 95+</td>
<td>5</td>
<td>C</td>
</tr>
<tr>
<td>Trident</td>
<td>Internet
Explorer 5.5</td>
<td>Win 95+</td>
<td>5.5</td>
<td>A</td>
</tr>
<tr>
<td>Trident</td>
<td>Internet
Explorer 6</td>
<td>Win 98+</td>
<td>6</td>
<td>A</td>
</tr>
<tr>
<td>Trident</td>
<td>Internet Explorer 7</td>
<td>Win XP SP2+</td>
<td>7</td>
<td>A</td>
</tr>
<tr>
<td>Trident</td>
<td>AOL browser (AOL desktop)</td>
<td>Win XP</td>
<td>6</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Firefox 1.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Firefox 1.5</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Firefox 2.0</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Firefox 3.0</td>
<td>Win 2k+ / OSX.3+</td>
<td>1.9</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Camino 1.0</td>
<td>OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Camino 1.5</td>
<td>OSX.3+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Netscape 7.2</td>
<td>Win 95+ / Mac OS 8.6-9.2</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Netscape Browser 8</td>
<td>Win 98SE+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Netscape Navigator 9</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.0</td>
<td>Win 95+ / OSX.1+</td>
<td>1</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.1</td>
<td>Win 95+ / OSX.1+</td>
<td>1.1</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.2</td>
<td>Win 95+ / OSX.1+</td>
<td>1.2</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.3</td>
<td>Win 95+ / OSX.1+</td>
<td>1.3</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.4</td>
<td>Win 95+ / OSX.1+</td>
<td>1.4</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.5</td>
<td>Win 95+ / OSX.1+</td>
<td>1.5</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.6</td>
<td>Win 95+ / OSX.1+</td>
<td>1.6</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.7</td>
<td>Win 98+ / OSX.1+</td>
<td>1.7</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Mozilla 1.8</td>
<td>Win 98+ / OSX.1+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Seamonkey 1.1</td>
<td>Win 98+ / OSX.2+</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Gecko</td>
<td>Epiphany 2.20</td>
<td>Gnome</td>
<td>1.8</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>Safari 1.2</td>
<td>OSX.3</td>
<td>125.5</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>Safari 1.3</td>
<td>OSX.3</td>
<td>312.8</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>Safari 2.0</td>
<td>OSX.4+</td>
<td>419.3</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>Safari 3.0</td>
<td>OSX.4+</td>
<td>522.1</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>OmniWeb 5.5</td>
<td>OSX.4+</td>
<td>420</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>iPod Touch / iPhone</td>
<td>iPod</td>
<td>420.1</td>
<td>A</td>
</tr>
<tr>
<td>Webkit</td>
<td>S60</td>
<td>S60</td>
<td>413</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 7.0</td>
<td>Win 95+ / OSX.1+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 7.5</td>
<td>Win 95+ / OSX.2+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 8.0</td>
<td>Win 95+ / OSX.2+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 8.5</td>
<td>Win 95+ / OSX.2+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 9.0</td>
<td>Win 95+ / OSX.3+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 9.2</td>
<td>Win 88+ / OSX.3+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera 9.5</td>
<td>Win 88+ / OSX.3+</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Opera for Wii</td>
<td>Wii</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Nokia N800</td>
<td>N800</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Presto</td>
<td>Nintendo DS browser</td>
<td>Nintendo DS</td>
<td>8.5</td>
<td>C/A<sup>1</sup></td>
</tr>
<tr>
<td>KHTML</td>
<td>Konqureror 3.1</td>
<td>KDE 3.1</td>
<td>3.1</td>
<td>C</td>
</tr>
<tr>
<td>KHTML</td>
<td>Konqureror 3.3</td>
<td>KDE 3.3</td>
<td>3.3</td>
<td>A</td>
</tr>
<tr>
<td>KHTML</td>
<td>Konqureror 3.5</td>
<td>KDE 3.5</td>
<td>3.5</td>
<td>A</td>
</tr>
<tr>
<td>Tasman</td>
<td>Internet Explorer 4.5</td>
<td>Mac OS 8-9</td>
<td>-</td>
<td>X</td>
</tr>
<tr>
<td>Tasman</td>
<td>Internet Explorer 5.1</td>
<td>Mac OS 7.6-9</td>
<td>1</td>
<td>C</td>
</tr>
<tr>
<td>Tasman</td>
<td>Internet Explorer 5.2</td>
<td>Mac OS 8-X</td>
<td>1</td>
<td>C</td>
</tr>
<tr>
<td>Misc</td>
<td>NetFront 3.1</td>
<td>Embedded devices</td>
<td>-</td>
<td>C</td>
</tr>
<tr>
<td>Misc</td>
<td>NetFront 3.4</td>
<td>Embedded devices</td>
<td>-</td>
<td>A</td>
</tr>
<tr>
<td>Misc</td>
<td>Dillo 0.8</td>
<td>Embedded devices</td>
<td>-</td>
<td>X</td>
</tr>
<tr>
<td>Misc</td>
<td>Links</td>
<td>Text only</td>
<td>-</td>
<td>X</td>
</tr>
<tr>
<td>Misc</td>
<td>Lynx</td>
<td>Text only</td>
<td>-</td>
<td>X</td>
</tr>
<tr>
<td>Misc</td>
<td>IE Mobile</td>
<td>Windows Mobile 6</td>
<td>-</td>
<td>C</td>
</tr>
<tr>
<td>Misc</td>
<td>PSP browser</td>
<td>PSP</td>
<td>-</td>
<td>C</td>
</tr>
<tr>
<td>Other browsers</td>
<td>All others</td>
<td>-</td>
<td>-</td>
<td>U</td>
</tr>
</tbody>
</table>
</div>
table.row.add( ... ).draw();
table.searchPanes.rebuild();
remove above lines.
if u wanna use this with server side edit the "dataTables.searchPane.min.js" file as below.
var $jscomp = $jscomp || {}; $jscomp.scope = {}; $jscomp.findInternal = function (a, e, c) { a instanceof String && (a = String(a)); for (var g = a.length, d = 0; d < g; d++) { var l = a[d]; if (e.call(c, l, d, a)) return { i: d, v: l } } return { i: -1, v: void 0 } }; $jscomp.ASSUME_ES5 = !1; $jscomp.ASSUME_NO_NATIVE_MAP = !1; $jscomp.ASSUME_NO_NATIVE_SET = !1; $jscomp.defineProperty = $jscomp.ASSUME_ES5 || "function" == typeof Object.defineProperties ? Object.defineProperty : function (a, e, c) { a != Array.prototype && a != Object.prototype && (a[e] = c.value) };
$jscomp.getGlobal = function (a) { return "undefined" != typeof window && window === a ? a : "undefined" != typeof global && null != global ? global : a }; $jscomp.global = $jscomp.getGlobal(this); $jscomp.polyfill = function (a, e, c, g) { if (e) { c = $jscomp.global; a = a.split("."); for (g = 0; g < a.length - 1; g++) { var d = a[g]; d in c || (c[d] = {}); c = c[d] } a = a[a.length - 1]; g = c[a]; e = e(g); e != g && null != e && $jscomp.defineProperty(c, a, { configurable: !0, writable: !0, value: e }) } };
$jscomp.polyfill("Array.prototype.find", function (a) { return a ? a : function (a, c) { return $jscomp.findInternal(this, a, c).v } }, "es6-impl", "es3");
(function (a) { "function" === typeof define && define.amd ? define(["jquery", "datatables.net"], function (e) { return a(e, window, document) }) : "object" === typeof exports ? module.exports = function (e, c) { e || (e = window); c && c.fn.dataTable || (c = require("datatables.net")(e, c).$); return a(c, e, e.document) } : a(jQuery, window, document) })(function (a, e, c, g) {
function d(b, h) {
var f = this; b = new l.Api(b); this.classes = a.extend(!0, {}, d.classes); this.dom = { container: a("<div/>").addClass(this.classes.container) }; this.c = a.extend(!0, {}, d.defaults,
h); this.s = { dt: b }; b.settings()[0].searchPane = this; b.columns(this.c.columns).eq(0).each(function (a) { f._pane(a) }); a(this.dom.container).on("click", "li", function () { f._toggle(this) }).on("click", "button." + this.classes.clear, function () { f._clear(a(this).closest("div." + f.classes.pane.container)) }); this._attach()
} var l = a.fn.dataTable; a.extend(d.prototype, {
rebuild: function () { var a = this; this.s.dt.columns(this.c.columns).eq(0).each(function (b) { a._pane(b) }) }, _attach: function () {
var b = this.c.container, b = "function" ===
typeof b ? b(this.s.dt) : b; "prepend" === this.c.insert ? a(this.dom.container).prependTo(b) : a(this.dom.container).appendTo(b)
}, _binData: function (a) { var b = {}; a.each(function (a) { a && (b[a] ? b[a]++ : b[a] = 1) }); return b }, _clear: function (a) { var b = this.classes, f = b.item.selected; a.find("li." + f).removeClass(f); a.removeClass(b.pane.active); this.s.dt.column(a.data("column")).search("").draw() }, _pane: function (b) {
var h = this.classes, f = h.item, h = h.pane, c = this.s.dt.column(b), e = a("<ul/>"), d = this._binData(c.data().flatten());
if (!(this._variance(d) < this.c.threshold)) {
for (var g = c.search(), g = g ? g.substr(1, g.length - 2).split("|") : [], m = c.data().unique().sort().toArray(), k = 0, l = m.length; k < l; k++)if (m[k]) { var n = a("<li/>").html('<span class="' + f.label + '">' + m[k] + "</span>").data("filter", m[k]).append(a("<span/>").addClass(f.count).html(d[m[k]])); if (g.length) { var p = m[k].replace ? a.fn.dataTable.util.escapeRegex(m[k]) : m[k]; -1 !== a.inArray(p, g) && n.addClass(f.selected) } e.append(n) } f = a("<div/>").data("column", b).addClass(h.container).addClass(g.length ?
h.active : "").append(a('<button type="button">×</button>').addClass(this.classes.clear)).append(a("<div/>").addClass(h.title).html(a(c.header()).text())).append(a("<div/>").addClass(h.scroller).append(e)); h = this.dom.container; c = h.children().map(function () { if (a(this).data("column") == b) return this }); c.length ? c.replaceWith(f) : a(h).append(f)
}
}, _toggle: function (b) {
var c = this.classes, f = c.item.selected, e = this.s.dt; b = a(b); var d = b.closest("div." + c.pane.container); b.toggleClass(f, !b.hasClass(f)); b = d.find("li." +
f); 0 === b.length ? (d.removeClass(c.pane.active), e.column(d.data("column")).search("").draw()) : (d.addClass(c.pane.active), e.column(d.data("column")).search(a.map(b, function (b) { b = a(b).data("filter").toString(); return a.fn.dataTable.util.escapeRegex(b) }).join("|"), !0, !1).draw())
}, _variance: function (b) { b = a.map(b, function (a, b) { return a }); for (var c = b.length, f = 0, d = 0, e = c; d < e; d++)f += b[d]; for (var f = f / c, g = 0, d = 0, e = c; d < e; d++)g += Math.pow(f - b[d], 2); return g / (c - 1) }
}); d.classes = {
container: "dt-searchPanes", clear: "clear",
pane: { active: "filtering", container: "pane", title: "title", scroller: "scroller" }, item: { selected: "selected", label: "label", count: "count" }
}; d.defaults = { container: function (a) { return a.table().container() }, columns: g, insert: "prepend", threshold: .5 }; d.version = "0.0.1"; a.fn.dataTable.SearchPanes = d; a.fn.DataTable.SearchPanes = d; l.Api.register("searchPanes.rebuild()", function () { return this.iterator("table", function (a) { a.searchPane && a.searchPane.rebuild() }) }); a(c).on("init.dt", function (b, c, e) {
"dt" === b.namespace && (b =
c.oInit.searchPane, e = l.defaults.searchPane, b || e) && (e = a.extend({}, b, e), !1 !== b && new d(c, e))
})
});
I am using Graphviz to create a graph with nodes that are HTML-like labels. My dot file:
digraph 0 {
center = true
charset = "UTF-8"
overlap = false
splines = true
landscape = false
id = "0"
label = "Graph Example"
labelloc = "t"
node [shape = none width = 0 height = 0 margin = 0 fontcolor = blue ]
0 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "0" >Node 0</TD>
</TR>
<TR>
<TD CELLSPACING = "0" CELLPADDING = "0" >
<TABLE BORDER = "0" CELLSPACING = "1" CELLBORDER = "0" CELLPADDING = "0" >
<TR>
<TD PORT = "4"> </TD>
<TD PORT = "1"> </TD>
<TD PORT = "2"> </TD>
<TD PORT = "3"> </TD>
<TD PORT = "6"> </TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE> > ]
4 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "4" >Node 1</TD>
</TR>
<TR>
<TD CELLSPACING = "0" CELLPADDING = "0" >
<TABLE BORDER = "0" CELLSPACING = "1" CELLBORDER = "0" CELLPADDING = "0" >
<TR>
<TD PORT = "6"> </TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE> > ]
6 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "6" >Node 6</TD>
</TR>
</TABLE> > ]
1 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "1">Node 1</TD>
</TR>
<TR>
<TD CELLSPACING = "0" CELLPADDING = "0" >
<TABLE BORDER = "0" CELLSPACING = "1" CELLBORDER = "0" CELLPADDING = "0" >
<TR>
<TD PORT = "4"> </TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE> > ]
2 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "2">Node 2</TD>
</TR>
<TR>
<TD CELLSPACING = "0" CELLPADDING = "0" >
<TABLE BORDER = "0" CELLSPACING = "1" CELLBORDER = "0" CELLPADDING = "0" >
<TR>
<TD PORT = "4"> </TD>
<TD PORT = "5"> </TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE> > ]
5 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "5" >Node 5</TD>
</TR>
</TABLE> > ]
3 [ label = <
<TABLE BORDER = "0" CELLBORDER = "1" CELLSPACING = "0" CELLPADDING = "5" ALIGN = "CENTER" BGCOLOR = "white" COLOR = "black" >
<TR>
<TD PORT = "3" >Node 3</TD>
</TR>
<TR>
<TD CELLSPACING = "0" CELLPADDING = "0" >
<TABLE BORDER = "0" CELLSPACING = "1" CELLBORDER = "0" CELLPADDING = "0" >
<TR>
<TD PORT = "5"> </TD>
</TR>
</TABLE>
</TD>
</TR>
</TABLE> > ]
1:4:s -> 4:4:n
2:4:s -> 4:4:n
2:5:s -> 5:5:n
0:1:s -> 1:1:n
0:2:s -> 2:2:n
0:3:s -> 3:3:n
0:6:s -> 6:6:n
4:6:s -> 6:6:n
3:5:s -> 5:5:n
0:4:s -> 4:4:n
edge [color = red constraint = false ]
1:1 -> 4:4
1:1 -> 3:3
}
And I am using ports to define where on the node I want to connect with other nodes. Attached the image generated by dot.
I would like to have the edges drawn as polylines instead of curved arcs. I tried to modify the splines attribute for the graph but it does not work, in fact from the graphviz documentation I found this: "The value ortho specifies edges should be routed as polylines of axis-aligned segments. Currently, the routing does not handle ports or, in dot, edge labels."
Can you help in finding a solution to have polylines (or better looking edges) using ports?
Thanks.
simply change:
splines = true
to
splines = polyline
did the trick for me
result
I'm working on creating a datatable that has a drill down (row details) sub datatable as per the requirement. I was able to create the sub datatable when using drill down (row details) approach, but finding it hard to expand all of these rows that have drill down associated while loading the table. Here is the code I have and it works and expands all drill down rows on the current paginated table., but when clicking on the next pagination (number or page), the rows shows as expand (you know you can see the 'minus' (close) icon image) but no sub datatable. As far as I understood, its because, when I'm trying to simulate a click on the 'img' attribute associated for a drill down row, its being applied successfully for the current rows in the current page, but for the rest, which are not in the dom, the script says that the sub datatable is undefined. Any ideas or suggestions around this would help me a lot..
Below is the code snippet -
Table HTML source code -
<table id="mastertable" class="table table-striped table-bordered table-hover dataTable" aria-describedby="sample-table-2_info">
<thead>
<tr role="row">
<!-- <th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Domain: activate to sort column ascending" style="width: 255px;"></th> -->
<th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Domain: activate to sort column ascending" style="width: 25%;">Project Name</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Price: activate to sort column ascending" style="width: 10%;">Status</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Clicks: activate to sort column ascending" style="width: 10%;">Start Date</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Clicks: activate to sort column ascending" style="width: 10%;">End Date</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Clicks: activate to sort column ascending" style="width: 10%;">FCS Date</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Clicks: activate to sort column ascending" style="width: 10%;">Project Phase</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" aria-label="Clicks: activate to sort column ascending" style="width: 15%;">Defects</th>
</tr>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
<tr>
<td class=" ">
<img src="/tester/theme/v_1_0/app-images/details_open.png" masterProject="master-ROORKELA"/>
ROORKELA <font color="black">(System Project)</font>
// THIS IS THE SUB DATATABLE HIDDEN IN DIV AND THE ID OF THE DIV IS STORED IN THE IMG ATTRIBUTE ABOVE UNDER THE 'masterProject' attribute - [masterProject="master-ROORKELA"]
<div class="hide" id="master-ROORKELA">
<table id="subProjects-table" class="table table-striped table-bordered table-hover subTable" aria-describedby="sample-table-2_info">
<thead>
<tr role="row">
<th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 255px;">Project Name</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 186px;">Status</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 203px;">Start Date</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 203px;">End Date</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 203px;">Targetted Date</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 203px;">Project Phase</th>
<th class="hidden-480 sorting" role="columnheader" tabindex="0" aria-controls="sample-table-2" rowspan="1" colspan="1" style="width: 203px;">Defects</th>
</tr>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
<tr>
<td class=" " style="width: 26%;text-align:center;vertical-align: middle;">
Sirish
</td>
<td class="hidden-480 " style="width: 10%;">
<span class="label label-sm label-warning">Minor Impact</span>
</td>
<td class=" " style="width: 10%;">Feb 12 2013</td>
<td class="hidden-480 " style="width: 10%;">Nov 12 2013</td>
<td class=" " style="width: 10%;">Jan 16 2014</td>
<td class=" " style="width: 10%;">EFT</td>
<td class=" " style="width: 15%;">
22 defects
</tr>
</tbody>
</table>
</div>
</td>
<td class="hidden-480 ">
<span class="label label-sm label-warning">Minor Impact</span>
</td>
<td class=" ">Feb 12 2013</td>
<td class="hidden-480 ">Nov 12 2013</td>
<td class=" ">Jan 16 2014</td>
<td class=" ">TESTING</td>
<td class=" ">22 defects
</tr>
</tbody>
</table>
Defining the initial table -
var oTable = $('#mastertable').dataTable( {
"aLengthMenu": [[5,10, 25, 50, 100 , -1], [5,10, 25, 50, 100, "All"]],
"iDisplayLength" : 10,
"aoColumnDefs": [
{"sWidth": "25%", "aTargets": [ 0 ] },
{"sWidth": "10%", "aTargets": [ 1 ] },
{"sWidth": "10%", "aTargets": [ 2 ] },
{"sWidth": "10%", "aTargets": [ 3 ] },
{"sWidth": "10%", "aTargets": [ 4 ] },
{"sWidth": "10%", "aTargets": [ 5 ] },
{"sWidth": "15%", "aTargets": [ 6 ] },
{"sClass": "align-left" , "aTargets": [ 0,1,4, 2,3,5,6] }
],
"sDom": '<"row"<"col-sm-4"l><"col-sm-6"f><"col-sm-1 saveas_div"T><"col-sm-1 filtering_div"C>r>t<"row"<"col-sm-6"i><"col-sm-6"p>>',
"oTableTools": {
"aButtons": [
{
"sExtends": 'csv',
"sButtonText":'Export as CSV',
"mColumns":"visible"
}
]
},
"aoColumns": [
{ "bSortable": true },
null, null, null,null, null,
{ "bSortable": true }
],
"bStateSave": true,
"fnStateSave": function (oSettings, oData) {
localStorage.setItem( 'DataTables_'+window.location.pathname, JSON.stringify(oData) );
},
"fnStateLoad": function (oSettings) {
return JSON.parse( localStorage.getItem('DataTables_'+window.location.pathname) );
}
});
Associating click events on the 'img' attributes in the table -
oTable.$('td').each( function () {
$(this).on('click','img', function () {
var nTr = $(this).parents('tr')[0];
if ( oTable.fnIsOpen(nTr) )
{
/* This row is already open - close it */
this.src = "${pageContext.request.contextPath}/theme/v_1_0/app-images/details_open.png";
oTable.fnClose( nTr );
}
else
{
/* Open this row */
this.src = "${pageContext.request.contextPath}/theme/v_1_0/app-images/details_close.png";
var masterProject = $(this).attr("masterProject");
var html = $("#"+masterProject).html();
console.log(html); // THIS IS WHERE I SEE AS UNDEFINED FOR HIDDEN TR ELEMENTS WHICH ARE HIDDEN DURING PAGINATION
oTable.fnOpen(nTr, html, 'details');
}
} );
$(this).find('img').trigger('click'); // THIS IS WHERE I"M SIMULATING CLICK EVENT TO EXPAND ALL ROWS WHILE LOADING PAGE BY DEFAULT.
});
I tried using the - fnDrawCallback method to simulate the click events, but its giving me weird results, meaning rows are expanded on alternate pages like 1,3,5 but on consecutive pages.
Sorry for this monologue, as am just trying to explain the detail of the problem.
Please pass on your valuable suggestions or solutions..
Many thanks,
Sirish.
So I added functionality on button to collapse all and expand all child rows. that will work with pagination, search and
<script>
function format ( d ) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<td>Full CallStack:</td>'+
'<td style="text-align:left;">'+d.call_stack+'</td>'+
'</tr>'+
'</table>';
}
$(document).ready(function() {
var isCollapse = 1;
var visited_cehck = 0;
var table = $('#example').DataTable( {
"aaData": $Json_data,
"aoColumns": [
{ "sTitle": "col1", "mData": "col1" },
{ "sTitle": "col2", "mData": "col2" },
{ "sTitle": "col3", "mData": "col3" },
{ "sTitle": "col4", "mData": "col4" },
{ "sTitle": "col5", "mData": "col5" },
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
}
]
} );
//This function gets the length of the row and collapse and
//expend all the rows depending on the current state of the row:
function collapse_exand_rows(){
var table_length = $('#example tbody tr').length;
for (var i = 0; i < table_length; i++) {
var tr = $('.details-control').parents('tr').eq(i);
var row = table.row( tr );
if(!tr.hasClass('visited_child') || visited_cehck != 1){
if ( isCollapse === 1 ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
}
}
}
//This event handles click for on each child row to show and hide rows.
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).parents('tr');
var row = table.row( tr );
visited_cehck = 1;
tr.addClass('visited_child');
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
//This event handles navigation bar below the report to show and hide all the visible rows
$('.dataTables_paginate').bind('click', '.details-control', function(event) {
if(visited_cehck === 1){
return false;
}
collapse_exand_rows();
});
//This event handles collapse expand button click to show and hide all the visible rows
$('#collapse_expand').on('click', function(event) {
visited_cehck = 0;
if(isCollapse === 1){
$('#collapse_expand').text('Collapse All');
isCollapse = 0;
}
else{
$('#collapse_expand').text('Expand All');
isCollapse = 1;
}
collapse_exand_rows();
});
//This event handles dropdown to show and hide all the visible rows
$('select').on('change', function (event) {
collapse_exand_rows();
});
$("thead > tr", '#example').click(function(event) {
collapse_exand_rows();
})
$(':input').change(function(event) {
collapse_exand_rows();
});
});
</script>
do something like this:
var table_length = $("#mastertable tr").length;
var paginate_button = $('.paginate_button');
for(var i = 0; i< table_length; i++){
var tr = $('#mastertable tbody td.details-control').eq(i).parents('tr');
var row = table.row(tr);
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
if you have pagination :
isCollapse === 0
paginate_button.on('click',function(){
table_length = $("#example tr").length;
if ( isCollapse === 1 ) {
for(var i = 0; i< table_length; i++){
var tr = $('#example tbody td.details-control').eq(i).parents('tr');
var row = table.row(tr);
row.child.hide();
tr.removeClass('shown');
}
}
else {
// Open this row
for(var i = 0; i< table_length; i++){
var tr = $('#example tbody td.details-control').eq(i).parents('tr');
var row = table.row(tr);
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
}
});