我正在将Splunk数据输入D3可视化。 D3树图需要填充树图的JSON数组,以便进行预先计算。
来自Splunk的数据以表格格式返回,第一个表包含Active Directory路径(" ou =启用Firefox,ou =笔记本电脑,ou =计算机,dc =域")大小表示该OU(10)中的框数和用于确定树形图中描绘的颜色的数字等。
我在一小组数据(少于500行左右)上完美地工作,但是当我把它包含大约1500行Splunk数据(返回数据中有1500行)时,脚本会强制浏览器关闭以下是代码的适用部分。
var nodeTree = new DeviceCountsplunkRowsBuilder(myResults.data().rows, colorMap);
nodeTree.setRootNode();
nodeTree.parseOUsplunkRows();
// clear the chart
d3.select("#chart").selectAll("*").remove();
TreeMap(nodeTree.rootNode);
// OU Device Count Parser Class
//
// Description:
// Builds the TreeMap data structure from the OU device count query in Splunk
// Takes an array of rows as input E.G. SearchResults.data().rows;
function DeviceCountsplunkRowsBuilder(splunkRows, colorMap) {
this.splunkRows = splunkRows;
this.colorMap = colorMap;
// sets the root node when constructing the OUsplunkRowsMapBuilder Class
this.setRootNode = function() {
// take the first OU String and split it by comma
var ouParts = this.splunkRows[0][0].split(",");
// grab the last item in the array which is the highest level DC
this.rootNode = new Node(ouParts[ouParts.length - 1]);
};
this.parseOUsplunkRows = function() {
console.log("second length" + " " + splunkRows.length);
console.log("length" + " " + this.splunkRows.length);
for(var i = 0; i<this.splunkRows.length; i++) {
console.log("row: " + i + " " + splunkRows[i][0]);
this.splitOUString(this.splunkRows[i]);
}
};
this.splitOUString = function(ou) {
var ouParts = ou[0].split(",");
console.log("after split " + i + " " + ouParts);
// Recurse through OU String backwards from highest to lowest level
for(var i = ouParts.length - 2; i>-1; i--) {
node = new Node(ouParts[i]);
console.log("node is: " + JSON.stringify(node));
// set distinguished name
node.dName = ouParts;
// set the device count
node.devCount = parseInt(ou[1]);
// set the score
node.score = parseFloat(ou[2]);
// set name intersection
node.nameIntersect = parseInt(ou[3], 10);
// set value intersection
node.valIntersect = parseInt(ou[4], 10);
// set STIG Name
node.stigName = ou[5];
// pick the color using colorize function
node.color = colorize(this.colorMap, ou[2]);
/*
if(ou[2] > 0.8) {
node.setColor("green");
} else if(ou[2] > 0.6) {
node.setColor("yellow");
} else {
node.setColor("red");
}
*/
// If the node is at the bottom of the tree assign it a value
if(i == 0) {
// If the count isn't a number assign it a value of 0
// This fixes some of the issues with messy data
if(isNaN(ou[1])) {
node.setValue(0);
} else {
node.setValue(parseInt(ou[1], 10));
}
}
this.rootNode.addChildRecursive(ouParts[i+1], this.rootNode, node);
//console.log(node);
//console.log(i);
}
};
}
//*****************************
// Node Class
//*****************************
// Node Constructor
function Node(name) {
this.name = name;
// Add a child node
this.addChild = function(node) {
// if this is the first child construct the children array
if(!this.hasChildren()) {
this.children = new Array();
}
// only add the node as a child if it is not already a child
if(!this.childExists(node)) {
//console.log("adding node " + node.name);
this.children.push(node);
}
};
// returns true if the given node is in the list of children
// returns false if the node is not in the list of children
this.childExists = function(node) {
var inChildren = false;
for(var i = 0; i<this.children.length; i++) {
if(this.children[i].name == node.name) {
inChildren = true;
break;
}
}
return inChildren;
};
// Optionally set the size of the node
this.setValue = function(value) {
this.value = value;
};
this.setColor = function(color) {
this.color = color;
};
// Determins whether the children array has been initialized
// returns either true or false
this.hasChildren = function() {
var nodeHasChildren = true;
if (typeof this.children === 'undefined') {
nodeHasChildren = false;
}
return nodeHasChildren;
};
// returns the array of children Node objects
this.getChildren = function() {
return this.children;
};
this.getNodeByName = function(name, node) {
var theNodeYouAreLookingFor = null;
if(node.hasChildren()) {
var children = node.getChildren();
for(var i = 0; i < children.length; i++) {
if(children[i].name == name) {
//alert("Found: " + children[i].name);
theNodeYouAreLookingFor = children[i];
break;
} else {
// recursively call getNodeByName
this.getNodeByName(name, children[i]);
}
}
}
return theNodeYouAreLookingFor;
};
this.addChildRecursive = function(name, node, child) {
var success = false;
if(this.name == name) {
this.addChild(child);
} else if(node.hasChildren()) {
var children = node.getChildren();
for(var i = 0; i < children.length; i++) {
if(children[i].name == name) {
//alert("found node" + name);
success = true;
children[i].addChild(child);
console.log(children[i].name + " => " + child.name);
break;
} else {
// recursively call getNodeByName
this.addChildRecursive(name, children[i], child);
}
}
}
return success;
};
}