graphSith

master
Tancre 4 years ago
parent 96c9c122c2
commit 806d010525

@ -0,0 +1 @@
*.sql linguist-language=PLSQL

@ -0,0 +1,12 @@
.DS_Store
.idea
node_modules
api-reference.md
example-query.sql
js/temp.js
d3-force-apex-plugin-demo-app.sql
d3-force-apex-plugin-demo-app.zip
description-apex-plugin.com.html
description-sample-app.html
temp.txt
temp.html

@ -0,0 +1,16 @@
{
"tags": {
"allowUnknownTags": true
},
"plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"useLongnameInNav": false,
"showInheritedInNav": true
},
"markdown": {
"parser": "gfm",
"hardwrap": true
}
}

@ -0,0 +1,140 @@
/* global module */
module.exports = function(grunt) {
"use strict";
grunt.initConfig({
pkg: grunt.file.readJSON("apexplugin.json"),
currentYear: parseInt(grunt.template.today("yyyy")),
banner: '/**\n' +
' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
' * Copyright (c) 2015<%= currentYear > 2015 ? "-" + currentYear : "" %> <%= pkg.author.name %> - <%= pkg.license %> license\n' +
' */\n',
exampleGraph: '<button onclick="example.useDomParentWidth((example.useDomParentWidth()?false:true))">Toggle option useDomParentWidth</button>\n' +
'<div id="example"></div><!--the graph container-->\n' +
'<link href="./lib/d3-force-<%= pkg.version %>.css" rel="stylesheet" type="text/css">\n' +
'<script src="./lib/ResizeObserver-1.5.0.min.js"></script>\n' +
'<script src="./lib/d3-3.5.6.min.js"></script>\n' +
'<script src="./lib/d3-force-<%= pkg.version %>.min.js"></script>\n' +
'<script>\n' +
' window.onload = function (){\n' +
' window.example = netGobrechtsD3Force("example")\n' +
' .width(600)\n' +
' .height(400)\n' +
' .lassoMode(true)\n' +
' .wrapLabels(true)\n' +
' .debug(true) //also creates the "Customize Me" link\n' +
' .render(); //sample data is provided when called without data\n' +
' }\n' +
'</script>\n',
jshint: {
files: [
"Gruntfile.js",
"apexplugin.json",
"src/d3-force.js"
]
},
clean: ["docs", "dist/*.css", "dist/*.js"],
copy: {
dist1: {
src: "src/d3-force.js",
dest: "dist/d3-force-<%= pkg.version %>.js",
options: {
process: function(content, srcpath) {
return grunt.template.process("<%= banner %>") + "\n" +
content.replace(/x\.x\.x/g, grunt.template.process("<%= pkg.version %>"));
}
}
},
dist2: {
files: [{
src: "src/d3-force.css",
dest: "dist/d3-force-<%= pkg.version %>.css"
},
{
src: "src/example.html",
dest: "dist/example.html"
},
{
src: "src/LICENSE.txt",
dest: "LICENSE.txt"
}
],
options: {
process: function(content) {
return content
.replace(/x\.x\.x/g, grunt.template.process("<%= pkg.version %>"))
.replace(/{{CURRENT-YEAR}}/g, grunt.template.process("<%= currentYear %>"))
.replace(/{{EXAMPLE-GRAPH}}/g, grunt.template.process("<%= exampleGraph %>"));
}
}
},
docs1: {
files: [{
src: "docs/tutorial-1-getting-started.html",
dest: "docs/tutorial-1-getting-started.html"
}],
options: {
process: function(content, srcpath) {
return content.replace(/{{EXAMPLE-GRAPH}}/g, grunt.template.process("<%= exampleGraph %>"))
.replace(/{{EXAMPLE-GRAPH-CODE}}/g, grunt.template.process("<%= exampleGraph %>").replace(/</g, "&lt;"));
}
}
},
docs2: {
files: [{
src: "dist/lib/d3/d3-3.5.6.min.js",
dest: "docs/lib/d3-3.5.6.min.js"
},
{
src: "dist/lib/resize-observer-polyfill/ResizeObserver-1.5.0.min.js",
dest: "docs/lib/ResizeObserver-1.5.0.min.js"
},
{
src: "dist/d3-force-<%= pkg.version %>.css",
dest: "docs/lib/d3-force-<%= pkg.version %>.css"
},
{
src: "dist/d3-force-<%= pkg.version %>.min.js",
dest: "docs/lib/d3-force-<%= pkg.version %>.min.js"
}
]
}
},
uglify: {
options: {
banner: "<%= banner %>"
},
dist: {
src: "dist/d3-force-<%= pkg.version %>.js",
dest: "dist/d3-force-<%= pkg.version %>.min.js"
},
},
jsdoc: {
docs: {
src: ["README.md", "src/*.js"],
options: {
destination: "docs",
tutorials: "src/tutorials",
template: "node_modules/minami",
configure: ".jsdoc.json"
}
}
},
watch: {
files: [
"Gruntfile.js",
"apexplugin.json",
"src/**"
],
tasks: ["default"]
}
});
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-notify");
grunt.loadNpmTasks("grunt-jsdoc");
grunt.registerTask("default", ["jshint", "clean", "copy:dist1", "copy:dist2", "uglify", "jsdoc", "copy:docs1", "copy:docs2"]);
};

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-2019 Ottmar Gobrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,267 @@
[Latest version][zip] | [Docs & API Reference][docs] | [Online demo][demo] | [APEX Plugin demo][apexdemo]
[zip]: https://github.com/ogobrecht/d3-force-apex-plugin/releases/latest
[docs]: https://ogobrecht.github.io/d3-force-apex-plugin/
[demo]: https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-1-getting-started.html
[apexdemo]: https://apex.oracle.com/pls/apex/f?p=18290
# Oracle APEX Region Type Plugin: D3 Force Network Chart
This is a D3 force implementation, playground and Oracle APEX plugin, which uses the
[D3 visualization library](http://d3js.org/) to render a network layout. It has the following features:
- Works with APEX versions >= 5.1.4 or standalone in every HTML page
- Interactive customization wizard
- Source data can be a XML string, JSON string or JavaScript Object (JSON)
- Link directions are visible and self references are rendered in a nice way - have a look in the online demos
- Node sizes are calculated between given min and max values depending on the SIZEVALUE attribute in your source data
- Node colors are assigned depending on the given COLORVALUE attribute in your source data - if you provide a IMAGE attribute for a node, then the image is used instead of a fill color
- Optional tooltips depending on the given INFOSTRING attribute in your source data
- If you have a node attribute called LINK, you can define on which event the URL should be called - default is dblclick - try it out in the online demos by double clicking the node KING
- Nodes can be pinned and the current positions can be saved and loaded to predefine a layout - optionally you can align the nodes to a grid when they are dragged around
- Labels can be wrapped and placed after force end to prevent overlapping (optional, per default switched off)
- With the lasso mode you can select nodes and implement a graphical multi select
- The graph can be zoomed between the two configured min and max scale factors
- There is a JavaScript API to interact with the graph ([API reference][docs]), also including 12 events (node click, node double click, node contextmenu, node mouse enter, node mouse leave, link click, lasso start, lasso end, force start, force end, render end, resize)
- All 12 events are available in APEX - the plugin region can be AJAX refreshed and triggers then also apexbeforerefresh and apexafterrefresh
## Requirements
- APEX 5.1.4 or higher, if used as a plugin
- A modern browser, which is able to work with SVG and CSS3 - for more informations see the [D3 Wiki](https://github.com/mbostock/d3/wiki#browser--platform-support)
## Installation
### APEX
- Download the [latest version][zip]
- Install the plugin by importing the sql file in the folder `apex-plugin`
### Any HTML page
- Download the [latest version][zip]
- See `dist/example.html` and `docs/tutorial-1-getting-started.html`
## Credits
I would like to say THANK YOU to all the people who share their knowledge. Without this sharing I would not have been able to create this D3 implementation. Special thanks to Mike Bostock for his great library and to Carsten Czarski for mentoring me on Oracle APEX plugin development.
## Roadmap
### 4.0.0 (201x-xx-xx) in planning
- Update to current D3 version (5.x.x): [link 1](https://github.com/d3/d3/blob/master/CHANGES.md#forces-d3-force), [link 2](https://github.com/d3/d3-force/blob/master/README.md)
- Devide code base into modularized graph code and APEX plugin code in different repos to make clear, that the graph function can run in any HTML environment
## Changelog
This D3 force implementation uses [semantic versioning](http://semver.org).
Please refer to the [documentation](https://ogobrecht.github.io/d3-force-apex-plugin/) for more informations on how to get started and an overview of all graph methods. Please use for all comments and discussions the [issues functionality on GitHub](https://github.com/ogobrecht/d3-force-apex-plugin/issues).
### 3.1.0 (2019-06-02)
ATTENTION: You need at least APEX 5.1.4 to be able to import the plugin in your APEX apps. If you need to support older APEX versions (at least 4.2) then download the plugin release 3.0.0.
- New option forceTimeLimit ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.forceTimeLimit))
- Nodes have now also a background color when an background image is defined (useful for images with transparency)
- New Link attribute LABEL ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-2-node-and-link-attributes.html)), which is rendered as a text along the link path and fires the link click event when clicked (the label is easier to click then the link itself - so we have here a usability improvement)
- Two new helper methods to get the center of the graph (border box) or the SVG viewport:
- centerPositionGraph ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.centerPositionGraph))
- centerPositionViewport ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.centerPositionViewport))
Thanks are going to github.com/Ignacius68 for the valuable feedback and all the beta testing.
### 3.0.0 (2018-11-26)
Because of breaking API changes we have a new major realease:
- Overall improvements
- Better responsiveness by implementing a resize observer (native in Chrome since v64, polyfill for other browsers)
- Default true for the following options: `zoomToFitOnForceEnd` (was false in the past), `zoomToFitOnResize` (new option), `keepAspectRatioOnResize` (new option)
- When setting the option `useDomParentWidth` to true together with the previous mentioned defaults you can achieve a responsiveness like with images set to width 100% - see the [online demo][demo] and play around with it
- All zoom relevant API methods are no longer depending on the `zoomMode` - they work simply always
- The `zoomMode` sets only the ability for the end user to use zoom and pan
- Fixed
- APEX plug-in - sample data is rendered before live data (#32) - thanks are going to github.com/Ignacius68 for finding this bug
- New events
- Resize ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onResizeFunction))
- New options
- labelSplitCharacter ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.labelSplitCharacter))
- onResizeFunction ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onResizeFunction))
- onResizeFunctionTimeout ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onResizeFunctionTimeout))
- zoomToFitOnResize ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoomToFitOnResize))
- keepAspectRatioOnResize ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.keepAspectRatioOnResize))
- Changed methods
- `zoom` has now a parameter `duration` ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoom))
- `transform` has now a parameter `duration` ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.transform))
- `useDomParentWidth` ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.useDomParentWidth)) no longer needs a render call to take into effect - it works now immediately; Please remove unneccesary render calls to save CPU and battery time
- Deprecated methods for clean API
- `zoomSmooth` - can be replaced with the `zoom` method ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoom)), please provide a appropriate duration parameter (default is 1500 with zoomSmooth)
Thanks are going to github.com/Ignacius68 for the idea for option `labelSplitCharacter` and all the beta testing.
### 2.2.0 (2018-09-29)
- New events
- Render end ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onRenderEndFunction))
- Force start ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onForceStartFunction))
- Force end ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onForceEndFunction))
- New graph methods
- nodes ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.nodes))
- links ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.links))
- selfLinks ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.selfLinks))
- All three returning a D3 selection (array) for direct manipulation with D3 methods like `style` or `classed` - also see the [D3 docs](https://github.com/d3/d3-3.x-api-reference/blob/master/Selections.md#operating-on-selections)
Thanks are going to github.com/Ignacius68 for the inspiration.
### 2.1.2 (2018-01-07)
- Fixed again :-(
- APEX plugin - semi colon in region query no longer throws an error
- Was a copy paste bug... no comments please...
### 2.1.1 (2018-01-06)
- Fixed: Nodes stick on the top left corner in APEX 5.x under some circumstances
- Improved docs: getting started section
### 2.1.0 (2017-12-30)
- New option `wrapLabels` with a configurable max width - thanks to Ekaterina & Andrey for the idea
- New option `zoomToFitOnForceEnd` to fit the graph in the available space on force end (like the automatic label placement) - needs the zoomMode switched on to work properly
- New API method `zoomToFit`, which is used by the option zoomToFitOnForceEnd - now you can do things like `example.width(800).height(600).zoomToFit()` :-)
- APEX enhancements: the graph is listen to the event `apexwindowresized` and the click on the navigation control button in the universal theme - together with the option `useDomParentWidth` the graph is then always using the available width
- Changed: Use JSDoc to generate documentation and API reference. Relocate documentation from own Wiki to GitHub pages
- Reorganized repository structure
- Fixed: Standalone version not loading after APEX 5.1 bugfix
- Fixed: APEX plugin - semi colon in region query no longer throws an error
### 2.0.3 (2016-12-13)
- Fixed: #18 - APEX 5.1: jQuery reports syntax error and graph stops loading, if "Page Items to Submit" is not configured - thanks to github.com/KiralyCs to report this issue
### 2.0.2 (2016-07-17)
- Fixed: #12 - tooltips not showing correctly, if showLabels are set to false - thanks to github.com/pocelka to report this issue
### 2.0.1 (2015-11-18)
- Fixed: Fixed positions not working in initial data in v2.0.0 - thanks to github.com/rlashaw to report this issue
- Move online demo and documentation to own wiki for better maintenance
### 2.0.0 (2015-11-07)
- New option `preventLabelOverlappingOnForceEnd`: If set to true the labels are aligned with a simulated annealing function to prevent overlapping when the graph is cooled down (correctly on the force end event and only on labels, who are not circular) - thanks to Philippe Duchateau to ask for such a feature and all the testing
- New option `labelPlacementIterations`: The number of iterations for the preventLabelOverlappingOnForceEnd function - default is 250 - as higher the number, as higher the quality of the result - for details refer to the description of the [simulated annealing function](https://github.com/tinker10/D3-Labeler) from the author Evan Wang
- New behaviour: the font size and weight of a label is aligned when you hovering a node with your mouse - this helps you to find the right label in graphs with many nodes
- New possible value `dotted` for the links `STYLE` attribute: Now you have solid, dashed and dotted available for link styles
- New link attribute `INFOSTRING`: Like for nodes - this is shown as a tooltip, if tooltips are switched on in the configuration and you hover the links; ATTENTION: links are very narrow, so this plays nice together with the zoomMode; thanks again to Philippe Duchateau for the ideas of this and the next feature :-)
- New link attribute `COLOR`: This must be a HTML color code like `green` or `#00ff00` because of SVG standard 1.1 does not support the inheritance of colors to markers and the graph function hast to manage dynamic markers for the colors and therefore the color names are used as identifiers for the markers
- New API method/option `transform`: behaves like a normal getter/setter (the zoom and zoomSmooth methods implements only setters) and can be used in the conf object to initialize the graph with different translate/scale factors than [0,0]/1 - works only, if the zoomMode is set to true - the current transform value(an object) is rendered in the customization wizard conf object text area like all other options when the current value is different then the default value `{"translate":[0,0],"scale":1}`
- Fixed: With the option alignFixedNodesToGrid it was possible to place nodes direct on the graphs left or top border - now the nodes are placed to the gridSize value, if the current position is smaller or equal the half of the gridsize
- Fixed: Provided fixed positions on startup not correctly set
- Fixed: No node shown if there is only one record return (thanks to Kenny Wang for reporting this issue)
- Code integration of the D3 lasso and labeler plugins - no more need to load the files for this plugins
- Code replacement of the XML to JSON converter X2JS with an own one
- Code refactoring against JSHint: This refactoring is also the reason for a new major version (API changed: renamed graph function, integration of libs, new XML parser)
- Update to D3 v3.5.6
### 1.4.1 (2015-08-05)
- Fixed "Tooltip on wrong positions in complex layouts". This was also the case with APEX 5 and universal theme. Thanks to Philippe Duchateau for telling me about this problem.
### 1.4.0 (2015-08-03)
- New possible node attribute `COLORLABEL`: Since there is an option to render a legend, it makes no sense to render the color names as legend labels, if the colorScheme "direct" is used to directly deliver CSS color codes (thanks to Philippe Duchateau for telling me about the problems); With other color schemes it is ok, since the COLORVALUE information can be any string like department names or ids or city names or whatever; To not to break existing graphs, the COLORVALUE is used as the legend label, if the COLORLABEL is not given in the nodes attributes
- New option `onLinkClickFunction`: You can register a function which is called when a link is clicked (thanks to Niels de Bruijn for requesting this feature); It is not so easy to click a link, because the links are so narrow - if this option is needed I recommend to switch on the zoom mode - with zoom and pan it feels more natural to click links
- New option `setDomParentPaddingToZero`: Boolean. If true, the style `padding: 0px;` is added to the graphs DOM parent element; If false, this style is removed from the graphs DOM parent element
- The customization wizard shows now in the configuration object only non-default options; This reduces the size of the configuration object and is more transparent
- New API methods `options` and `optionsCustomizationWizard`: with this API methods you can get and set the whole configuration object with one call; `options` ouput includes all options, which are accessible via the API methods including the registered event functions (no APEX dynamic actions, only the functions under the report attributes); `optionsCustomizationWizard` output includes only the options, which are accessible via the customization wizard; With both methods you can set all options which are accessible via the API in one call
- Restructuring the online API reference method overview
### 1.3.0 (2015-06-07)
- New option `showLoadingIndicatorOnAjaxCall`: if set to true, a loading indicator is shown when used as a APEX plugin during the AJAX calls; If you want to show the loading indicator in a standalone implementation you can show and hide the loading indicator directly with the API method `showLoadingIndicator` (SHOW: `example.showLoadingIndicator(true);` HIDE: `example.showLoadingIndicator(false);`)
- Update to D3 v3.5.5
### 1.2.1 (2015-06-02)
- Fixed "Customize wizard jumps down when dragged on pages with hidden or fixed elements"
### 1.2.0 (2015-05-31)
- Refactor render function, so that the returned graph function is only one line of code and does not spoil the console when debug is set to true
- New option `zoomMode` (thanks to Alexej Schneider to ask for this feature and for testing the new version and his valuable feedback): I tried this before and was not happy with the solution, because the pan were disturbing the nodes drag functionality - now it is working :-) ATTENTION: When zoomMode is set to true then the lassoMode is only working with the pressed alt or shift key KNOWN BUG: In iOS it is after the first zoom event no more possible, to drag a node - instead the whole graph is moved - this is, because iOS Safari provide a wrong event.target.tagName. Also a problem: your are not able to press the alt or shift key - if you want to use lasso and zoom together on a touch device, you have to provide a workaround; One possible way is to provide a button, which turns zoom mode on and off with the API zoomMode method - then the user has the choice between these two modes - not comfortable, but working
- New option `minZoomFactor`: The minimum possible zoom factor
- New option `maxZoomFactor`: The maximum possible zoom factor
- New method `zoom`: Can be used to programatically zoom to a point in the graph with the three parameters centerX, centerY and viewportWidth; [read more...](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoom)
- New method `zoomSmooth`: Does the same as the zoom method, but animated in a nice way: [read more...](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoomSmooth)
- New method `nodeDataById`: Helper function to get the data of one node. Can be helpful for the two new zoom methods to programatically focus a single node
- New option `showLegend`: renders a legend for all (distinct) COLORVALUE attribute values of the nodes
- New option `showLabels`: Labels are not new - a label is rendered, when a node has a filled attribute LABEL - new is the possibility to switch on and off the labels globally
- Hint in the customize wizard, that the configuration object has to be saved in the region attributes to save the configuration permanently (thanks to Renato Nobre to ask me a question about this topic)
- Reorganize the options in the customize wizard thematically: node/link/graph related options
### 1.1.0 (2015-04-19)
- New option `lassoMode`: boolean - if set to true you can select nodes with a lasso
- New events for lasso mode: `lassostart`, `lassoend` - if You register to this events, you get as data an object with all nodes, number of selected nodes and also a APEX compatible string of selected node IDs in the form of the multi select lists like `1234:567:890` - for details and examples see API reference
- New option `alignFixedNodesToGrid`: boolean - if set to true nodes are aligned to the nearest grid position on the drag end event - works only, if pinMode is set to true (thanks to Carsten Czarski for showing me an use case for this option)
- New option `gridSize`: numeric - default 50 - grid size for the new option `alignFixedNodesToGrid`
- New possible node attribute `IMAGE`: URL to an image - if you provide this attribute in your source data (SQL query with the APEX plugin), the node is rendered with an background image instead of a fill color (idea by Andrew Weir, thank you for your response!) - attention: this is definitly slowing down your visualization - please do not complain about this fact ;-)
- New possible node attributes `fixed`, `x`, `y` (all lower case, because of these are also internal attributes of the D3 force layout): With these attributes you are able to predefine a layout already in your data (SQL query)
- New API method `moveFixedNodes(x,y)`: moves all fixed nodes in the provided direction - `exampleGraphVariable.moveFixedNodes(10,-5).resume();` adds 10 to x position and -5 to y position on all fixed nodes - ATTENTION if alignFixedNodesToGrid is set to true this can have unexpected behavior - you must then provide values greater then grid size halved to see any changes on your graph, otherwise the positions are falling back to the nearest (current) grid position
- New API method `releaseFixedNodes`
- New API method `resume`: with this method you can resume the graph force without a complete render cycle - e.g. you call the new method `releaseFixedNodes` and to take your changes into effect you can call then resume `exampleGraphVariable.releaseFixedNodes().resume();`
- New API method `render`: with this method you can render the graph with a complete render cycle - when used standalone there is no difference between the start and the render method - when used as APEX plugin the start method try to fetch new data with the query provided in your region source and call then the render method - with the render method you are now able to rerender the graph in APEX without fetching new data `exampleGraphVariable.minNodeRadius(4).maxNodeRadius(20).render();`
- API method positions: In the past this method was only used to predefine a layout before rendering the graph - now you can call this method also after rendering is complete and with calling the new method resume you can apply new positions at runtime without rerender the graph `exampleGraphVariable.positions([...]).resume();` (thanks to Mark Russellbrown to show me an unconventional use case for my force implementation and therefore force me to think about modification after rendering ;-)
- New third keyword for the option `nodeLinkTarget` in the customize wizard: "domContainerID" - if you use this keyword, then each event on a node, that opens the link is using the DOM container ID of your graph for the link target - this means, all your links are opened in the same browser window/tab, but a second graph is using a different browser window/tab (thanks to Philippe Duchateau for the question regarding this option) - please have a look in the [API reference for more details](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.nodeLinkTarget)
- Reducing the rendered DOM data by removing unnecessary id attributes on nodes, links and labels
- Input data can now be also an object: you have the choice to deliver graph data in three formats (XML string, JSON string or JavaScript Object) - when used as APEX plugin the data is transferred as text - your query has to select a single clob result and this clob can also be a XML or JSON string - you have the choice depending on your database version and existing libraries
- Fixed "Dragging a node triggers a click event"
### 1.0.5 (2015-02-21)
- Fixed "Links not correctly rendered in IE 9, 10, 11 when showLinkDirection is set to true" (found by Philippe Duchateau, thank you for your response!)
### 1.0.4 (2015-02-15)
- Fixed "APEX - unable to view datasets > 32k" (found by Andrew Weir, thank you for your response!)
- Improved error handling: errors are shown as single nodes with error text as label
- Empty nodes array does no longer break render function
- Positions are rounded on export to save space for APEX parameter item
### 1.0.3 (2015-01-30)
- Fixed "APEX - AJAX refresh not working without setting items to submit in region source"
- Correct links from customize wizard to online API documentation
- Activate also debug mode, when customize wizard is started
- Some small cosmetic changes
### 1.0.2 (2015-01-30)
- Fixed "Configuration - Boolean values are not correct initialized" (found by Carsten Czarski, thank you for your response!)
- Fixed "APEX - Page items to submit not working on AJAX refresh" (found by Carsten Czarski, thank you for your response!)

@ -0,0 +1,34 @@
{
"name": "D3 Force Network Chart",
"version": "3.1.0",
"description": "D3 force directed network visualization with an interactive customization wizard",
"keywords": ["d3.js", "force layout", "network visualization"],
"homepage": "https://github.com/ogobrecht/d3-force-apex-plugin",
"bugs": {
"url": "https://github.com/ogobrecht/d3-force-apex-plugin/issues"
},
"license": "MIT",
"author": {
"name": "Ottmar Gobrecht",
"email": "ottmar.gobrecht@gmail.com",
"url": "https://ogobrecht.github.io",
"twitter": "ogobrecht",
"donationUrl": "https://www.paypal.me/ogobrecht"
},
"repository": {
"type": "git",
"url": "https://github.com/ogobrecht/d3-force-apex-plugin.git"
},
"oracle": {
"versions": ["11.2.0.1", "12.1.0.1"],
"apex": {
"versions": ["5.1.4"],
"plugin": {
"internalName": "NET.GOBRECHTS.D3.FORCE",
"type": "region",
"demo": "https://apex.oracle.com/pls/apex/f?p=18290:1",
"previewImage": "https://raw.githubusercontent.com/ogobrecht/d3-force-apex-plugin/master/preview.png"
}
}
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

@ -0,0 +1,208 @@
.net_gobrechts_d3_force,
.net_gobrechts_d3_force_customize,
.net_gobrechts_d3_force_customize td,
.net_gobrechts_d3_force_tooltip {
box-sizing: content-box;
font-family: Arial, Helvetica, Sans Serif;
font-size: 10px;
line-height: normal;
background-color: #fff
}
.net_gobrechts_d3_force.border {
border: 1px solid silver;
border-radius: 5px;
}
.net_gobrechts_d3_force circle.highlighted {
stroke: #555;
stroke-width: 2px;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force circle.selected {
stroke: #555;
stroke-width: 4px;
stroke-dasharray: 4 2;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force text.linkLabel {
fill: #bbb;
font-size: 8px;
letter-spacing: 0;
cursor: default;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.labelCircular {
fill: black;
font-size: 10px;
letter-spacing: 0;
pointer-events: none;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.linkLabel {
text-anchor: middle;
}
.net_gobrechts_d3_force text.highlighted {
font-size: 12px;
font-weight: bold;
}
.net_gobrechts_d3_force text.link {
font-size: 12px;
fill: #268bd2;
cursor: pointer;
}
.net_gobrechts_d3_force line.link,
.net_gobrechts_d3_force path.link {
fill: none;
stroke: #bbb;
stroke-width: 1.5px;
stroke-opacity: 0.8;
}
.net_gobrechts_d3_force line.dotted,
.net_gobrechts_d3_force path.dotted {
stroke-dasharray: .01 3;
stroke-linecap: round;
}
.net_gobrechts_d3_force line.dashed,
.net_gobrechts_d3_force path.dashed {
stroke-dasharray: 4 2;
}
.net_gobrechts_d3_force line.highlighted,
.net_gobrechts_d3_force path.highlighted {
stroke: white !important;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force marker.normal {
stroke: none;
fill: #bbb;
}
.net_gobrechts_d3_force marker.highlighted {
stroke: none;
fill: #555;
}
.net_gobrechts_d3_force .graphOverlay,
.net_gobrechts_d3_force .graphOverlaySizeHelper {
fill: none;
pointer-events: all;
}
.net_gobrechts_d3_force .lasso path {
stroke: #505050;
stroke-width: 2px;
}
.net_gobrechts_d3_force .lasso .drawn {
fill-opacity: 0.05 ;
}
.net_gobrechts_d3_force .lasso .loop_close {
fill: none;
stroke-dasharray: 4,4;
}
.net_gobrechts_d3_force .lasso .origin {
fill: #3399FF;
fill-opacity: 0.5;
}
.net_gobrechts_d3_force .loading rect {
fill: black;
fill-opacity: 0.2;
}
.net_gobrechts_d3_force .loading text {
fill: white;
font-size: 36px;
text-anchor: middle;
}
.net_gobrechts_d3_force_tooltip {
position: absolute;
border-radius: 5px;
padding: 5px;
background-color: silver;
opacity: 0.9;
width: 150px;
overflow: auto;
font-size: 12px;
z-index: 100000;
pointer-events: none;
display: none;
}
.net_gobrechts_d3_force_customize {
border: 1px solid silver;
border-radius: 5px;
font-size: 12px;
position: absolute;
padding: 5px;
background-color:white;
box-shadow: 1px 1px 6px #666;
z-index: 200000;
}
.net_gobrechts_d3_force_customize .drag {
border: 1px dashed silver;
border-radius: 3px;
display: block;
cursor: move;
font-weight: bold;
height: 24px;
margin-bottom: 5px;
}
.net_gobrechts_d3_force_customize .title {
position: absolute;
top: 10px;
left: 10px;
}
.net_gobrechts_d3_force_customize .close {
position: absolute;
top: 10px;
right: 10px;
}
.net_gobrechts_d3_force_customize table {
border-collapse: collapse;
border-spacing: 0;
border: none;
margin:0;
padding:0;
}
.net_gobrechts_d3_force_customize tr.hidden {
display: none;
}
.net_gobrechts_d3_force_customize td {
padding: 1px;
font-size: 12px;
vertical-align: middle;
border: none;
}
.net_gobrechts_d3_force_customize .label {
text-align: right;
}
.net_gobrechts_d3_force_customize .warning {
background-color: orange;
}
.net_gobrechts_d3_force_customize input,
.net_gobrechts_d3_force_customize select,
.net_gobrechts_d3_force_customize textarea,
.net_gobrechts_d3_force_customize a {
border: 1px solid silver;
margin: 0;
padding: 0;
height: auto;
}
.net_gobrechts_d3_force_customize a {
border: 1px solid transparent;
color: #268bd2;
text-decoration: none;
cursor: pointer;
}
.net_gobrechts_d3_force_customize a:hover {
text-decoration: underline;
}
.net_gobrechts_d3_force_customize input:focus,
.net_gobrechts_d3_force_customize select:focus,
.net_gobrechts_d3_force_customize textarea:focus,
.net_gobrechts_d3_force_customize a:focus {
outline: none !important;
border: 1px solid #268bd2 !important;
background-color: #ffff99 !important;
box-shadow: none !important;
}
.net_gobrechts_d3_force_customize textarea {
font-size: 10px !important;
padding: 2px;
width: 160px;
height: 85px;
background-color: white;
color: black;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>D3 Force Network Chart</title>
</head>
<body style="font-family:Arial, Helvetica, sans-serif">
<h2>D3 Force Network Chart 3.1.0 Example Page</h2>
<p>To play around with the graph options click the "Customize Me" link.</p>
<p>For more informations also see <a href="https://ogobrecht.github.io/d3-force-apex-plugin/" target="_blank">the
docs</a>. <button onclick="example.useDomParentWidth((example.useDomParentWidth()?false:true))">Toggle option
useDomParentWidth</button></p>
<div id="example"></div>
<p>The customization wizard, which opens by clicking the link "Customize me", is not intended to used by end users
(and also not on small devices) - it is a convenience helper for developers to better understand the implications
of the different graph options.</p>
<p>The link is only shown, when the debug mode is switched on, which is the case here for demonstration purposes. The
debug mode writes many informations to the browser console - it should be switched off in a production environment.</p>
<link href="d3-force-3.1.0.css" rel="stylesheet" type="text/css">
<script src="lib/resize-observer-polyfill/ResizeObserver-1.5.0.min.js"></script>
<script src="lib/d3/d3-3.5.6.min.js"></script>
<script src="d3-force-3.1.0.min.js"></script>
<script>
window.onload = function () {
example = netGobrechtsD3Force('example')
.width(600)
.height(400)
//.useDomParentWidth(true) //for responsive layout
.zoomMode(true)
.lassoMode(true)
.wrapLabels(true)
.debug(true) //to enable the customization wizard
.render(); //sample data is provided when called without data
//see also https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-1-getting-started.html
}
</script>
</body>
</html>

@ -0,0 +1,29 @@
FROM: https://github.com/d3/d3/blob/master/LICENSE
Copyright 2010-2017 Mike Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,23 @@
FROM: https://github.com/tinker10/D3-Labeler/blob/master/LICENSE
The MIT License (MIT)
Copyright (c) 2013 Evan Wang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,29 @@
Source Code: https://github.com/d3/d3-plugins/blob/master/lasso/lasso.js
Copyright 2010-2017 Mike Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -0,0 +1,23 @@
FROM: https://github.com/que-etc/resize-observer-polyfill/blob/master/LICENSE
The MIT License (MIT)
Copyright (c) 2016 Denis Rul
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 120 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 114 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 120 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 117 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 116 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 120 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,208 @@
.net_gobrechts_d3_force,
.net_gobrechts_d3_force_customize,
.net_gobrechts_d3_force_customize td,
.net_gobrechts_d3_force_tooltip {
box-sizing: content-box;
font-family: Arial, Helvetica, Sans Serif;
font-size: 10px;
line-height: normal;
background-color: #fff
}
.net_gobrechts_d3_force.border {
border: 1px solid silver;
border-radius: 5px;
}
.net_gobrechts_d3_force circle.highlighted {
stroke: #555;
stroke-width: 2px;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force circle.selected {
stroke: #555;
stroke-width: 4px;
stroke-dasharray: 4 2;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force text.linkLabel {
fill: #bbb;
font-size: 8px;
letter-spacing: 0;
cursor: default;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.labelCircular {
fill: black;
font-size: 10px;
letter-spacing: 0;
pointer-events: none;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.linkLabel {
text-anchor: middle;
}
.net_gobrechts_d3_force text.highlighted {
font-size: 12px;
font-weight: bold;
}
.net_gobrechts_d3_force text.link {
font-size: 12px;
fill: #268bd2;
cursor: pointer;
}
.net_gobrechts_d3_force line.link,
.net_gobrechts_d3_force path.link {
fill: none;
stroke: #bbb;
stroke-width: 1.5px;
stroke-opacity: 0.8;
}
.net_gobrechts_d3_force line.dotted,
.net_gobrechts_d3_force path.dotted {
stroke-dasharray: .01 3;
stroke-linecap: round;
}
.net_gobrechts_d3_force line.dashed,
.net_gobrechts_d3_force path.dashed {
stroke-dasharray: 4 2;
}
.net_gobrechts_d3_force line.highlighted,
.net_gobrechts_d3_force path.highlighted {
stroke: #555 !important;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force marker.normal {
stroke: none;
fill: #bbb;
}
.net_gobrechts_d3_force marker.highlighted {
stroke: none;
fill: #555;
}
.net_gobrechts_d3_force .graphOverlay,
.net_gobrechts_d3_force .graphOverlaySizeHelper {
fill: none;
pointer-events: all;
}
.net_gobrechts_d3_force .lasso path {
stroke: #505050;
stroke-width: 2px;
}
.net_gobrechts_d3_force .lasso .drawn {
fill-opacity: 0.05 ;
}
.net_gobrechts_d3_force .lasso .loop_close {
fill: none;
stroke-dasharray: 4,4;
}
.net_gobrechts_d3_force .lasso .origin {
fill: #3399FF;
fill-opacity: 0.5;
}
.net_gobrechts_d3_force .loading rect {
fill: black;
fill-opacity: 0.2;
}
.net_gobrechts_d3_force .loading text {
fill: white;
font-size: 36px;
text-anchor: middle;
}
.net_gobrechts_d3_force_tooltip {
position: absolute;
border-radius: 5px;
padding: 5px;
background-color: silver;
opacity: 0.9;
width: 150px;
overflow: auto;
font-size: 12px;
z-index: 100000;
pointer-events: none;
display: none;
}
.net_gobrechts_d3_force_customize {
border: 1px solid silver;
border-radius: 5px;
font-size: 12px;
position: absolute;
padding: 5px;
background-color:white;
box-shadow: 1px 1px 6px #666;
z-index: 200000;
}
.net_gobrechts_d3_force_customize .drag {
border: 1px dashed silver;
border-radius: 3px;
display: block;
cursor: move;
font-weight: bold;
height: 24px;
margin-bottom: 5px;
}
.net_gobrechts_d3_force_customize .title {
position: absolute;
top: 10px;
left: 10px;
}
.net_gobrechts_d3_force_customize .close {
position: absolute;
top: 10px;
right: 10px;
}
.net_gobrechts_d3_force_customize table {
border-collapse: collapse;
border-spacing: 0;
border: none;
margin:0;
padding:0;
}
.net_gobrechts_d3_force_customize tr.hidden {
display: none;
}
.net_gobrechts_d3_force_customize td {
padding: 1px;
font-size: 12px;
vertical-align: middle;
border: none;
}
.net_gobrechts_d3_force_customize .label {
text-align: right;
}
.net_gobrechts_d3_force_customize .warning {
background-color: orange;
}
.net_gobrechts_d3_force_customize input,
.net_gobrechts_d3_force_customize select,
.net_gobrechts_d3_force_customize textarea,
.net_gobrechts_d3_force_customize a {
border: 1px solid silver;
margin: 0;
padding: 0;
height: auto;
}
.net_gobrechts_d3_force_customize a {
border: 1px solid transparent;
color: #268bd2;
text-decoration: none;
cursor: pointer;
}
.net_gobrechts_d3_force_customize a:hover {
text-decoration: underline;
}
.net_gobrechts_d3_force_customize input:focus,
.net_gobrechts_d3_force_customize select:focus,
.net_gobrechts_d3_force_customize textarea:focus,
.net_gobrechts_d3_force_customize a:focus {
outline: none !important;
border: 1px solid #268bd2 !important;
background-color: #ffff99 !important;
box-shadow: none !important;
}
.net_gobrechts_d3_force_customize textarea {
font-size: 10px !important;
padding: 2px;
width: 160px;
height: 85px;
background-color: white;
color: black;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,25 @@
/*global document */
(function() {
var source = document.getElementsByClassName('prettyprint source linenums');
var i = 0;
var lineNumber = 0;
var lineId;
var lines;
var totalLines;
var anchorHash;
if (source && source[0]) {
anchorHash = document.location.hash.substring(1);
lines = source[0].getElementsByTagName('li');
totalLines = lines.length;
for (; i < totalLines; i++) {
lineNumber++;
lineId = 'line' + lineNumber;
lines[i].id = lineId;
if (lineId === anchorHash) {
lines[i].className += ' selected';
}
}
}
})();

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,2 @@
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);

@ -0,0 +1,28 @@
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();

@ -0,0 +1,692 @@
@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,500i,500,600,600i|Roboto);
* {
box-sizing: border-box
}
html, body {
height: 100%;
width: 100%;
}
body {
color: #4d4e53;
background-color: white;
margin: 0 auto;
padding: 0;
font-family: 'Source Sans Pro', Helvetica, sans-serif;
font-size: 16px;
line-height: 160%;
}
a,
a:active {
color: #0095dd;
text-decoration: none;
}
a:hover {
text-decoration: underline
}
p, ul, ol, blockquote {
margin-bottom: 1em;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Roboto', sans-serif;
}
h1, h2, h3, h4, h5, h6 {
color: #000;
font-weight: 400;
margin: 0;
}
h1 {
font-weight: 300;
font-size: 48px;
margin: 1em 0 .5em;
}
h1.page-title {margin-bottom: 10px;font-size: 34px;font-weight: 300;border-bottom: solid 2px #ddd;padding: .5em 0 .5em;margin-top: 0;}
h2 {
font-size: 32px;
margin: 1.2em 0 .8em;
font-weight: bold;
}
h3 {
/* margin-top: 1em; */
/* margin-bottom: 16px; */
/* font-weight: bold; */
padding: 0;
margin: 1em 0 .6em;
font-size: 28px;
/* border-bottom: 1px solid #eee; */
/* padding-bottom: 15px; */
}
h4 {
font-size: 18px;
margin: 1em 0 .2em;
color: #4d4e53;
/* border-bottom: 1px solid #eee; */
padding-bottom: 8px;
}
h5, .container-overview .subsection-title {
font-size: 120%;
/* letter-spacing: -0.01em; */
margin: 20px 0 5px;
}
h6 {
font-size: 100%;
letter-spacing: -0.01em;
margin: 6px 0 3px 0;
font-style: italic;
}
tt, code, kbd, samp {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
background: #f4f4f4;
padding: 1px 5px;
border-radius: 5px;
font-size: 14px;
}
blockquote {
display: block;
border-left: 4px solid #eee;
margin: 0;
padding-left: 1em;
color: #888;
}
.class-description {
font-size: 130%;
line-height: 140%;
margin-bottom: 1em;
margin-top: 1em;
}
.class-description:empty {
margin: 0
}
/** Container **/
#main {
float: right;
min-width: 360px;
width: calc(100% - 250px);
padding: 0 30px 20px 30px;
}
header {
display: block
}
section {
display: block;
background-color: #fff;
padding: 0;
}
.variation {
display: none
}
.signature-attributes {
font-size: 60%;
color: #aaa;
font-style: italic;
font-weight: lighter;
}
/** Readme **/
.readme {
font-size: 16px;
}
.readme h1,
.readme h2,
.readme h3,
.readme h4,
.readme h5 {
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
padding: 0;
}
.readme h1 {
font-size: 2em;
padding-bottom: 0.3em;
}
.readme h2 {
font-size: 1.75em;
padding-bottom: 0.3em;
}
.readme h3 {
font-size: 1.5em;
background-color: transparent;
}
.readme h4 {
font-size: 1.25em;
}
.readme h5 {
font-size: 1em;
}
.readme img {
max-width: 100%;
}
.readme ul, .readme ol {
padding-left: 2em;
}
.readme pre > code {
font-size: 0.85em;
}
.readme table {
margin-bottom: 1em;
border-collapse: collapse;
border-spacing: 0;
}
.readme table tr {
background-color: #fff;
border-top: 1px solid #ccc;
}
.readme table th,
.readme table td {
padding: 6px 13px;
border: 1px solid #ddd;
}
.readme table tr:nth-child(2n) {
background-color: #f8f8f8;
}
/** Nav **/
nav {
float: left;
display: block;
width: 250px;
background: #fff;
overflow: auto;
position: fixed;
height: 100%;
padding: 10px;
border-right: 1px solid #eee;
/* box-shadow: 0 0 3px rgba(0,0,0,0.1); */
}
nav li {
list-style: none;
padding: 0;
margin: 0;
}
.nav-heading {
margin-top: 10px;
font-weight: bold;
}
.nav-heading a {
color: #888;
font-size: 14px;
display: inline-block;
}
.nav-item-type {
/* margin-left: 5px; */
width: 18px;
height: 18px;
display: inline-block;
text-align: center;
border-radius: 0.2em;
margin-right: 5px;
font-weight: bold;
line-height: 20px;
font-size: 13px;
}
.type-function {
background: #B3E5FC;
color: #0288D1;
}
.type-class {
background: #D1C4E9;
color: #4527A0;
}
.type-member {
background: #C8E6C9;
color: #388E3C;
}
.type-module {
background: #E1BEE7;
color: #7B1FA2;
}
/** Footer **/
footer {
color: hsl(0, 0%, 28%);
margin-left: 250px;
display: block;
padding: 30px;
font-style: italic;
font-size: 90%;
border-top: 1px solid #eee;
}
.ancestors {
color: #999
}
.ancestors a {
color: #999 !important;
text-decoration: none;
}
.clear {
clear: both
}
.important {
font-weight: bold;
color: #950B02;
}
.yes-def {
text-indent: -1000px
}
.type-signature {
color: #aaa
}
.name, .signature {
font-family: Consolas, Monaco, 'Andale Mono', monospace
}
.details {
margin-top: 14px;
border-left: 2px solid #DDD;
line-height: 30px;
}
.details dt {
width: 120px;
float: left;
padding-left: 10px;
}
.details dd {
margin-left: 70px
}
.details ul {
margin: 0
}
.details ul {
list-style-type: none
}
.details li {
margin-left: 30px
}
.details pre.prettyprint {
margin: 0
}
.details .object-value {
padding-top: 0
}
.description {
margin-bottom: 1em;
margin-top: 1em;
}
.code-caption {
font-style: italic;
font-size: 107%;
margin: 0;
}
.prettyprint {
font-size: 13px;
border: 1px solid #ddd;
border-radius: 3px;
box-shadow: 0 1px 3px hsla(0, 0%, 0%, 0.05);
overflow: auto;
}
.prettyprint.source {
width: inherit
}
.prettyprint code {
font-size: 12px;
line-height: 18px;
display: block;
background-color: #fff;
color: #4D4E53;
}
.prettyprint code:empty:before {
content: '';
}
.prettyprint > code {
padding: 15px
}
.prettyprint .linenums code {
padding: 0 15px
}
.prettyprint .linenums li:first-of-type code {
padding-top: 15px
}
.prettyprint code span.line {
display: inline-block
}
.prettyprint.linenums {
padding-left: 70px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.prettyprint.linenums ol {
padding-left: 0
}
.prettyprint.linenums li {
border-left: 3px #ddd solid
}
.prettyprint.linenums li.selected, .prettyprint.linenums li.selected * {
background-color: lightyellow
}
.prettyprint.linenums li * {
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.params, .props {
border-spacing: 0;
border: 1px solid #ddd;
border-collapse: collapse;
border-radius: 3px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
width: 100%;
font-size: 14px;
/* margin-left: 15px; */
}
.params .name, .props .name, .name code {
color: #4D4E53;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 100%;
}
.params td, .params th, .props td, .props th {
margin: 0px;
text-align: left;
vertical-align: top;
padding: 10px;
display: table-cell;
}
.params td {
border-top: 1px solid #eee
}
.params thead tr, .props thead tr {
background-color: #fff;
font-weight: bold;
}
.params .params thead tr, .props .props thead tr {
background-color: #fff;
font-weight: bold;
}
.params td.description > p:first-child, .props td.description > p:first-child {
margin-top: 0;
padding-top: 0;
}
.params td.description > p:last-child, .props td.description > p:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
dl.param-type {
/* border-bottom: 1px solid hsl(0, 0%, 87%); */
margin: 0;
padding: 0;
font-size: 16px;
}
.param-type dt, .param-type dd {
display: inline-block
}
.param-type dd {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
display: inline-block;
padding: 0;
margin: 0;
font-size: 14px;
}
.disabled {
color: #454545
}
/* navicon button */
.navicon-button {
display: none;
position: relative;
padding: 2.0625rem 1.5rem;
transition: 0.25s;
cursor: pointer;
user-select: none;
opacity: .8;
}
.navicon-button .navicon:before, .navicon-button .navicon:after {
transition: 0.25s;
}
.navicon-button:hover {
transition: 0.5s;
opacity: 1;
}
.navicon-button:hover .navicon:before, .navicon-button:hover .navicon:after {
transition: 0.25s;
}
.navicon-button:hover .navicon:before {
top: .825rem;
}
.navicon-button:hover .navicon:after {
top: -.825rem;
}
/* navicon */
.navicon {
position: relative;
width: 2.5em;
height: .3125rem;
background: #000;
transition: 0.3s;
border-radius: 2.5rem;
}
.navicon:before, .navicon:after {
display: block;
content: "";
height: .3125rem;
width: 2.5rem;
background: #000;
position: absolute;
z-index: -1;
transition: 0.3s 0.25s;
border-radius: 1rem;
}
.navicon:before {
top: .625rem;
}
.navicon:after {
top: -.625rem;
}
/* open */
.nav-trigger:checked + label:not(.steps) .navicon:before,
.nav-trigger:checked + label:not(.steps) .navicon:after {
top: 0 !important;
}
.nav-trigger:checked + label .navicon:before,
.nav-trigger:checked + label .navicon:after {
transition: 0.5s;
}
/* Minus */
.nav-trigger:checked + label {
transform: scale(0.75);
}
/* × and + */
.nav-trigger:checked + label.plus .navicon,
.nav-trigger:checked + label.x .navicon {
background: transparent;
}
.nav-trigger:checked + label.plus .navicon:before,
.nav-trigger:checked + label.x .navicon:before {
transform: rotate(-45deg);
background: #FFF;
}
.nav-trigger:checked + label.plus .navicon:after,
.nav-trigger:checked + label.x .navicon:after {
transform: rotate(45deg);
background: #FFF;
}
.nav-trigger:checked + label.plus {
transform: scale(0.75) rotate(45deg);
}
.nav-trigger:checked ~ nav {
left: 0 !important;
}
.nav-trigger:checked ~ .overlay {
display: block;
}
.nav-trigger {
position: fixed;
top: 0;
clip: rect(0, 0, 0, 0);
}
.overlay {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
background: hsla(0, 0%, 0%, 0.5);
z-index: 1;
}
.section-method {
margin-bottom: 30px;
padding-bottom: 30px;
border-bottom: 1px solid #eee;
}
@media only screen and (min-width: 320px) and (max-width: 680px) {
body {
overflow-x: hidden;
}
nav {
background: #FFF;
width: 250px;
height: 100%;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: -250px;
z-index: 3;
padding: 0 10px;
transition: left 0.2s;
}
.navicon-button {
display: inline-block;
position: fixed;
top: 1.5em;
right: 0;
z-index: 2;
}
#main {
width: 100%;
min-width: 360px;
}
#main h1.page-title {
margin: 1em 0;
}
#main section {
padding: 0;
}
footer {
margin-left: 0;
}
}
@media only print {
nav {
display: none;
}
#main {
float: none;
width: 100%;
}
}

@ -0,0 +1,111 @@
/* JSDoc prettify.js theme */
/* plain text */
.pln {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* string content */
.str {
color: hsl(104, 100%, 24%);
font-weight: normal;
font-style: normal;
}
/* a keyword */
.kwd {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a comment */
.com {
font-weight: normal;
font-style: italic;
}
/* a type name */
.typ {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* a literal value */
.lit {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* punctuation */
.pun {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* lisp open bracket */
.opn {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* lisp close bracket */
.clo {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a markup tag name */
.tag {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a markup attribute name */
.atn {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a markup attribute value */
.atv {
color: #006400;
font-weight: normal;
font-style: normal;
}
/* a declaration */
.dec {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* a variable name */
.var {
color: #000000;
font-weight: normal;
font-style: normal;
}
/* a function name */
.fun {
color: #000000;
font-weight: bold;
font-style: normal;
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
}

@ -0,0 +1,132 @@
/* Tomorrow Theme */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* Pretty printing styles. Used with prettify.js. */
/* SPAN elements with the classes below are added by prettyprint. */
/* plain text */
.pln {
color: #4d4d4c; }
@media screen {
/* string content */
.str {
color: hsl(104, 100%, 24%); }
/* a keyword */
.kwd {
color: hsl(240, 100%, 50%); }
/* a comment */
.com {
color: hsl(0, 0%, 60%); }
/* a type name */
.typ {
color: hsl(240, 100%, 32%); }
/* a literal value */
.lit {
color: hsl(240, 100%, 40%); }
/* punctuation */
.pun {
color: #000000; }
/* lisp open bracket */
.opn {
color: #000000; }
/* lisp close bracket */
.clo {
color: #000000; }
/* a markup tag name */
.tag {
color: #c82829; }
/* a markup attribute name */
.atn {
color: #f5871f; }
/* a markup attribute value */
.atv {
color: #3e999f; }
/* a declaration */
.dec {
color: #f5871f; }
/* a variable name */
.var {
color: #c82829; }
/* a function name */
.fun {
color: #4271ae; } }
/* Use higher contrast and text-weight for printable form. */
@media print, projection {
.str {
color: #060; }
.kwd {
color: #006;
font-weight: bold; }
.com {
color: #600;
font-style: italic; }
.typ {
color: #404;
font-weight: bold; }
.lit {
color: #044; }
.pun, .opn, .clo {
color: #440; }
.tag {
color: #006;
font-weight: bold; }
.atn {
color: #404; }
.atv {
color: #060; } }
/* Style */
/*
pre.prettyprint {
background: white;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
font-size: 12px;
line-height: 1.5;
border: 1px solid #ccc;
padding: 10px; }
*/
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0; }
/* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L4,
li.L5,
li.L6,
li.L7,
li.L8,
li.L9 {
/* */ }
/* Alternate shading for lines */
li.L1,
li.L3,
li.L5,
li.L7,
li.L9 {
/* */ }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

@ -0,0 +1,25 @@
{
"name": "d3-force-apex-plugin",
"version": "0.0.0-ignored",
"private": true,
"devDependencies": {
"eslint": "^5.6.1",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-node": "^7.0.1",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
"grunt": "^1.0.3",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-contrib-jshint": "^2.0.0",
"grunt-contrib-uglify": "^4.0.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-jsdoc": "^2.3.0",
"grunt-notify": "^0.4.1",
"ink-docstrap": "^1.3.2",
"jsdoc": "^3.5.5",
"jshint": "^2.9.6",
"minami": "^1.2.3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-{{CURRENT-YEAR}} Ottmar Gobrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,220 @@
FUNCTION d3_force__render( p_region IN apex_plugin.t_region
, p_plugin IN apex_plugin.t_plugin
, p_is_printer_friendly IN BOOLEAN )
RETURN apex_plugin.t_region_render_result
IS
v_configuration_object apex_application_page_regions.attribute_02%TYPE := p_region.attribute_02;
v_custom_styles apex_application_page_regions.attribute_03%TYPE := p_region.attribute_03;
v_region_static_id VARCHAR2( 100 );
BEGIN
v_region_static_id := apex_plugin_util.escape( p_region.static_id, TRUE );
apex_css.add_file( p_name => 'd3-force-'
, p_directory => p_plugin.file_prefix
, p_version => '3.1.0' );
apex_javascript.add_library( p_name => 'ResizeObserver-'
, p_directory => p_plugin.file_prefix
, p_version => '1.5.0'
, p_check_to_add_minified => TRUE );
apex_javascript.add_library( p_name => 'd3-'
, p_directory => p_plugin.file_prefix
, p_version => '3.5.6'
, p_check_to_add_minified => TRUE );
apex_javascript.add_library( p_name => 'd3-force-'
, p_directory => p_plugin.file_prefix
, p_version => '3.1.0'
, p_check_to_add_minified => TRUE );
HTP.p( CASE
WHEN v_custom_styles IS NOT NULL THEN
'<style>' || v_custom_styles || '</style>' || CHR( 10 )
END
|| '<svg></svg>'
|| CHR( 10 ) );
apex_javascript.add_onload_code( --> initialize chart function
'd3_force_'
|| v_region_static_id --> we need to use a global var - that is the reason to NOT use the var keyword
|| ' = netGobrechtsD3Force('
--> domContainerId:
|| apex_javascript.add_value( v_region_static_id, TRUE )
--> options:
|| CASE
WHEN v_configuration_object IS NOT NULL THEN
v_configuration_object
ELSE
'null'
END
|| ', '
--> apexPluginId:
|| apex_javascript.add_value( apex_plugin.get_ajax_identifier
, TRUE )
--> apexPageItemsToSubmit:
|| apex_javascript.add_value( p_region.ajax_items_to_submit
, FALSE )
|| ')'
|| CASE WHEN v( 'DEBUG' ) = 'YES' THEN '.debug(true)' END
|| CASE
WHEN p_region.attribute_09 IS NOT NULL THEN
'.positions(' || p_region.attribute_09 || ')'
END
|| CASE
WHEN p_region.attribute_04 IS NOT NULL THEN
'.onNodeClickFunction('
|| p_region.attribute_04
|| ')'
END
|| CASE
WHEN p_region.attribute_05 IS NOT NULL THEN
'.onNodeDblclickFunction('
|| p_region.attribute_05
|| ')'
END
|| CASE
WHEN p_region.attribute_06 IS NOT NULL THEN
'.onNodeContextmenuFunction('
|| p_region.attribute_06
|| ')'
END
|| CASE
WHEN p_region.attribute_12 IS NOT NULL THEN
'.onLinkClickFunction('
|| p_region.attribute_12
|| ')'
END
|| CASE
WHEN p_region.attribute_07 IS NOT NULL THEN
'.onNodeMouseenterFunction('
|| p_region.attribute_07
|| ')'
END
|| CASE
WHEN p_region.attribute_08 IS NOT NULL THEN
'.onNodeMouseleaveFunction('
|| p_region.attribute_08
|| ')'
END
|| CASE
WHEN p_region.attribute_10 IS NOT NULL THEN
'.onLassoStartFunction('
|| p_region.attribute_10
|| ')'
END
|| CASE
WHEN p_region.attribute_11 IS NOT NULL THEN
'.onLassoEndFunction('
|| p_region.attribute_11
|| ')'
END
|| CASE
WHEN p_region.attribute_13 IS NOT NULL THEN
'.onForceStartFunction('
|| p_region.attribute_13
|| ')'
END
|| CASE
WHEN p_region.attribute_14 IS NOT NULL THEN
'.onForceEndFunction('
|| p_region.attribute_14
|| ')'
END
|| CASE
WHEN p_region.attribute_15 IS NOT NULL THEN
'.onRenderEndFunction('
|| p_region.attribute_15
|| ')'
END
|| CASE
WHEN p_region.attribute_16 IS NOT NULL THEN
'.onResizeFunction('
|| p_region.attribute_16
|| ')'
END
--> start the visualization
|| '.start();' );
RETURN NULL;
END d3_force__render;
FUNCTION d3_force__ajax( p_region IN apex_plugin.t_region, p_plugin IN apex_plugin.t_plugin )
RETURN apex_plugin.t_region_ajax_result
IS
v_clob CLOB;
v_binds DBMS_SQL.varchar2_table;
v_cur INTEGER;
v_ret INTEGER;
BEGIN
IF p_region.source IS NOT NULL THEN
v_binds := wwv_flow_utilities.get_binds( p_region.source );
v_cur := DBMS_SQL.open_cursor;
DBMS_SQL.parse( c => v_cur, statement => REGEXP_REPLACE(p_region.source,';\s*$',''), language_flag => DBMS_SQL.native );
IF v_binds.COUNT > 0 THEN
FOR i IN v_binds.FIRST .. v_binds.LAST LOOP
DBMS_SQL.bind_variable( v_cur
, v_binds( i )
, APEX_UTIL.get_session_state( SUBSTR( v_binds( i ), 2 ) ) );
END LOOP;
END IF;
DBMS_SQL.define_column( c => v_cur, position => 1, column => v_clob );
v_ret := DBMS_SQL.execute( c => v_cur );
WHILE DBMS_SQL.fetch_rows( v_cur ) > 0 LOOP
DBMS_SQL.COLUMN_VALUE( v_cur, 1, v_clob );
END LOOP;
DBMS_SQL.close_cursor( v_cur );
IF sys.DBMS_LOB.getlength( v_clob ) > 0 THEN
DECLARE
v_len PLS_INTEGER;
v_pos PLS_INTEGER := 1;
v_amo PLS_INTEGER := 4000;
v_chu VARCHAR2( 32767 );
BEGIN
v_len := DBMS_LOB.getlength( v_clob );
WHILE v_pos <= v_len LOOP
v_amo := LEAST( v_amo, v_len - ( v_pos - 1 ) );
v_chu := DBMS_LOB.SUBSTR( v_clob, v_amo, v_pos );
v_pos := v_pos + v_amo;
HTP.prn( v_chu );
END LOOP;
END;
ELSE
HTP.prn( 'query_returned_no_data' ); --> prn prints without newline
END IF;
ELSE
HTP.prn( 'no_query_defined' );
END IF;
--> Free the temp LOB, if necessary
BEGIN
DBMS_LOB.freetemporary( v_clob );
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
RETURN NULL;
EXCEPTION
WHEN OTHERS THEN
--> Close the cursor, if open
BEGIN
IF v_cur IS NOT NULL
AND DBMS_SQL.is_open( v_cur ) THEN
DBMS_SQL.close_cursor( v_cur );
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
apex_debug.MESSAGE( SQLERRM );
--> Write error back to the Browser
HTP.prn( SQLERRM );
RETURN NULL;
END d3_force__ajax;

@ -0,0 +1,208 @@
.net_gobrechts_d3_force,
.net_gobrechts_d3_force_customize,
.net_gobrechts_d3_force_customize td,
.net_gobrechts_d3_force_tooltip {
box-sizing: content-box;
font-family: Arial, Helvetica, Sans Serif;
font-size: 10px;
line-height: normal;
background-color: #fff
}
.net_gobrechts_d3_force.border {
border: 1px solid silver;
border-radius: 5px;
}
.net_gobrechts_d3_force circle.highlighted {
stroke: #555;
stroke-width: 2px;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force circle.selected {
stroke: #555;
stroke-width: 4px;
stroke-dasharray: 4 2;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force text.linkLabel {
fill: #bbb;
font-size: 8px;
letter-spacing: 0;
cursor: default;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.labelCircular {
fill: black;
font-size: 10px;
letter-spacing: 0;
pointer-events: none;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.linkLabel {
text-anchor: middle;
}
.net_gobrechts_d3_force text.highlighted {
font-size: 12px;
font-weight: bold;
}
.net_gobrechts_d3_force text.link {
font-size: 12px;
fill: #268bd2;
cursor: pointer;
}
.net_gobrechts_d3_force line.link,
.net_gobrechts_d3_force path.link {
fill: none;
stroke: #bbb;
stroke-width: 1.5px;
stroke-opacity: 0.8;
}
.net_gobrechts_d3_force line.dotted,
.net_gobrechts_d3_force path.dotted {
stroke-dasharray: .01 3;
stroke-linecap: round;
}
.net_gobrechts_d3_force line.dashed,
.net_gobrechts_d3_force path.dashed {
stroke-dasharray: 4 2;
}
.net_gobrechts_d3_force line.highlighted,
.net_gobrechts_d3_force path.highlighted {
stroke: white !important;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force marker.normal {
stroke: none;
fill: #bbb;
}
.net_gobrechts_d3_force marker.highlighted {
stroke: none;
fill: #555;
}
.net_gobrechts_d3_force .graphOverlay,
.net_gobrechts_d3_force .graphOverlaySizeHelper {
fill: none;
pointer-events: all;
}
.net_gobrechts_d3_force .lasso path {
stroke: #505050;
stroke-width: 2px;
}
.net_gobrechts_d3_force .lasso .drawn {
fill-opacity: 0.05 ;
}
.net_gobrechts_d3_force .lasso .loop_close {
fill: none;
stroke-dasharray: 4,4;
}
.net_gobrechts_d3_force .lasso .origin {
fill: #3399FF;
fill-opacity: 0.5;
}
.net_gobrechts_d3_force .loading rect {
fill: black;
fill-opacity: 0.2;
}
.net_gobrechts_d3_force .loading text {
fill: white;
font-size: 36px;
text-anchor: middle;
}
.net_gobrechts_d3_force_tooltip {
position: absolute;
border-radius: 5px;
padding: 5px;
background-color: silver;
opacity: 0.9;
width: 150px;
overflow: auto;
font-size: 12px;
z-index: 100000;
pointer-events: none;
display: none;
}
.net_gobrechts_d3_force_customize {
border: 1px solid silver;
border-radius: 5px;
font-size: 12px;
position: absolute;
padding: 5px;
background-color:white;
box-shadow: 1px 1px 6px #666;
z-index: 200000;
}
.net_gobrechts_d3_force_customize .drag {
border: 1px dashed silver;
border-radius: 3px;
display: block;
cursor: move;
font-weight: bold;
height: 24px;
margin-bottom: 5px;
}
.net_gobrechts_d3_force_customize .title {
position: absolute;
top: 10px;
left: 10px;
}
.net_gobrechts_d3_force_customize .close {
position: absolute;
top: 10px;
right: 10px;
}
.net_gobrechts_d3_force_customize table {
border-collapse: collapse;
border-spacing: 0;
border: none;
margin:0;
padding:0;
}
.net_gobrechts_d3_force_customize tr.hidden {
display: none;
}
.net_gobrechts_d3_force_customize td {
padding: 1px;
font-size: 12px;
vertical-align: middle;
border: none;
}
.net_gobrechts_d3_force_customize .label {
text-align: right;
}
.net_gobrechts_d3_force_customize .warning {
background-color: orange;
}
.net_gobrechts_d3_force_customize input,
.net_gobrechts_d3_force_customize select,
.net_gobrechts_d3_force_customize textarea,
.net_gobrechts_d3_force_customize a {
border: 1px solid silver;
margin: 0;
padding: 0;
height: auto;
}
.net_gobrechts_d3_force_customize a {
border: 1px solid transparent;
color: #268bd2;
text-decoration: none;
cursor: pointer;
}
.net_gobrechts_d3_force_customize a:hover {
text-decoration: underline;
}
.net_gobrechts_d3_force_customize input:focus,
.net_gobrechts_d3_force_customize select:focus,
.net_gobrechts_d3_force_customize textarea:focus,
.net_gobrechts_d3_force_customize a:focus {
outline: none !important;
border: 1px solid #268bd2 !important;
background-color: #ffff99 !important;
box-shadow: none !important;
}
.net_gobrechts_d3_force_customize textarea {
font-size: 10px !important;
padding: 2px;
width: 160px;
height: 85px;
background-color: white;
color: black;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>D3 Force Network Chart</title>
</head>
<body style="font-family:Arial, Helvetica, sans-serif">
<h2>D3 Force Network Chart x.x.x Example Page</h2>
<p>To play around with the graph options click the "Customize Me" link.</p>
<p>For more informations also see <a href="https://ogobrecht.github.io/d3-force-apex-plugin/" target="_blank">the
docs</a>. <button onclick="example.useDomParentWidth((example.useDomParentWidth()?false:true))">Toggle option
useDomParentWidth</button></p>
<div id="example"></div>
<p>The customization wizard, which opens by clicking the link "Customize me", is not intended to used by end users
(and also not on small devices) - it is a convenience helper for developers to better understand the implications
of the different graph options.</p>
<p>The link is only shown, when the debug mode is switched on, which is the case here for demonstration purposes. The
debug mode writes many informations to the browser console - it should be switched off in a production environment.</p>
<link href="d3-force-x.x.x.css" rel="stylesheet" type="text/css">
<script src="lib/resize-observer-polyfill/ResizeObserver-1.5.0.min.js"></script>
<script src="lib/d3/d3-3.5.6.min.js"></script>
<script src="d3-force-x.x.x.min.js"></script>
<script>
window.onload = function () {
example = netGobrechtsD3Force('example')
.width(600)
.height(400)
//.useDomParentWidth(true) //for responsive layout
.zoomMode(true)
.lassoMode(true)
.wrapLabels(true)
.debug(true) //to enable the customization wizard
.render(); //sample data is provided when called without data
//see also https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-1-getting-started.html
}
</script>
</body>
</html>

@ -0,0 +1,172 @@
{{EXAMPLE-GRAPH}}
The graph above was started with this code:
```html
{{EXAMPLE-GRAPH-CODE}}
```
## Installation
### APEX
- Download the [latest version][zip]
- Install the plugin by importing the sql file in the folder `apex-plugin`
### Any HTML page
- Download the [latest version][zip]
- See `dist/example.html`
[zip]: https://github.com/ogobrecht/d3-force-apex-plugin/releases/latest
When using the Oracle APEX plugin, your variable to access the graph is automatically set by the plugin. You can open the JavaScript console in your browser and look for `d3_force_YOUR_REGION_STATIC_ID`. You can then interact with the graph - in the example we inspect the graphs current variables:
```js
example.inspect(); // in the example above
d3_force_YOUR_REGION_STATIC_ID.inspect(); // when using the Oracle APEX plugin
// or you can change the width of your graph:
example.width(700).resume();
d3_force_YOUR_REGION_STATIC_ID.width(700).resume();
// there are more then sixty methods...
// please have a look in the API methods overview
```
## Providing Data
You can provide data to the [render](./module-API.html#.render) (or [start](./module-API.html#.start) ) function. This data can be a JSON object, a JSON string or a XML string. Below the call for the graph variable `example` with the graph method `render` and the data for two nodes and links.
For all people outside the Oracle world: we use here data from an example employees table which is used since years for almost all Oracle related SQL trainings. Inside this table you find employees with an ID, name, salary, department ID and so on. We use here the department ID to color the nodes and the salary to calculate the node sizes.
Please have also a look at the [possible node and link attributes](./tutorial-2-node-and-link-attributes.html)
```js
example.render({
"data": {
"nodes": [{
"ID": "7839",
"LABEL": "KING is THE KING, you know?",
"COLORVALUE": "10",
"COLORLABEL": "Accounting",
"SIZEVALUE": 5000,
"LABELCIRCULAR": true,
"LINK": "http://apex.oracle.com/",
"INFOSTRING": "This visualization is based on the well known emp table."
},
{
"ID": "7698",
"LABEL": "BLAKE",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2850
}
],
"links": [{
"FROMID": "7839",
"TOID": "7839",
"STYLE": "dotted",
"COLOR": "blue",
"INFOSTRING": "This is a self link (same source and target node) rendered along a path with the STYLE attribute set to dotted and COLOR attribute set to blue."
},
{
"FROMID": "7698",
"TOID": "7839",
"STYLE": "dashed"
}
]
}
});
```
You can export the current graph data as a JSON object at every time with the [data](./module-API.html#.data) method:
```js
//JSON object
example.data();
//stringified JSON object
JSON.stringify(example.data());
```
## Configure The Graph
There are two ways to configure the graph:
1. Provide a configuration object to the graph function on initialisation
2. Use API methods before starting the graph or also on runtime
### Configuration Object
```js
var example = netGobrechtsD3Force(
'domContainerToAppendTheGraph',
{"width":"700", "height":"500"}
)
.render({"data":{
"nodes":[{...}, {...}],
"links":[{...}, {...}]
}});
```
### API Methods
```js
var example = netGobrechtsD3Force(
'domContainerToAppendTheGraph'
)
.width(700)
.height(500)
.render({"data":{
"nodes":[{...}, {...}],
"links":[{...}, {...}]
}});
```
Of course you can combine the two ways:
```js
var example = netGobrechtsD3Force(
'domContainerToAppendTheGraph',
{"width":"700","height":"500"}
)
.onNodeClickFunction(
function(event, data){
console.log(event, data, this);
}
)
.debug(true)
.render({"data":{
"nodes":[{...}, {...}],
"links":[{...}, {...}]
}});
```
If the DOM container is not existing, then the container is created under the body element.
### Customization wizard
You can use the customization wizard to get your configuration object. This
wizard has a predefined set of values, e.g. you can choose values between 300
and 1200 for the width. If this does not meet your requirements, you can of
course change these values in your configuration object. If you do so and use
the customization wizard later on, your additional values are appended to the
select lists of the wizard.
There are two ways to start the wizard:
1. Click the link “Customize Me” in the graph - this link is shown, when the graph is in debug mode (when you are using the APEX plugin with a Application Builder session, then the debug mode is automatically set to true): `example.debug(true);`
2. Directly start the wizard by setting the customize option to true: `example.customize(true);`
Each configuration option in the wizard is also implemented as a get and set method:
```js
example.width(); //get the current graph width
example.width(700).resume(); //set the current graph width and resume the graph
```
ATTENTION: Some options/methods are instantly working, some needs a resume of the graph force, some needs a complete render cycle with the start or render method. Please have also a look in the method descriptions for [start](./module-API.html#.start), [render](./module-API.html#.render), [resume](./module-API.html#.resume).

@ -0,0 +1,29 @@
Node and link attributes are case sensitive:
## Nodes
- `ID`: mandatory, string, alphanumeric node identifier
- `SIZEVALUE`: mandatory, number, numeric base for radius calculation
- `COLORVALUE`: mandatory, string, HTML color code or any alphanumeric string - see also [colorScheme](./module-API.html#.colorScheme)
- `COLORLABEL`: optional, string, used for legend - if not existing, colorvalue is used instead
- `LABEL`: optional, string, label for the node
- `LABELCIRCULAR`: optional, boolean, overwrites the global option [labelsCircular](./module-API.html#.labelsCircular)
- `INFOSTRING`: optional, string, this string is shown as a tooltip - see also [showTooltips](./module-API.html#.showTooltips) and [tooltipPosition](./module-API.html#.tooltipPosition)
- `LINK`: optional, string, URL to open on configurable event - see also [nodeEventToOpenLink](./module-API.html#.nodeEventToOpenLink)
- `IMAGE`: optional, string, URL to a background image for a node instead of a fill color
- `fixed`: optional, boolean, pin status of a node
- `x`: optional, number, x position of fixed (pinned) node
- `y`: optional, number, y position of fixed (pinned) node
Fixed, x and y are native D3 attributes - they must be lowercase.
## Links
- `FROMID`: mandatory, string, id of node, where a link starts (links are able to showing directions, see also [showLinkDirection](./module-API.html#.showLinkDirection))
- `TOID`: mandatory, string, id of node, where a link ends
- `STYLE`: optional, string, can be `solid` (default), `dotted` or `dashed`
- `COLOR`: optional, string, must be a HTML color code like `green` or `#00ff00`
- `LABEL`: optional, string, label for the link
- `INFOSTRING`: optional, string, this string is shown as a tooltip - see also [showTooltips](./module-API.html#.showTooltips) and [tooltipPosition](./module-API.html#.tooltipPosition)

@ -0,0 +1,82 @@
The following data (XML notation, not all records shown) is included in the source code. You can deliver your data in three formats: JSON object, JSON string or XML string. See the examples below.
## JSON Notation Example
```js
{
"data":{
"nodes":[
{
"ID":"7839",
"LABEL":"KING is THE KING, you know?",
"COLORVALUE":"10",
"COLORLABEL":"Accounting",
"SIZEVALUE":5000,
"LABELCIRCULAR":true,
"LINK":"http://apex.oracle.com/",
"INFOSTRING":"This visualization is based on the well known emp table."
},
{
"ID":"7698",
"LABEL":"BLAKE",
"COLORVALUE":"30",
"COLORLABEL":"Sales",
"SIZEVALUE":2850
}
],
"links":[
{
"FROMID":"7839",
"TOID":"7839",
"STYLE":"dotted",
"COLOR":"blue",
"INFOSTRING":"This is a self link (same source and target node) rendered along a path with the STYLE attribute set to dotted and COLOR attribute set to blue."
},
{
"FROMID":"7698",
"TOID":"7839",
"STYLE":"dashed",
"LABEL":"A link label"
}
]
}
}
```
## XML Notation Example
```xml
<data>
<nodes
ID="7839"
LABEL="KING is THE KING, you know?"
COLORVALUE="10"
COLORLABEL="Accounting"
SIZEVALUE="5000"
LABELCIRCULAR="true"
LINK="http://apex.oracle.com/"
INFOSTRING="This visualization is based on the well known emp table."
/>
<nodes
ID="7698"
LABEL="BLAKE"
COLORVALUE="30"
COLORLABEL="Sales"
SIZEVALUE="2850"
/>
<links
FROMID="7839"
TOID="7839"
STYLE="dotted"
COLOR="blue"
INFOSTRING="This is a self link (same source and target node) rendered along a path with the STYLE attribute set to dotted and COLOR attribute set to blue."
/>
<links
FROMID="7698"
TOID="7839"
STYLE="dashed"
LABEL="A link label"
/>
</data>
```

@ -0,0 +1,188 @@
Please note, that you have to deliver distinct data to ensure your graph is rendered correctly - see also this [issue on GitHub](https://github.com/ogobrecht/d3-force-apex-plugin/issues/17). It is always a good idea to review your queries/data before you try to use it in a visualization ;-)
## Oracle - Table EMP
This query is the base for the shipped sample data:
```sql
WITH
nodes AS ( --> START YOUR NODES QUERY HERE
SELECT XMLELEMENT( "nodes", xmlattributes(
empno AS id
, ename AS label
, sal AS sizevalue
, d.deptno AS colorvalue
--, d.dname AS colorlabel -- optional, used for the graph legend
--, 'http://...' AS link -- optional
--, 'some text' AS infostring -- optional, rendered as tooltip
--, 'false' AS labelcircular -- optional, overwrites labelsCircular
--, 'http://...' AS image -- optional, background image for a node
--, 'true' AS "fixed" -- optional | fixed, x and y are native
--, 100 AS "x" -- optional | D3 attributes, they must be
--, 100 AS "y" -- optional | lowercase
) ) AS xml_nodes
FROM emp e join dept d on e.deptno = d.deptno --< STOP YOUR NODES QUERY HERE
),
links AS ( --> START YOUR LINKS QUERY HERE
SELECT XMLELEMENT( "links", xmlattributes(
empno AS fromid
, NVL(mgr,empno) AS toid
--, 'dashed' AS style -- optional, solid, dotted or dashed
--, 'red' AS color -- optional, must be a HTML color code
--, 'some text' AS infostring -- optional, rendered as tooltip
) ) AS xml_links
FROM emp --< STOP YOUR LINKS QUERY HERE
)
SELECT XMLSERIALIZE( DOCUMENT( XMLELEMENT( "data",
( SELECT XMLAGG( xml_nodes ) FROM nodes ),
( SELECT XMLAGG( xml_links ) FROM links ) ) ) INDENT ) AS single_clob_result
FROM DUAL
```
## Oracle - Data Model of Current Schema
With this query you can visualize the data model of the current schema. Tested on Oracle 11g. Some subqueries select more data then needed for the visualization - this could be a starting point for your own custom visualization.
ATTENTION: I tried to speed up the dictionary queries by using the with clause and filtering each subquery for the desired tables. Also, I tried to get the correct NOT NULL informations from the dictionary, since the nullable column in user_tab_columns does not reflect table level not null constraints. If you play around with the query to find an own solution you can run in massive performance problems when you join directly the dictionary views.
Many thanks to Adrian Billington for his excellent [article about working with long columns](http://www.oracle-developer.net/display.php?id=430).
```sql
--> The following helper function is needed to read the constraint search condition:
CREATE OR REPLACE FUNCTION get_long_search_condition( p_constraint_name IN VARCHAR2 )
RETURN VARCHAR2
AS
v_return LONG;
CURSOR c_search_condition
IS
SELECT search_condition
FROM user_constraints
WHERE constraint_name = p_constraint_name;
BEGIN
OPEN c_search_condition;
FETCH c_search_condition INTO v_return;
CLOSE c_search_condition;
RETURN SUBSTR( v_return, 1, 4000 );
END;
```
```sql
WITH
tabs AS ( --> filter your tables here, all other queries use tabs as filter
SELECT table_name
, NVL( num_rows, 0 ) AS num_rows
, CASE --> used for coloring the nodes in the graph
WHEN table_name LIKE 'APEX$%' THEN 'APEX websheet apps'
WHEN table_name LIKE 'DEMO%' THEN 'Sample database app'
WHEN table_name in ('EMP', 'DEPT') THEN
'The well known emp & dept tables'
ELSE 'uncategorized tables'
END
AS table_group
FROM user_tables
WHERE table_name NOT LIKE 'PLSQL%'
),
cons AS (
SELECT owner
, constraint_name
, constraint_type
, table_name
, get_long_search_condition( constraint_name ) AS search_condition
, r_owner
, r_constraint_name
, delete_rule
, status
FROM user_constraints
WHERE table_name IN (SELECT table_name FROM tabs)
),
concols AS (
SELECT owner
, constraint_name
, table_name
, column_name
, position
FROM user_cons_columns
WHERE table_name IN (SELECT table_name FROM tabs)
),
connotnulls AS ( --> because of primary keys and not null check constraints we
--> have to select distinct here
SELECT DISTINCT table_name, column_name, nullable
FROM ( SELECT c.table_name
, cc.column_name
, c.constraint_name
, c.constraint_type
, c.search_condition
, 'N' AS nullable
FROM cons c
JOIN concols cc ON c.constraint_name = cc.constraint_name
WHERE c.status = 'ENABLED'
AND ( c.constraint_type = 'P'
OR c.constraint_type = 'C'
AND REGEXP_COUNT( TRIM( c.search_condition )
, '^"{0,1}'
|| cc.column_name
|| '"{0,1}\s+is\s+not\s+null$'
, 1
, 'i' ) = 1 ))
),
tabcols AS (
SELECT t.table_name
, t.column_name
, t.data_type
, t.data_length
, t.data_precision
, t.data_scale
, t.nullable AS nullable_dict
--> dict does not recognize table level not null constraints:
--> working with long columns:
--> http://www.oracle-developer.net/display.php?id=430
, NVL( n.nullable, 'Y' ) AS nullable_cons
FROM user_tab_columns t
LEFT JOIN connotnulls n
ON t.table_name = n.table_name
AND t.column_name = n.column_name
WHERE t.table_name IN (SELECT table_name FROM tabs)
),
fks AS (
SELECT concols.table_name AS source_table
, r_concols.table_name AS target_table
, cons.status
, tabcols.nullable_cons
FROM cons
JOIN concols
ON cons.constraint_name = concols.constraint_name
JOIN concols r_concols
ON cons.r_constraint_name = r_concols.constraint_name
JOIN tabcols
ON concols.table_name = tabcols.table_name
AND concols.column_name = tabcols.column_name
WHERE cons.constraint_type = 'R'
AND cons.status = 'ENABLED'
),
nodes AS ( --> START YOUR NODES QUERY HERE
SELECT XMLELEMENT( "nodes"
, xmlattributes( table_name AS id
, table_name AS label
, table_group AS colorvalue
, num_rows AS sizevalue ) )
AS xml_nodes
FROM tabs --< STOP YOUR NODES QUERY HERE
),
links AS ( --> START YOUR LINKS QUERY HERE
SELECT XMLELEMENT( "links"
, xmlattributes( source_table AS fromid
, target_table AS toid
, CASE nullable_cons
WHEN 'Y' THEN 'dashed'
WHEN 'N' THEN 'solid'
END AS style )
, status )
AS xml_links
FROM fks --< STOP YOUR LINKS QUERY HERE
)
SELECT XMLSERIALIZE( DOCUMENT( XMLELEMENT( "data",
( SELECT XMLAGG( xml_nodes ) FROM nodes ),
( SELECT XMLAGG( xml_links ) FROM links ) ) ) INDENT ) AS single_clob_result
FROM DUAL
```

@ -0,0 +1,52 @@
Some people have special use cases and ask interesting questions. On this page we collect them to provide examples for other users.
## Speed up background images on nodes
When you use background images on nodes instead of background colors this can slow down your graphs render performance. This is depending on the render performance of your browser, but even the fastest browser engines can have big problems with too many and/or too big images.
One possible workaround is to switch the background images to background colors when the force is starting and switch back to images when the force is stopping. Fortunately we have events for this available. Here an example - please align the graphs variable `example` to your specific one:
```js
example.onForceStartFunction(
function () {
example.nodes().each(function (node) {
elem = d3.select(this);
// Save the reference to the SVG pattern in a new node attribute.
// Your provided image URL is used in the pattern, not direct in the fill attribute.
// This is how SVG works, sorry. You can inspect the patterns in your browser console.
node.fill_backup = elem.style("fill");
elem.style("fill", "silver")
});
}
);
example.onForceEndFunction(
function () {
example.nodes().each(function (node) {
// Write back the saved reference to the SVG pattern.
d3.select(this).style("fill", node.fill_backup);
});
}
);
```
Thanks are going to github.com/Ignacius68 for questions around this topic.
## Stop force early when all nodes are fixed
This use case can be related to the previous one. If you deliver data with predefined, fixed positions for all nodes then the force is still running and calculate all positions. The fixed nodes are not updated within the ticks but the force is running as usual. This might become a problem when you wait for the force end to do some own things - like with the images from the previous use case.
The force has to run a minimum time to correct render all nodes. So what can we do? The graph API has currently no method to stop the force directly, but there is a trick. The graph API exposes a method mainly for debugging named `inspect`. With this method you have access to all the graph internal variables and functions. You can try this out in your browser console by executing `example.inspect()`.
To stop the force after 100ms we reuse the inspect method like so:
```js
example.onForceStartFunction(function () {
setTimeout(function () {
example.inspect().main.force.stop();
}, 100);
})
Thanks are going to github.com/Ignacius68 for questions around this topic.

@ -0,0 +1,17 @@
{
"1-getting-started": {
"title": "Getting Started"
},
"2-node-and-link-attributes": {
"title": "Node & Link Attributes"
},
"3-included-sample-data": {
"title": "Included Sample Data"
},
"4-example-queries": {
"title": "Example Queries"
},
"5-special-use-cases": {
"title": "Special Use Cases"
}
}

@ -563,7 +563,7 @@
</p>
</div>
</div>
<script type="text/javascript" src="../scripts/drag.js"></script>
<!-- <script type="text/javascript" src="../scripts/drag.js"></script> -->
<script type="text/javascript">
var l = $('.ocr_line');
@ -614,6 +614,27 @@
span.title = "hypervirus";
}
}
// ------------ DRAG ------------
$( function() {
$( ".draggable" ).draggable(
//{ containment: [-1300,-750,1800,1250] }
);
});
// ------------ ZOOM -------------
function zoom(event) {
event.preventDefault();
scale += event.deltaY * -0.01;
scale = Math.min(Math.max(.125, scale), 4);
el.style.transform = `scale(${scale})`;
}
let scale = 1;
const el = document.querySelector('body');
el.onwheel = zoom;
// CURSOR GRAB AND RELEASE
$('.draggable').on("mousedown",function(){

@ -0,0 +1,486 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Network Advanced</title>
<script src="d3-force-apex-plugin/docs/scripts/prettify/prettify.js"></script>
<script src="d3-force-apex-plugin/docs/scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style type="text/css">
body {margin: 0; overflow: hidden;}
svg{ background: black !important; border: none !important;}
circle {
cursor: grab;
fill: black !important;
}
.label {
font-size: 15px !important;
fill: white !important;
transform:translateY(22px);
}
circle.highlighted {
stroke: red !important;
}
line.highlighted {
stroke: red !important;
}
line{ stroke: black !important; }
.link {
fill: black !important;
}
</style>
</head>
<body>
<div id="main">
<div id="example"></div><!--the graph container-->
<link href="d3-force-apex-plugin/docs/lib/d3-force-3.1.0.css" rel="stylesheet" type="text/css">
<script src="d3-force-apex-plugin/docs/lib/ResizeObserver-1.5.0.min.js"></script>
<script src="d3-force-apex-plugin/docs/lib/d3-3.5.6.min.js"></script>
<script src="d3-force-apex-plugin/docs/lib/d3-force-3.1.0.min.js"></script>
<script>
var w = window.innerWidth;
var h = window.innerHeight;
window.onload = function (){
window.example = netGobrechtsD3Force("example")
.width(w)
.height(h)
.showLinkDirection(false)
.wrapLabels(true)
.zoomMode(true)
.forceTimeLimit(100000)
.charge(-5000)
.gravity(0.05)
.friction(1)
.theta(0.05)
.debug(true) //also creates the "Customize Me" link
.render({
"data": {
"nodes": [{
"ID": "1",
"LABEL": "SITUATIONISM",
"COLORVALUE": "10",
"COLORLABEL": "Accounting",
"SIZEVALUE": 13000,
"LABELCIRCULAR": false,
"LINK": "http://apex.oracle.com/",
"INFOSTRING": "Situazionismo e libertà",
},
{
"ID": "2",
"LABEL": "First World Congress of Liberated Artists",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"LABELCIRCULAR": false,
"SIZEVALUE": 3500
},
{
"ID": "3",
"LABEL": "Lettrist International",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2850
},
{
"ID": "4",
"LABEL": "International Movement for an Imaginist Bauhaus",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2850,
"INFOSTRING": "cipollotti"
},
{
"ID": "5",
"LABEL": "London Psychogeography Association",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2850
},
{
"ID": "6",
"LABEL": "Socialism ou Barbarie",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2850,
},
{
"ID": "7",
"LABEL": "Lettrism",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "8",
"LABEL": "COBRA",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "9",
"LABEL": "ULM",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 3500,
},
{
"ID": "10",
"LABEL": "BAUHAUS",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "11",
"LABEL": "SURREALISM",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "12",
"LABEL": "College of Sociology",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 3000,
},
{
"ID": "13",
"LABEL": "College of Pataphysics",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 3000,
},
{
"ID": "14",
"LABEL": "Oulipo",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "15",
"LABEL": "Lacan",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "16",
"LABEL": "LINGUISTICS / SEMIOTICS (Saussure)",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "17",
"LABEL": "Ogden & Richard (New Criticism)",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 5000,
},
{
"ID": "18",
"LABEL": "Barthes",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "19",
"LABEL": "Levi-Strauss",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "20",
"LABEL": "Media Theory (Mc Luhan)",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "21",
"LABEL": "CYBERNETICS",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "22",
"LABEL": "Cyberculture",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "23",
"LABEL": "COUNTERCULTURE",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "24",
"LABEL": "AI",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "25",
"LABEL": "PostHuman",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "26",
"LABEL": "Beat Generation",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 2000,
},
{
"ID": "27",
"LABEL": "PSYCHOANALYSIS",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "28",
"LABEL": "DADA",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 13000,
},
{
"ID": "29",
"LABEL": "NEO-DADA",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 5000,
},
{
"ID": "30",
"LABEL": "POP-ART",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 5000,
},
{
"ID": "31",
"LABEL": "FLUXUS",
"COLORVALUE": "30",
"COLORLABEL": "Sales",
"SIZEVALUE": 5000,
}
],
"links": [
{
"FROMID": "2",
"TOID": "1",
"STYLE": "solid",
},
{
"FROMID": "3",
"TOID": "2",
"STYLE": "solid"
},
{
"FROMID": "4",
"TOID": "2",
"STYLE": "solid"
},
{
"FROMID": "5",
"TOID": "2",
"STYLE": "solid"
},
{
"FROMID": "6",
"TOID": "1",
"STYLE": "dashed"
},
{
"FROMID": "7",
"TOID": "3",
"STYLE": "solid"
},
{
"FROMID": "8",
"TOID": "4",
"STYLE": "solid"
},
{
"FROMID": "9",
"TOID": "4",
"STYLE": "dashed",
"COLOR": "red"
},
{
"FROMID": "10",
"TOID": "9",
"STYLE": "dotted"
},
{
"FROMID": "11",
"TOID": "7",
"COLOR": "red",
"STYLE": "dashed"
},
{
"FROMID": "11",
"TOID": "12",
"COLOR": "red",
"STYLE": "dashed"
},
{
"FROMID": "11",
"TOID": "13",
"STYLE": "dashed",
"COLOR": "red",
"LABEL": "Queneaux"
},
{
"FROMID": "13",
"TOID": "14",
"STYLE": "dotted",
"LABEL": "Queneaux"
},
{
"FROMID": "12",
"TOID": "15",
"STYLE": "dotted",
},
{
"FROMID": "16",
"TOID": "17",
"STYLE": "dotted",
},
{
"FROMID": "17",
"TOID": "18",
"STYLE": "dotted",
},
{
"FROMID": "17",
"TOID": "19",
"STYLE": "dotted",
},
{
"FROMID": "17",
"TOID": "20",
"STYLE": "dotted",
},
{
"FROMID": "17",
"TOID": "15",
"STYLE": "dotted",
},
{
"FROMID": "17",
"TOID": "21",
"STYLE": "dotted",
},
{
"FROMID": "21",
"TOID": "22",
"STYLE": "dotted",
},
{
"FROMID": "21",
"TOID": "24",
"STYLE": "dotted",
},
{
"FROMID": "21",
"TOID": "25",
"STYLE": "dotted",
},
{
"FROMID": "26",
"TOID": "23",
"STYLE": "dotted",
},
{
"FROMID": "23",
"TOID": "22",
"STYLE": "dotted",
},
{
"FROMID": "21",
"TOID": "15",
"STYLE": "dotted",
},
{
"FROMID": "21",
"TOID": "20",
"STYLE": "dotted",
},
{
"FROMID": "27",
"TOID": "21",
"STYLE": "dotted",
},
{
"FROMID": "27",
"TOID": "15",
"STYLE": "dotted",
},
{
"FROMID": "27",
"TOID": "12",
"STYLE": "dotted",
},
{
"FROMID": "21",
"TOID": "9",
"STYLE": "dotted",
},
{
"FROMID": "17",
"TOID": "9",
"STYLE": "dotted",
},
{
"FROMID": "28",
"TOID": "11",
"STYLE": "dotted",
},
{
"FROMID": "28",
"TOID": "29",
"STYLE": "dotted",
},
{
"FROMID": "29",
"TOID": "30",
"STYLE": "dotted",
}
]
}
}); //sample data is provided when called without data
}
</script>
</div>
</body>
</html>

@ -0,0 +1 @@
*.sql linguist-language=PLSQL

@ -0,0 +1,12 @@
.DS_Store
.idea
node_modules
api-reference.md
example-query.sql
js/temp.js
d3-force-apex-plugin-demo-app.sql
d3-force-apex-plugin-demo-app.zip
description-apex-plugin.com.html
description-sample-app.html
temp.txt
temp.html

@ -0,0 +1,16 @@
{
"tags": {
"allowUnknownTags": true
},
"plugins": ["plugins/markdown"],
"templates": {
"cleverLinks": false,
"monospaceLinks": false,
"useLongnameInNav": false,
"showInheritedInNav": true
},
"markdown": {
"parser": "gfm",
"hardwrap": true
}
}

@ -0,0 +1,140 @@
/* global module */
module.exports = function(grunt) {
"use strict";
grunt.initConfig({
pkg: grunt.file.readJSON("apexplugin.json"),
currentYear: parseInt(grunt.template.today("yyyy")),
banner: '/**\n' +
' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
' * Copyright (c) 2015<%= currentYear > 2015 ? "-" + currentYear : "" %> <%= pkg.author.name %> - <%= pkg.license %> license\n' +
' */\n',
exampleGraph: '<button onclick="example.useDomParentWidth((example.useDomParentWidth()?false:true))">Toggle option useDomParentWidth</button>\n' +
'<div id="example"></div><!--the graph container-->\n' +
'<link href="./lib/d3-force-<%= pkg.version %>.css" rel="stylesheet" type="text/css">\n' +
'<script src="./lib/ResizeObserver-1.5.0.min.js"></script>\n' +
'<script src="./lib/d3-3.5.6.min.js"></script>\n' +
'<script src="./lib/d3-force-<%= pkg.version %>.min.js"></script>\n' +
'<script>\n' +
' window.onload = function (){\n' +
' window.example = netGobrechtsD3Force("example")\n' +
' .width(600)\n' +
' .height(400)\n' +
' .lassoMode(true)\n' +
' .wrapLabels(true)\n' +
' .debug(true) //also creates the "Customize Me" link\n' +
' .render(); //sample data is provided when called without data\n' +
' }\n' +
'</script>\n',
jshint: {
files: [
"Gruntfile.js",
"apexplugin.json",
"src/d3-force.js"
]
},
clean: ["docs", "dist/*.css", "dist/*.js"],
copy: {
dist1: {
src: "src/d3-force.js",
dest: "dist/d3-force-<%= pkg.version %>.js",
options: {
process: function(content, srcpath) {
return grunt.template.process("<%= banner %>") + "\n" +
content.replace(/x\.x\.x/g, grunt.template.process("<%= pkg.version %>"));
}
}
},
dist2: {
files: [{
src: "src/d3-force.css",
dest: "dist/d3-force-<%= pkg.version %>.css"
},
{
src: "src/example.html",
dest: "dist/example.html"
},
{
src: "src/LICENSE.txt",
dest: "LICENSE.txt"
}
],
options: {
process: function(content) {
return content
.replace(/x\.x\.x/g, grunt.template.process("<%= pkg.version %>"))
.replace(/{{CURRENT-YEAR}}/g, grunt.template.process("<%= currentYear %>"))
.replace(/{{EXAMPLE-GRAPH}}/g, grunt.template.process("<%= exampleGraph %>"));
}
}
},
docs1: {
files: [{
src: "docs/tutorial-1-getting-started.html",
dest: "docs/tutorial-1-getting-started.html"
}],
options: {
process: function(content, srcpath) {
return content.replace(/{{EXAMPLE-GRAPH}}/g, grunt.template.process("<%= exampleGraph %>"))
.replace(/{{EXAMPLE-GRAPH-CODE}}/g, grunt.template.process("<%= exampleGraph %>").replace(/</g, "&lt;"));
}
}
},
docs2: {
files: [{
src: "dist/lib/d3/d3-3.5.6.min.js",
dest: "docs/lib/d3-3.5.6.min.js"
},
{
src: "dist/lib/resize-observer-polyfill/ResizeObserver-1.5.0.min.js",
dest: "docs/lib/ResizeObserver-1.5.0.min.js"
},
{
src: "dist/d3-force-<%= pkg.version %>.css",
dest: "docs/lib/d3-force-<%= pkg.version %>.css"
},
{
src: "dist/d3-force-<%= pkg.version %>.min.js",
dest: "docs/lib/d3-force-<%= pkg.version %>.min.js"
}
]
}
},
uglify: {
options: {
banner: "<%= banner %>"
},
dist: {
src: "dist/d3-force-<%= pkg.version %>.js",
dest: "dist/d3-force-<%= pkg.version %>.min.js"
},
},
jsdoc: {
docs: {
src: ["README.md", "src/*.js"],
options: {
destination: "docs",
tutorials: "src/tutorials",
template: "node_modules/minami",
configure: ".jsdoc.json"
}
}
},
watch: {
files: [
"Gruntfile.js",
"apexplugin.json",
"src/**"
],
tasks: ["default"]
}
});
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-contrib-copy");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks("grunt-contrib-clean");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks("grunt-notify");
grunt.loadNpmTasks("grunt-jsdoc");
grunt.registerTask("default", ["jshint", "clean", "copy:dist1", "copy:dist2", "uglify", "jsdoc", "copy:docs1", "copy:docs2"]);
};

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-2019 Ottmar Gobrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,267 @@
[Latest version][zip] | [Docs & API Reference][docs] | [Online demo][demo] | [APEX Plugin demo][apexdemo]
[zip]: https://github.com/ogobrecht/d3-force-apex-plugin/releases/latest
[docs]: https://ogobrecht.github.io/d3-force-apex-plugin/
[demo]: https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-1-getting-started.html
[apexdemo]: https://apex.oracle.com/pls/apex/f?p=18290
# Oracle APEX Region Type Plugin: D3 Force Network Chart
This is a D3 force implementation, playground and Oracle APEX plugin, which uses the
[D3 visualization library](http://d3js.org/) to render a network layout. It has the following features:
- Works with APEX versions >= 5.1.4 or standalone in every HTML page
- Interactive customization wizard
- Source data can be a XML string, JSON string or JavaScript Object (JSON)
- Link directions are visible and self references are rendered in a nice way - have a look in the online demos
- Node sizes are calculated between given min and max values depending on the SIZEVALUE attribute in your source data
- Node colors are assigned depending on the given COLORVALUE attribute in your source data - if you provide a IMAGE attribute for a node, then the image is used instead of a fill color
- Optional tooltips depending on the given INFOSTRING attribute in your source data
- If you have a node attribute called LINK, you can define on which event the URL should be called - default is dblclick - try it out in the online demos by double clicking the node KING
- Nodes can be pinned and the current positions can be saved and loaded to predefine a layout - optionally you can align the nodes to a grid when they are dragged around
- Labels can be wrapped and placed after force end to prevent overlapping (optional, per default switched off)
- With the lasso mode you can select nodes and implement a graphical multi select
- The graph can be zoomed between the two configured min and max scale factors
- There is a JavaScript API to interact with the graph ([API reference][docs]), also including 12 events (node click, node double click, node contextmenu, node mouse enter, node mouse leave, link click, lasso start, lasso end, force start, force end, render end, resize)
- All 12 events are available in APEX - the plugin region can be AJAX refreshed and triggers then also apexbeforerefresh and apexafterrefresh
## Requirements
- APEX 5.1.4 or higher, if used as a plugin
- A modern browser, which is able to work with SVG and CSS3 - for more informations see the [D3 Wiki](https://github.com/mbostock/d3/wiki#browser--platform-support)
## Installation
### APEX
- Download the [latest version][zip]
- Install the plugin by importing the sql file in the folder `apex-plugin`
### Any HTML page
- Download the [latest version][zip]
- See `dist/example.html` and `docs/tutorial-1-getting-started.html`
## Credits
I would like to say THANK YOU to all the people who share their knowledge. Without this sharing I would not have been able to create this D3 implementation. Special thanks to Mike Bostock for his great library and to Carsten Czarski for mentoring me on Oracle APEX plugin development.
## Roadmap
### 4.0.0 (201x-xx-xx) in planning
- Update to current D3 version (5.x.x): [link 1](https://github.com/d3/d3/blob/master/CHANGES.md#forces-d3-force), [link 2](https://github.com/d3/d3-force/blob/master/README.md)
- Devide code base into modularized graph code and APEX plugin code in different repos to make clear, that the graph function can run in any HTML environment
## Changelog
This D3 force implementation uses [semantic versioning](http://semver.org).
Please refer to the [documentation](https://ogobrecht.github.io/d3-force-apex-plugin/) for more informations on how to get started and an overview of all graph methods. Please use for all comments and discussions the [issues functionality on GitHub](https://github.com/ogobrecht/d3-force-apex-plugin/issues).
### 3.1.0 (2019-06-02)
ATTENTION: You need at least APEX 5.1.4 to be able to import the plugin in your APEX apps. If you need to support older APEX versions (at least 4.2) then download the plugin release 3.0.0.
- New option forceTimeLimit ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.forceTimeLimit))
- Nodes have now also a background color when an background image is defined (useful for images with transparency)
- New Link attribute LABEL ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-2-node-and-link-attributes.html)), which is rendered as a text along the link path and fires the link click event when clicked (the label is easier to click then the link itself - so we have here a usability improvement)
- Two new helper methods to get the center of the graph (border box) or the SVG viewport:
- centerPositionGraph ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.centerPositionGraph))
- centerPositionViewport ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.centerPositionViewport))
Thanks are going to github.com/Ignacius68 for the valuable feedback and all the beta testing.
### 3.0.0 (2018-11-26)
Because of breaking API changes we have a new major realease:
- Overall improvements
- Better responsiveness by implementing a resize observer (native in Chrome since v64, polyfill for other browsers)
- Default true for the following options: `zoomToFitOnForceEnd` (was false in the past), `zoomToFitOnResize` (new option), `keepAspectRatioOnResize` (new option)
- When setting the option `useDomParentWidth` to true together with the previous mentioned defaults you can achieve a responsiveness like with images set to width 100% - see the [online demo][demo] and play around with it
- All zoom relevant API methods are no longer depending on the `zoomMode` - they work simply always
- The `zoomMode` sets only the ability for the end user to use zoom and pan
- Fixed
- APEX plug-in - sample data is rendered before live data (#32) - thanks are going to github.com/Ignacius68 for finding this bug
- New events
- Resize ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onResizeFunction))
- New options
- labelSplitCharacter ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.labelSplitCharacter))
- onResizeFunction ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onResizeFunction))
- onResizeFunctionTimeout ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onResizeFunctionTimeout))
- zoomToFitOnResize ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoomToFitOnResize))
- keepAspectRatioOnResize ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.keepAspectRatioOnResize))
- Changed methods
- `zoom` has now a parameter `duration` ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoom))
- `transform` has now a parameter `duration` ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.transform))
- `useDomParentWidth` ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.useDomParentWidth)) no longer needs a render call to take into effect - it works now immediately; Please remove unneccesary render calls to save CPU and battery time
- Deprecated methods for clean API
- `zoomSmooth` - can be replaced with the `zoom` method ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoom)), please provide a appropriate duration parameter (default is 1500 with zoomSmooth)
Thanks are going to github.com/Ignacius68 for the idea for option `labelSplitCharacter` and all the beta testing.
### 2.2.0 (2018-09-29)
- New events
- Render end ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onRenderEndFunction))
- Force start ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onForceStartFunction))
- Force end ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.onForceEndFunction))
- New graph methods
- nodes ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.nodes))
- links ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.links))
- selfLinks ([API reference](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.selfLinks))
- All three returning a D3 selection (array) for direct manipulation with D3 methods like `style` or `classed` - also see the [D3 docs](https://github.com/d3/d3-3.x-api-reference/blob/master/Selections.md#operating-on-selections)
Thanks are going to github.com/Ignacius68 for the inspiration.
### 2.1.2 (2018-01-07)
- Fixed again :-(
- APEX plugin - semi colon in region query no longer throws an error
- Was a copy paste bug... no comments please...
### 2.1.1 (2018-01-06)
- Fixed: Nodes stick on the top left corner in APEX 5.x under some circumstances
- Improved docs: getting started section
### 2.1.0 (2017-12-30)
- New option `wrapLabels` with a configurable max width - thanks to Ekaterina & Andrey for the idea
- New option `zoomToFitOnForceEnd` to fit the graph in the available space on force end (like the automatic label placement) - needs the zoomMode switched on to work properly
- New API method `zoomToFit`, which is used by the option zoomToFitOnForceEnd - now you can do things like `example.width(800).height(600).zoomToFit()` :-)
- APEX enhancements: the graph is listen to the event `apexwindowresized` and the click on the navigation control button in the universal theme - together with the option `useDomParentWidth` the graph is then always using the available width
- Changed: Use JSDoc to generate documentation and API reference. Relocate documentation from own Wiki to GitHub pages
- Reorganized repository structure
- Fixed: Standalone version not loading after APEX 5.1 bugfix
- Fixed: APEX plugin - semi colon in region query no longer throws an error
### 2.0.3 (2016-12-13)
- Fixed: #18 - APEX 5.1: jQuery reports syntax error and graph stops loading, if "Page Items to Submit" is not configured - thanks to github.com/KiralyCs to report this issue
### 2.0.2 (2016-07-17)
- Fixed: #12 - tooltips not showing correctly, if showLabels are set to false - thanks to github.com/pocelka to report this issue
### 2.0.1 (2015-11-18)
- Fixed: Fixed positions not working in initial data in v2.0.0 - thanks to github.com/rlashaw to report this issue
- Move online demo and documentation to own wiki for better maintenance
### 2.0.0 (2015-11-07)
- New option `preventLabelOverlappingOnForceEnd`: If set to true the labels are aligned with a simulated annealing function to prevent overlapping when the graph is cooled down (correctly on the force end event and only on labels, who are not circular) - thanks to Philippe Duchateau to ask for such a feature and all the testing
- New option `labelPlacementIterations`: The number of iterations for the preventLabelOverlappingOnForceEnd function - default is 250 - as higher the number, as higher the quality of the result - for details refer to the description of the [simulated annealing function](https://github.com/tinker10/D3-Labeler) from the author Evan Wang
- New behaviour: the font size and weight of a label is aligned when you hovering a node with your mouse - this helps you to find the right label in graphs with many nodes
- New possible value `dotted` for the links `STYLE` attribute: Now you have solid, dashed and dotted available for link styles
- New link attribute `INFOSTRING`: Like for nodes - this is shown as a tooltip, if tooltips are switched on in the configuration and you hover the links; ATTENTION: links are very narrow, so this plays nice together with the zoomMode; thanks again to Philippe Duchateau for the ideas of this and the next feature :-)
- New link attribute `COLOR`: This must be a HTML color code like `green` or `#00ff00` because of SVG standard 1.1 does not support the inheritance of colors to markers and the graph function hast to manage dynamic markers for the colors and therefore the color names are used as identifiers for the markers
- New API method/option `transform`: behaves like a normal getter/setter (the zoom and zoomSmooth methods implements only setters) and can be used in the conf object to initialize the graph with different translate/scale factors than [0,0]/1 - works only, if the zoomMode is set to true - the current transform value(an object) is rendered in the customization wizard conf object text area like all other options when the current value is different then the default value `{"translate":[0,0],"scale":1}`
- Fixed: With the option alignFixedNodesToGrid it was possible to place nodes direct on the graphs left or top border - now the nodes are placed to the gridSize value, if the current position is smaller or equal the half of the gridsize
- Fixed: Provided fixed positions on startup not correctly set
- Fixed: No node shown if there is only one record return (thanks to Kenny Wang for reporting this issue)
- Code integration of the D3 lasso and labeler plugins - no more need to load the files for this plugins
- Code replacement of the XML to JSON converter X2JS with an own one
- Code refactoring against JSHint: This refactoring is also the reason for a new major version (API changed: renamed graph function, integration of libs, new XML parser)
- Update to D3 v3.5.6
### 1.4.1 (2015-08-05)
- Fixed "Tooltip on wrong positions in complex layouts". This was also the case with APEX 5 and universal theme. Thanks to Philippe Duchateau for telling me about this problem.
### 1.4.0 (2015-08-03)
- New possible node attribute `COLORLABEL`: Since there is an option to render a legend, it makes no sense to render the color names as legend labels, if the colorScheme "direct" is used to directly deliver CSS color codes (thanks to Philippe Duchateau for telling me about the problems); With other color schemes it is ok, since the COLORVALUE information can be any string like department names or ids or city names or whatever; To not to break existing graphs, the COLORVALUE is used as the legend label, if the COLORLABEL is not given in the nodes attributes
- New option `onLinkClickFunction`: You can register a function which is called when a link is clicked (thanks to Niels de Bruijn for requesting this feature); It is not so easy to click a link, because the links are so narrow - if this option is needed I recommend to switch on the zoom mode - with zoom and pan it feels more natural to click links
- New option `setDomParentPaddingToZero`: Boolean. If true, the style `padding: 0px;` is added to the graphs DOM parent element; If false, this style is removed from the graphs DOM parent element
- The customization wizard shows now in the configuration object only non-default options; This reduces the size of the configuration object and is more transparent
- New API methods `options` and `optionsCustomizationWizard`: with this API methods you can get and set the whole configuration object with one call; `options` ouput includes all options, which are accessible via the API methods including the registered event functions (no APEX dynamic actions, only the functions under the report attributes); `optionsCustomizationWizard` output includes only the options, which are accessible via the customization wizard; With both methods you can set all options which are accessible via the API in one call
- Restructuring the online API reference method overview
### 1.3.0 (2015-06-07)
- New option `showLoadingIndicatorOnAjaxCall`: if set to true, a loading indicator is shown when used as a APEX plugin during the AJAX calls; If you want to show the loading indicator in a standalone implementation you can show and hide the loading indicator directly with the API method `showLoadingIndicator` (SHOW: `example.showLoadingIndicator(true);` HIDE: `example.showLoadingIndicator(false);`)
- Update to D3 v3.5.5
### 1.2.1 (2015-06-02)
- Fixed "Customize wizard jumps down when dragged on pages with hidden or fixed elements"
### 1.2.0 (2015-05-31)
- Refactor render function, so that the returned graph function is only one line of code and does not spoil the console when debug is set to true
- New option `zoomMode` (thanks to Alexej Schneider to ask for this feature and for testing the new version and his valuable feedback): I tried this before and was not happy with the solution, because the pan were disturbing the nodes drag functionality - now it is working :-) ATTENTION: When zoomMode is set to true then the lassoMode is only working with the pressed alt or shift key KNOWN BUG: In iOS it is after the first zoom event no more possible, to drag a node - instead the whole graph is moved - this is, because iOS Safari provide a wrong event.target.tagName. Also a problem: your are not able to press the alt or shift key - if you want to use lasso and zoom together on a touch device, you have to provide a workaround; One possible way is to provide a button, which turns zoom mode on and off with the API zoomMode method - then the user has the choice between these two modes - not comfortable, but working
- New option `minZoomFactor`: The minimum possible zoom factor
- New option `maxZoomFactor`: The maximum possible zoom factor
- New method `zoom`: Can be used to programatically zoom to a point in the graph with the three parameters centerX, centerY and viewportWidth; [read more...](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoom)
- New method `zoomSmooth`: Does the same as the zoom method, but animated in a nice way: [read more...](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.zoomSmooth)
- New method `nodeDataById`: Helper function to get the data of one node. Can be helpful for the two new zoom methods to programatically focus a single node
- New option `showLegend`: renders a legend for all (distinct) COLORVALUE attribute values of the nodes
- New option `showLabels`: Labels are not new - a label is rendered, when a node has a filled attribute LABEL - new is the possibility to switch on and off the labels globally
- Hint in the customize wizard, that the configuration object has to be saved in the region attributes to save the configuration permanently (thanks to Renato Nobre to ask me a question about this topic)
- Reorganize the options in the customize wizard thematically: node/link/graph related options
### 1.1.0 (2015-04-19)
- New option `lassoMode`: boolean - if set to true you can select nodes with a lasso
- New events for lasso mode: `lassostart`, `lassoend` - if You register to this events, you get as data an object with all nodes, number of selected nodes and also a APEX compatible string of selected node IDs in the form of the multi select lists like `1234:567:890` - for details and examples see API reference
- New option `alignFixedNodesToGrid`: boolean - if set to true nodes are aligned to the nearest grid position on the drag end event - works only, if pinMode is set to true (thanks to Carsten Czarski for showing me an use case for this option)
- New option `gridSize`: numeric - default 50 - grid size for the new option `alignFixedNodesToGrid`
- New possible node attribute `IMAGE`: URL to an image - if you provide this attribute in your source data (SQL query with the APEX plugin), the node is rendered with an background image instead of a fill color (idea by Andrew Weir, thank you for your response!) - attention: this is definitly slowing down your visualization - please do not complain about this fact ;-)
- New possible node attributes `fixed`, `x`, `y` (all lower case, because of these are also internal attributes of the D3 force layout): With these attributes you are able to predefine a layout already in your data (SQL query)
- New API method `moveFixedNodes(x,y)`: moves all fixed nodes in the provided direction - `exampleGraphVariable.moveFixedNodes(10,-5).resume();` adds 10 to x position and -5 to y position on all fixed nodes - ATTENTION if alignFixedNodesToGrid is set to true this can have unexpected behavior - you must then provide values greater then grid size halved to see any changes on your graph, otherwise the positions are falling back to the nearest (current) grid position
- New API method `releaseFixedNodes`
- New API method `resume`: with this method you can resume the graph force without a complete render cycle - e.g. you call the new method `releaseFixedNodes` and to take your changes into effect you can call then resume `exampleGraphVariable.releaseFixedNodes().resume();`
- New API method `render`: with this method you can render the graph with a complete render cycle - when used standalone there is no difference between the start and the render method - when used as APEX plugin the start method try to fetch new data with the query provided in your region source and call then the render method - with the render method you are now able to rerender the graph in APEX without fetching new data `exampleGraphVariable.minNodeRadius(4).maxNodeRadius(20).render();`
- API method positions: In the past this method was only used to predefine a layout before rendering the graph - now you can call this method also after rendering is complete and with calling the new method resume you can apply new positions at runtime without rerender the graph `exampleGraphVariable.positions([...]).resume();` (thanks to Mark Russellbrown to show me an unconventional use case for my force implementation and therefore force me to think about modification after rendering ;-)
- New third keyword for the option `nodeLinkTarget` in the customize wizard: "domContainerID" - if you use this keyword, then each event on a node, that opens the link is using the DOM container ID of your graph for the link target - this means, all your links are opened in the same browser window/tab, but a second graph is using a different browser window/tab (thanks to Philippe Duchateau for the question regarding this option) - please have a look in the [API reference for more details](https://ogobrecht.github.io/d3-force-apex-plugin/module-API.html#.nodeLinkTarget)
- Reducing the rendered DOM data by removing unnecessary id attributes on nodes, links and labels
- Input data can now be also an object: you have the choice to deliver graph data in three formats (XML string, JSON string or JavaScript Object) - when used as APEX plugin the data is transferred as text - your query has to select a single clob result and this clob can also be a XML or JSON string - you have the choice depending on your database version and existing libraries
- Fixed "Dragging a node triggers a click event"
### 1.0.5 (2015-02-21)
- Fixed "Links not correctly rendered in IE 9, 10, 11 when showLinkDirection is set to true" (found by Philippe Duchateau, thank you for your response!)
### 1.0.4 (2015-02-15)
- Fixed "APEX - unable to view datasets > 32k" (found by Andrew Weir, thank you for your response!)
- Improved error handling: errors are shown as single nodes with error text as label
- Empty nodes array does no longer break render function
- Positions are rounded on export to save space for APEX parameter item
### 1.0.3 (2015-01-30)
- Fixed "APEX - AJAX refresh not working without setting items to submit in region source"
- Correct links from customize wizard to online API documentation
- Activate also debug mode, when customize wizard is started
- Some small cosmetic changes
### 1.0.2 (2015-01-30)
- Fixed "Configuration - Boolean values are not correct initialized" (found by Carsten Czarski, thank you for your response!)
- Fixed "APEX - Page items to submit not working on AJAX refresh" (found by Carsten Czarski, thank you for your response!)

@ -0,0 +1,34 @@
{
"name": "D3 Force Network Chart",
"version": "3.1.0",
"description": "D3 force directed network visualization with an interactive customization wizard",
"keywords": ["d3.js", "force layout", "network visualization"],
"homepage": "https://github.com/ogobrecht/d3-force-apex-plugin",
"bugs": {
"url": "https://github.com/ogobrecht/d3-force-apex-plugin/issues"
},
"license": "MIT",
"author": {
"name": "Ottmar Gobrecht",
"email": "ottmar.gobrecht@gmail.com",
"url": "https://ogobrecht.github.io",
"twitter": "ogobrecht",
"donationUrl": "https://www.paypal.me/ogobrecht"
},
"repository": {
"type": "git",
"url": "https://github.com/ogobrecht/d3-force-apex-plugin.git"
},
"oracle": {
"versions": ["11.2.0.1", "12.1.0.1"],
"apex": {
"versions": ["5.1.4"],
"plugin": {
"internalName": "NET.GOBRECHTS.D3.FORCE",
"type": "region",
"demo": "https://apex.oracle.com/pls/apex/f?p=18290:1",
"previewImage": "https://raw.githubusercontent.com/ogobrecht/d3-force-apex-plugin/master/preview.png"
}
}
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.6 KiB

@ -0,0 +1,208 @@
.net_gobrechts_d3_force,
.net_gobrechts_d3_force_customize,
.net_gobrechts_d3_force_customize td,
.net_gobrechts_d3_force_tooltip {
box-sizing: content-box;
font-family: Arial, Helvetica, Sans Serif;
font-size: 10px;
line-height: normal;
background-color: #fff
}
.net_gobrechts_d3_force.border {
border: 1px solid silver;
border-radius: 5px;
}
.net_gobrechts_d3_force circle.highlighted {
stroke: #555;
stroke-width: 2px;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force circle.selected {
stroke: #555;
stroke-width: 4px;
stroke-dasharray: 4 2;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force text.linkLabel {
fill: #bbb;
font-size: 8px;
letter-spacing: 0;
cursor: default;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.labelCircular {
fill: black;
font-size: 10px;
letter-spacing: 0;
pointer-events: none;
}
.net_gobrechts_d3_force text.label,
.net_gobrechts_d3_force text.linkLabel {
text-anchor: middle;
}
.net_gobrechts_d3_force text.highlighted {
font-size: 12px;
font-weight: bold;
}
.net_gobrechts_d3_force text.link {
font-size: 12px;
fill: #268bd2;
cursor: pointer;
}
.net_gobrechts_d3_force line.link,
.net_gobrechts_d3_force path.link {
fill: none;
stroke: #bbb;
stroke-width: 1.5px;
stroke-opacity: 0.8;
}
.net_gobrechts_d3_force line.dotted,
.net_gobrechts_d3_force path.dotted {
stroke-dasharray: .01 3;
stroke-linecap: round;
}
.net_gobrechts_d3_force line.dashed,
.net_gobrechts_d3_force path.dashed {
stroke-dasharray: 4 2;
}
.net_gobrechts_d3_force line.highlighted,
.net_gobrechts_d3_force path.highlighted {
stroke: white !important;
stroke-opacity: 1.0;
}
.net_gobrechts_d3_force marker.normal {
stroke: none;
fill: #bbb;
}
.net_gobrechts_d3_force marker.highlighted {
stroke: none;
fill: #555;
}
.net_gobrechts_d3_force .graphOverlay,
.net_gobrechts_d3_force .graphOverlaySizeHelper {
fill: none;
pointer-events: all;
}
.net_gobrechts_d3_force .lasso path {
stroke: #505050;
stroke-width: 2px;
}
.net_gobrechts_d3_force .lasso .drawn {
fill-opacity: 0.05 ;
}
.net_gobrechts_d3_force .lasso .loop_close {
fill: none;
stroke-dasharray: 4,4;
}
.net_gobrechts_d3_force .lasso .origin {
fill: #3399FF;
fill-opacity: 0.5;
}
.net_gobrechts_d3_force .loading rect {
fill: black;
fill-opacity: 0.2;
}
.net_gobrechts_d3_force .loading text {
fill: white;
font-size: 36px;
text-anchor: middle;
}
.net_gobrechts_d3_force_tooltip {
position: absolute;
border-radius: 5px;
padding: 5px;
background-color: silver;
opacity: 0.9;
width: 150px;
overflow: auto;
font-size: 12px;
z-index: 100000;
pointer-events: none;
display: none;
}
.net_gobrechts_d3_force_customize {
border: 1px solid silver;
border-radius: 5px;
font-size: 12px;
position: absolute;
padding: 5px;
background-color:white;
box-shadow: 1px 1px 6px #666;
z-index: 200000;
}
.net_gobrechts_d3_force_customize .drag {
border: 1px dashed silver;
border-radius: 3px;
display: block;
cursor: move;
font-weight: bold;
height: 24px;
margin-bottom: 5px;
}
.net_gobrechts_d3_force_customize .title {
position: absolute;
top: 10px;
left: 10px;
}
.net_gobrechts_d3_force_customize .close {
position: absolute;
top: 10px;
right: 10px;
}
.net_gobrechts_d3_force_customize table {
border-collapse: collapse;
border-spacing: 0;
border: none;
margin:0;
padding:0;
}
.net_gobrechts_d3_force_customize tr.hidden {
display: none;
}
.net_gobrechts_d3_force_customize td {
padding: 1px;
font-size: 12px;
vertical-align: middle;
border: none;
}
.net_gobrechts_d3_force_customize .label {
text-align: right;
}
.net_gobrechts_d3_force_customize .warning {
background-color: orange;
}
.net_gobrechts_d3_force_customize input,
.net_gobrechts_d3_force_customize select,
.net_gobrechts_d3_force_customize textarea,
.net_gobrechts_d3_force_customize a {
border: 1px solid silver;
margin: 0;
padding: 0;
height: auto;
}
.net_gobrechts_d3_force_customize a {
border: 1px solid transparent;
color: #268bd2;
text-decoration: none;
cursor: pointer;
}
.net_gobrechts_d3_force_customize a:hover {
text-decoration: underline;
}
.net_gobrechts_d3_force_customize input:focus,
.net_gobrechts_d3_force_customize select:focus,
.net_gobrechts_d3_force_customize textarea:focus,
.net_gobrechts_d3_force_customize a:focus {
outline: none !important;
border: 1px solid #268bd2 !important;
background-color: #ffff99 !important;
box-shadow: none !important;
}
.net_gobrechts_d3_force_customize textarea {
font-size: 10px !important;
padding: 2px;
width: 160px;
height: 85px;
background-color: white;
color: black;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>D3 Force Network Chart</title>
</head>
<body style="font-family:Arial, Helvetica, sans-serif">
<h2>D3 Force Network Chart 3.1.0 Example Page</h2>
<p>To play around with the graph options click the "Customize Me" link.</p>
<p>For more informations also see <a href="https://ogobrecht.github.io/d3-force-apex-plugin/" target="_blank">the
docs</a>. <button onclick="example.useDomParentWidth((example.useDomParentWidth()?false:true))">Toggle option
useDomParentWidth</button></p>
<div id="example"></div>
<p>The customization wizard, which opens by clicking the link "Customize me", is not intended to used by end users
(and also not on small devices) - it is a convenience helper for developers to better understand the implications
of the different graph options.</p>
<p>The link is only shown, when the debug mode is switched on, which is the case here for demonstration purposes. The
debug mode writes many informations to the browser console - it should be switched off in a production environment.</p>
<link href="d3-force-3.1.0.css" rel="stylesheet" type="text/css">
<script src="lib/resize-observer-polyfill/ResizeObserver-1.5.0.min.js"></script>
<script src="lib/d3/d3-3.5.6.min.js"></script>
<script src="d3-force-3.1.0.min.js"></script>
<script>
window.onload = function () {
example = netGobrechtsD3Force('example')
.width(600)
.height(400)
//.useDomParentWidth(true) //for responsive layout
.zoomMode(true)
.lassoMode(true)
.wrapLabels(true)
.debug(true) //to enable the customization wizard
.render(); //sample data is provided when called without data
//see also https://ogobrecht.github.io/d3-force-apex-plugin/tutorial-1-getting-started.html
}
</script>
</body>
</html>

@ -0,0 +1,29 @@
FROM: https://github.com/d3/d3/blob/master/LICENSE
Copyright 2010-2017 Mike Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save