Refactor Graph to avoid cross-platform issues (#100)
Refactor Graph to avoid cross-platform issues (#100)

* Refactor Graph to avoid cross-platform issues

This uses

- `tempfile.TemporaryDirectory()` to handle cleaning up temporary files for the images. This isn't available in Python 2.7 but a simple backport is included (the standard-library version goes a little further in cleaning up still, should not be needed here).
- `tempfile.mkstemp()` to generate image filenames, those are guaranteed to be unique without needing to generate filenames based on the current timestamp.
- I cleaned up the code to be Flake-8 clean and better factored.

* Add missing bracket

Last-second typo introduced without looking at the linter, now corrected.

* Pass in attributes directly

* Only generate a filename

Using mkstemp won't work on Windows, where the file permissions are locked down
such that nothing else can write to it. All we need is a unique filename, not
a file created for us.

The node id is unique for a given tree, so just use that; because we use a
unique temporary directory per tree, there is no need for further complication
here.

* Remove now-unused import

* Fix edge labels

- Use xlabel instead of label, because orthogonal edges don't support the
  latter.
- Fix label whitespace; we want a bit of space on either side to control
  label-from-edge distance, but not whitespace within the parentheses.
  The newline ensures that labels above horizontal edges are still properly
  spaced.

* Clean up table settings

- consistent use of hex RGB (compact); the rgba() color converted by blending
  with white (`89.25 + .65 * component`)
- header height or line color are not needed
- use `attribute_property` when only one property is set; e.g.
  `"fill": {"color": "..."}` becomes `"fill_color": "..."`.
- no need to multiply per-cell or per-column settings if they are just repeated
- the default font size appears to be 12, so this can be dropped.

* Move most of the plotly config into globals

* Figure config: Further cut back on redundancy.

* A bit more padding still.

This should probably be converted to a head label with `labeldistance` and `labelangle` instead.

* Update graph.py

Rambatino/CHAID