- Contract.php: 返回合约账户余额(balance_contract) - My.php: 地址管理增加BTC/ETH - AppContract.php: 一键平仓(closeall) - AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2) - site.php: 手续费减半(0.018→0.009) - agent_permission_setup.sql: 代理权限SQL - crypto_news_crawler.py: 新闻自动采集脚本
242 lines
9.6 KiB
HTML
Executable File
242 lines
9.6 KiB
HTML
Executable File
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>GoJS Packed Class Hierarchy</title>
|
|
<!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
|
|
<meta name="description" content="The JavaScript class hierarchy defined by the GoJS library, arranged in nested circles." />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<script src="../samples/assets/require.js"></script>
|
|
<script src="../assets/js/goSamples.js"></script> <!-- this is only for the GoJS Samples framework -->
|
|
<script id="code">
|
|
function init() {
|
|
if (window.goSamples) window.goSamples(); // init for these samples -- you don't need to call this
|
|
|
|
require(["../extensionsTS/PackedLayout"], function(app) {
|
|
var PackedLayout = app.PackedLayout;
|
|
|
|
// subclass PackedLayout to change default properties and override commitLayout function
|
|
function HierarchyLayout() {
|
|
PackedLayout.call(this);
|
|
this.packShape = PackedLayout.Spiral;
|
|
this.hasCircularNodes = true;
|
|
this.sortMode = PackedLayout.Area,
|
|
this.comparer = function(na, nb) {
|
|
// ensure label is placed last
|
|
if (na.data.isLabel) {
|
|
return 1;
|
|
}
|
|
if (nb.data.isLabel) {
|
|
return -1;
|
|
}
|
|
// otherwise sort in ascending order by size (all nodes are circular, so using width or height here doesn't matter)
|
|
return (na.actualBounds.width - nb.actualBounds.width);
|
|
}
|
|
}
|
|
go.Diagram.inherit(HierarchyLayout, PackedLayout);
|
|
|
|
/* after each group has had its layout applied, size and position it according
|
|
* to the smallest enclosing circle which goes around all of its nodes */
|
|
HierarchyLayout.prototype.commitLayout = function() {
|
|
if (this.group !== null) {
|
|
var groupData = keyToNodeDataMap.get(this.group.key);
|
|
|
|
var enclosingCircle = this.enclosingCircle;
|
|
var actualBounds = this.actualBounds;
|
|
|
|
var size = new go.Size(enclosingCircle.width, enclosingCircle.width);
|
|
this.diagram.model.setDataProperty(groupData, "size", size);
|
|
|
|
var dx = enclosingCircle.centerX - actualBounds.centerX;
|
|
var dy = enclosingCircle.centerY - actualBounds.centerY;
|
|
var position = new go.Point((actualBounds.width - enclosingCircle.width) / 2 + dx, (actualBounds.height - enclosingCircle.height) / 2 + dy);
|
|
this.diagram.model.setDataProperty(groupData, "position", position);
|
|
}
|
|
}
|
|
|
|
var $ = go.GraphObject.make; // for conciseness in defining templates
|
|
|
|
var myDiagram =
|
|
$(go.Diagram, "myDiagramDiv", // must be the ID or reference to div
|
|
{
|
|
layout: $(HierarchyLayout), // defined above
|
|
"animationManager.isEnabled": false,
|
|
isReadOnly: true,
|
|
initialAutoScale: go.Diagram.Uniform
|
|
});
|
|
|
|
// common definitions for both Nodes and Groups
|
|
var toolTipTemplate =
|
|
$(go.Adornment, "Auto",
|
|
$(go.Shape, { fill: "white" }),
|
|
$(go.TextBlock, { margin: 4 },
|
|
new go.Binding("text", "tooltip"))
|
|
);
|
|
|
|
var selectionAdornmentTemplate =
|
|
$(go.Adornment, "Auto",
|
|
$(go.Shape, "Circle",
|
|
{ fill: null, stroke: "dodgerblue", strokeWidth: 3,
|
|
spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight }),
|
|
$(go.Placeholder)
|
|
);
|
|
|
|
function commonStyle() {
|
|
return [
|
|
{
|
|
toolTip: toolTipTemplate,
|
|
selectionAdornmentTemplate: selectionAdornmentTemplate,
|
|
doubleClick: function(e, node) {
|
|
var url = "../../api/symbols/" + node.data.key + ".html";
|
|
window.open(url, "_blank");
|
|
}
|
|
}
|
|
];
|
|
}
|
|
|
|
myDiagram.nodeTemplate =
|
|
$(go.Node, "Auto", commonStyle(),
|
|
new go.Binding("width", "diameter"),
|
|
new go.Binding("height", "diameter"),
|
|
$(go.Shape,
|
|
{ figure: "Circle", fill: "#1F4963", strokeWidth: 0, spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight },
|
|
new go.Binding("fill")),
|
|
$(go.TextBlock,
|
|
{ font: "12px Helvetica, Arial, sans-serif", stroke: "white", maxLines: 1 },
|
|
new go.Binding("text"),
|
|
new go.Binding("font"),
|
|
new go.Binding("stroke", "fill", function(f) { return go.Brush.isDark(f) ? "white" : "black"; }))
|
|
);
|
|
|
|
myDiagram.groupTemplate =
|
|
$(go.Group, commonStyle(),
|
|
{ layout: $(HierarchyLayout) }, // defined above
|
|
$(go.Shape, "Circle",
|
|
{ fill: "rgba(128,128,128,0.33)" },
|
|
new go.Binding("desiredSize", "size"),
|
|
new go.Binding("position")),
|
|
$(go.Placeholder) // represents area for all member parts
|
|
);
|
|
|
|
// Collect all of the data for the model of the class hierarchy
|
|
var nodeDataArray = [
|
|
{ key: "GoJS", text: "GoJS", children: [] },
|
|
// large label to be placed at the very end
|
|
{
|
|
key: "GoJS label",
|
|
group: "GoJS",
|
|
text: "GoJS",
|
|
tooltip: "GoJS",
|
|
fill: null,
|
|
font: "64px Helvetica, bold Arial, sans-serif",
|
|
isLabel: true,
|
|
children: []
|
|
}
|
|
];
|
|
|
|
var keyToNodeDataMap = new go.Map();
|
|
keyToNodeDataMap.add("GoJS", nodeDataArray[0]);
|
|
|
|
// Iterate over all of the classes in "go"
|
|
for (var k in go) {
|
|
var cls = go[k];
|
|
if (!cls) continue;
|
|
var proto = cls.prototype;
|
|
if (!proto) continue;
|
|
proto.constructor.className = k; // remember name
|
|
|
|
var propCount = 0; // count number of properties on the class
|
|
for (var prop in proto) {
|
|
if (proto.hasOwnProperty(prop)) {
|
|
propCount++;
|
|
}
|
|
}
|
|
|
|
var data = { key: k, text: k, propCount: propCount, children: [] };
|
|
if (keyToNodeDataMap.has(k)) {
|
|
data.children = keyToNodeDataMap.get(k).children;
|
|
}
|
|
keyToNodeDataMap.add(k, data); // will replace existing key if there is one
|
|
|
|
// find base class constructor
|
|
var base = Object.getPrototypeOf(proto).constructor;
|
|
if (base === Object) { // "root" node?
|
|
data.group = "GoJS";
|
|
keyToNodeDataMap.get("GoJS").children.push(data);
|
|
nodeDataArray.push(data);
|
|
} else {
|
|
// add a node for this class and set its group to its parent
|
|
data.group = base.className;
|
|
if (keyToNodeDataMap.has(base.className)) {
|
|
keyToNodeDataMap.get(base.className).children.push(data);
|
|
} else {
|
|
keyToNodeDataMap.add(base.className, {children: [data]});
|
|
}
|
|
|
|
nodeDataArray.push(data);
|
|
}
|
|
}
|
|
|
|
// create groups and add labels to groups with only 1 child
|
|
for (var i = nodeDataArray.length - 1; i >= 0; i--) {
|
|
var n = nodeDataArray[i];
|
|
if (n.children.length > 0) {
|
|
n.isGroup = true;
|
|
}
|
|
|
|
// add tooltip and/or size node using the total number of properties it has and has inherited
|
|
var totalCount = n.propCount;
|
|
var parentKey = n.group;
|
|
var parentData;
|
|
while ((parentData = keyToNodeDataMap.get(parentKey)) !== null && parentData.propCount !== undefined) {
|
|
totalCount += parentData.propCount;
|
|
parentKey = parentData.group;
|
|
}
|
|
|
|
if (totalCount === undefined) { // applies to the root GoJS group only
|
|
n.tooltip = n.text;
|
|
} else {
|
|
n.tooltip = n.text + ": " + totalCount; // add tooltip
|
|
}
|
|
if (!n.isGroup && !n.isLabel) { // only set size of node if it is not a group
|
|
// calculate size by scaling totalCount logarithmically to produce more visually appealing results
|
|
n.diameter = 20 * Math.log(0.5 * (totalCount + 5.5));
|
|
}
|
|
|
|
// add label to groups that only have one child
|
|
if (n.children.length === 1) {
|
|
nodeDataArray.push({
|
|
text: n.text,
|
|
tooltip: n.tooltip,
|
|
group: n.key,
|
|
fill: null,
|
|
font: "20px Helvetica, bold Arial, sans-serif"
|
|
});
|
|
}
|
|
|
|
delete n.children;
|
|
}
|
|
|
|
myDiagram.model = new go.GraphLinksModel(nodeDataArray);
|
|
});
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="init()">
|
|
<div id="sample">
|
|
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:700px"></div>
|
|
<p>
|
|
Circle packing can be a useful way to visualize hierarchical data, as demonstrated here
|
|
with a visualization of the class hierarchy of the GoJS library. This layout is performed
|
|
automatically by the <a href="../extensions/PackedLayout.html">PackedLayout</a> extension. Nodes
|
|
are sized according to how many properties their corresponding class has, or has inherited.
|
|
As a result, larger nodes generally represent more complex classes. Mouse over nodes to see
|
|
their full name and the number of properties on their corresponding class.
|
|
</p>
|
|
<p>
|
|
This sample is very similar to the <a href="../samples/classHierarchy.html" target="_blank">Class Hierarchy</a> sample,
|
|
except that instead of showing the class hierarchy as a tree, it is displayed using nested circles.
|
|
Opening the API page is achieved by double-clicking on a node, rather than using a "HyperlinkText".
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html> |