feat: 后端全量更新 - 含所有本次需求
- 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: 新闻自动采集脚本
This commit is contained in:
+242
@@ -0,0 +1,242 @@
|
||||
<!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>
|
||||
Reference in New Issue
Block a user