.. _jsonlytreantrst: ========= treant-js ========= .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`PDF `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/2016/pydata/jsonly_treant.ipynb|*` `treant-js `__ is a javascript library to plot diagram and trees. The goal is to wrap it as a library for python. `documentation `__ `source `__ `tutorial `__ `gallery `__ .. code:: ipython3 from jyquickhelper import add_notebook_menu add_notebook_menu() .. contents:: :local: Javacript in the notebook ------------------------- Let’s take one of the example and look at the source: `tennis draw `__. I took the source of the example and I changed relative to absolute paths. There are two parts: - HTML: defines styles, references external script, new HTML and section div - Javascript: defines a tree structure as Json and calls *treant-js* to convert it into SVG. .. code:: ipython3 %%html
.. raw:: html
.. code:: javascript %%javascript // source: // http://www.atpworldtour.com/Share/Event-Draws.aspx?EventId=410&Year=2013 var tree_structure = { chart: { container: "#OrganiseChart6", levelSeparation: 20, siblingSeparation: 15, subTeeSeparation: 15, rootOrientation: "EAST", node: { HTMLclass: "tennis-draw", drawLineThrough: true }, connectors: { type: "straight", style: { "stroke-width": 2, "stroke": "#ccc" } } }, nodeStructure: { text: { name: {val: "Djokovic, Novak", href: "http://www.atpworldtour.com/Tennis/Players/Top-Players/Novak-Djokovic.aspx"} }, HTMLclass: "winner", children: [ { text: { name: "Djokovic, Novak", desc: "4-6, 6-2, 6-2" }, children: [ { text: { name: "Djokovic, Novak", desc: "4-6, 6-1, 6-4" }, children: [ { text: { name: "Djokovic, Novak", desc: "4-6, 6-1, 6-4" }, children: [ { text: { name: "Djokovic, Novak", title: 1 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/srb.jpg", HTMLclass: "first-draw", }, { text: { name: "Bye", title: 2 }, HTMLclass: "first-draw bye" } ] }, { text: { name: "Youzhny, Mikhail", desc: "6-4, 6-0" }, children: [ { text: { name: "Youzhny, Mikhail", title: 3 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/rus.jpg", HTMLclass: "first-draw" }, { text: { name: "Gimeno-Traver, Daniel", title: 4 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/esp.jpg", HTMLclass: "first-draw" } ] } ] }, { text: { name: "Monaco, Juan", desc: "6-0, 3-6, 6-3" }, children: [ { text: { name: "Gulbis, Ernests", desc: "4-6, 6-2, 6-3" }, children: [ { text: { name: "Gulbis, Ernests", title: 5 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/lat.jpg", HTMLclass: "first-draw" }, { text: { name: "Isner, John", title: 6 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/usa.jpg", HTMLclass: "first-draw" } ] }, { text: { name: "Monaco, Juan", desc: "6-4, 6-0" }, children: [ { text: { name: "Klizan, Martin", title: 7 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/slo.jpg", HTMLclass: "first-draw" }, { text: { name: "Monaco, Juan", title: 8 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/arg.jpg", HTMLclass: "first-draw" } ] } ] } ] }, { text: { name: "Nieminen, Jarkko", desc: "6-3, 1-6, 7-6(3)" }, children: [ { text: { name: "Nieminen, Jarkko", desc: "4-6, 6-1, 6-4" }, children: [ { text: { name: "Raonic, Milos", desc: "6-1, 6-4" }, children: [ { text: { name: "Raonic, Milos", title: 9 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/can.jpg", HTMLclass: "first-draw" }, { text: { name: "Benneteau, Julien", title: 10 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/fra.jpg", HTMLclass: "first-draw" } ] }, { text: { name: "Nieminen, Jarkko", desc: "6-1, 6-2" }, children: [ { text: { name: "Nieminen, Jarkko", title: 11 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/fin.jpg", HTMLclass: "first-draw" }, { text: { name: "Troicki, Viktor", title: 12 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/srb.jpg", HTMLclass: "first-draw" } ] } ] }, { text: { name: "Del Potro, Juan Martin", desc: "6-2, 6-4" }, children: [ { text: { name: "Dolgopolov, Alexandr", desc: "4-6, 6-2, 6-3" }, children: [ { text: { name: "Dolgopolov, Alexandr", title: 13 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/ukr.jpg", HTMLclass: "first-draw" }, { text: { name: "Tomic, Bernard", title: 14 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/aus.jpg", HTMLclass: "first-draw" } ] }, { text: { name: "Del Potro, Juan Martin", desc: "6-4, 6-0" }, children: [ { text: { name: "Bye", title: 15 }, HTMLclass: "first-draw bye" }, { text: { name: "Del Potro, Juan Martin", title: 16 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/arg.jpg", HTMLclass: "first-draw" } ] } ] } ] } ] } }; new Treant( tree_structure ); .. parsed-literal:: Wrap treant-js into a Python library ------------------------------------ We would to produce a function with the following signature: .. code:: ipython3 def display_treant(json, css): pass First issue: the javascript is hosted on a website which means the notebook will not work offline unless we import the javascript at a specific location. See `Jupyter notebook extensions `__ to see where to place them. .. code:: ipython3 css = """ .chart { height: 600px; width: 900px; margin: 5px; margin: 15px auto; border: 3px solid #DDD; border-radius: 3px; } .tennis-draw { font-size: 10px; width: 100px; } .tennis-draw.winner { height: 38px; } .tennis-draw.winner:hover { background: url('http://fperucic.github.io/treant-js/examples/tennis-draw/trophy.png') right 0 no-repeat; } .tennis-draw.winner .node-name { padding-left: 10px; margin-top: 1px; display: block; } .tennis-draw .node-name { padding: 2px; white-space: pre; color: #00AFF0; } .tennis-draw .node-desc { padding: 2px; color: #999; } .tennis-draw.first-draw .node-title, .tennis-draw.first-draw .node-name, .tennis-draw.first-draw img { position: absolute; top: -8px; } .tennis-draw.first-draw:hover img { width: 20px; top: -12px; } .tennis-draw.first-draw { width: 165px; height: 20px; } .tennis-draw.first-draw img { margin: 3px 4px 0 0; left: 25px; } .tennis-draw.first-draw .node-title { margin-top: 3px; } .tennis-draw.first-draw .node-name { width: 113px; padding-left: 50px; } .tennis-draw.first-draw.bye .node-name { color: #999; } """ classname = "chart" # this part should be part of a nice API (to avoid trick like this __DIVID__) json_tree = """{ container: "#__DIVID__", levelSeparation: 20, siblingSeparation: 15, subTeeSeparation: 15, rootOrientation: "EAST", node: { HTMLclass: "tennis-draw", drawLineThrough: true }, connectors: { type: "straight", style: { "stroke-width": 2, "stroke": "#ccc" } } }""" # there should a nice API to define that json_data = """{ text: { name: {val: "Djokovic, Novak", href: "http://www.atpworldtour.com/Tennis/Players/Top-Players/Novak-Djokovic.aspx"} }, HTMLclass: "winner", children: [ { text: { name: "Djokovic, Novak", desc: "4-6, 6-2, 6-2" }, children: [ { text: { name: "Djokovic, Novak", desc: "4-6, 6-1, 6-4" }, children: [ { text: { name: "Djokovic, Novak", desc: "4-6, 6-1, 6-4" }, children: [ { text: { name: "Djokovic, Novak", title: 1 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/srb.jpg", HTMLclass: "first-draw", }, { text: { name: "Bye", title: 2 }, HTMLclass: "first-draw bye" } ] }, { text: { name: "Youzhny, Mikhail", desc: "6-4, 6-0" }, children: [ { text: { name: "Youzhny, Mikhail", title: 3 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/rus.jpg", HTMLclass: "first-draw" }, { text: { name: "Gimeno-Traver, Daniel", title: 4 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/esp.jpg", HTMLclass: "first-draw" } ] } ] }, { text: { name: "Monaco, Juan", desc: "6-0, 3-6, 6-3" }, children: [ { text: { name: "Gulbis, Ernests", desc: "4-6, 6-2, 6-3" }, children: [ { text: { name: "Gulbis, Ernests", title: 5 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/lat.jpg", HTMLclass: "first-draw" }, { text: { name: "Isner, John", title: 6 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/usa.jpg", HTMLclass: "first-draw" } ] }, { text: { name: "Monaco, Juan", desc: "6-4, 6-0" }, children: [ { text: { name: "Klizan, Martin", title: 7 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/slo.jpg", HTMLclass: "first-draw" }, { text: { name: "Monaco, Juan", title: 8 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/arg.jpg", HTMLclass: "first-draw" } ] } ] } ] }, { text: { name: "Nieminen, Jarkko", desc: "6-3, 1-6, 7-6(3)" }, children: [ { text: { name: "Nieminen, Jarkko", desc: "4-6, 6-1, 6-4" }, children: [ { text: { name: "Raonic, Milos", desc: "6-1, 6-4" }, children: [ { text: { name: "Raonic, Milos", title: 9 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/can.jpg", HTMLclass: "first-draw" }, { text: { name: "Benneteau, Julien", title: 10 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/fra.jpg", HTMLclass: "first-draw" } ] }, { text: { name: "Nieminen, Jarkko", desc: "6-1, 6-2" }, children: [ { text: { name: "Nieminen, Jarkko", title: 11 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/fin.jpg", HTMLclass: "first-draw" }, { text: { name: "Troicki, Viktor", title: 12 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/srb.jpg", HTMLclass: "first-draw" } ] } ] }, { text: { name: "Del Potro, Juan Martin", desc: "6-2, 6-4" }, children: [ { text: { name: "Dolgopolov, Alexandr", desc: "4-6, 6-2, 6-3" }, children: [ { text: { name: "Dolgopolov, Alexandr", title: 13 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/ukr.jpg", HTMLclass: "first-draw" }, { text: { name: "Tomic, Bernard", title: 14 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/aus.jpg", HTMLclass: "first-draw" } ] }, { text: { name: "Del Potro, Juan Martin", desc: "6-4, 6-0" }, children: [ { text: { name: "Bye", title: 15 }, HTMLclass: "first-draw bye" }, { text: { name: "Del Potro, Juan Martin", title: 16 }, image: "http://fperucic.github.io/treant-js/examples/tennis-draw/flags/arg.jpg", HTMLclass: "first-draw" } ] } ] } ] } ] }""" .. code:: ipython3 from jupytalk.talk_examples.treant_wrapper import display_treant from IPython.core.display import display display(display_treant(json_tree, json_data, css, classname)) .. raw:: html
What’s next? ------------ - Add local support - Make the graph stick when the notebook is display again (reload dependencies) - Change parameter ``json_tree`` for a dictionary with options - Create an API to create the data in Python and not in Json.