You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@edgent.apache.org by qu...@apache.org on 2016/09/29 23:08:28 UTC
incubator-edgent git commit: [EDGENT-179] Console: Adjust oplet
coloring
Repository: incubator-edgent
Updated Branches:
refs/heads/master b0d44b587 -> f05ca87d4
[EDGENT-179] Console: Adjust oplet coloring
Project: http://git-wip-us.apache.org/repos/asf/incubator-edgent/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-edgent/commit/f05ca87d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-edgent/tree/f05ca87d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-edgent/diff/f05ca87d
Branch: refs/heads/master
Commit: f05ca87d40ac8b51dd931882b789dc4b824e5330
Parents: b0d44b5
Author: Queenie Ma <qu...@gmail.com>
Authored: Tue Sep 27 08:44:20 2016 -0700
Committer: Queenie Ma <qu...@gmail.com>
Committed: Thu Sep 29 08:51:47 2016 -0700
----------------------------------------------------------------------
console/servlets/webapp_content/js/graph.js | 34 +++-
console/servlets/webapp_content/js/index.js | 248 ++++++++++++++++++++++-
2 files changed, 270 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/f05ca87d/console/servlets/webapp_content/js/graph.js
----------------------------------------------------------------------
diff --git a/console/servlets/webapp_content/js/graph.js b/console/servlets/webapp_content/js/graph.js
index e279b91..538a892 100644
--- a/console/servlets/webapp_content/js/graph.js
+++ b/console/servlets/webapp_content/js/graph.js
@@ -16,15 +16,31 @@ KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
-opletColor = {"org.apache.edgent.streamscope.oplets.StreamScope": "#c7c7c7",
- "org.apache.edgent.metrics.oplets.CounterOp": "#c7c7c7", "org.apache.edgent.metrics.oplets.RateMeter": "#aec7e8", "org.apache.edgent.oplet.core.FanIn": "#ff7f0e",
- "org.apache.edgent.oplet.core.FanOut": "#ffbb78", "org.apache.edgent.oplet.core.Peek": "#2ca02c", "org.apache.edgent.oplet.core.PeriodicSource": "#98df8a",
- "org.apache.edgent.oplet.core.Pipe": "#d62728", "org.apache.edgent.oplet.core.PipeWindow": "#ff9896", "org.apache.edgent.oplet.core.ProcessSource": "#9467bd",
- "org.apache.edgent.oplet.core.Sink": "#c5b0d5", "org.apache.edgent.oplet.core.Source": "#8c564b", "org.apache.edgent.oplet.core.Split": "#c49c94", "org.apache.edgent.oplet.core.Union" : "#1f77b4",
- "org.apache.edgent.oplet.functional.ConsumerEventSource": "#e377c2", "org.apache.edgent.oplet.functional.ConsumerPeek": "#f7b6d2", "org.apache.edgent.oplet.functional.ConsumerSink": "#7f7f7f",
- "org.apache.edgent.oplet.functional.Filter": "#7F7F7F", "org.apache.edgent.oplet.functional.FlatMapper": "#bcbd22", "org.apache.edgent.oplet.functional.Isolate": "#dbdb8d",
- "org.apache.edgent.oplet.functional.Map": "#17becf", "org.apache.edgent.oplet.functional.SupplierPeriodicSource": "#9edae5", "org.apache.edgent.oplet.functional.SupplierSource": "#b5cf6b",
- "org.apache.edgent.oplet.plumbing.PressureReliever": "#e7cb94", "org.apache.edgent.oplet.plumbing.TextFileReader": "#ad494a", "org.apache.edgent.oplet.plumbing.UnorderedIsolate": "#de9ed6"};
+opletColor = {
+ "org.apache.edgent.metrics.oplets.CounterOp": "#c7c7c7",
+ "org.apache.edgent.metrics.oplets.RateMeter": "#1f77b4",
+ "org.apache.edgent.oplet.core.FanIn": "#aec7e8",
+ "org.apache.edgent.oplet.core.FanOut": "#ff7f0e",
+ "org.apache.edgent.oplet.core.Peek": "#ffbb78",
+ "org.apache.edgent.oplet.core.PeriodicSource": "#bcbd22",
+ "org.apache.edgent.oplet.core.Pipe": "#98df8a",
+ "org.apache.edgent.oplet.core.ProcessSource": "#d62728",
+ "org.apache.edgent.oplet.core.Sink": "#ff9896",
+ "org.apache.edgent.oplet.core.Source": "#9467bd",
+ "org.apache.edgent.oplet.core.Split": "#c5b0d5",
+ "org.apache.edgent.oplet.core.Union": "#c49c94",
+ "org.apache.edgent.oplet.functional.Filter": "#e377c2",
+ "org.apache.edgent.oplet.functional.Isolate": "#f7b6d2",
+ "org.apache.edgent.oplet.functional.Map": "#f2d979",
+ "org.apache.edgent.oplet.functional.Peek": "#dbdb8d",
+ "org.apache.edgent.oplet.functional.SupplierPeriodicSource": "#17becf",
+ "org.apache.edgent.oplet.functional.SupplierSource": "#9edae5",
+ "org.apache.edgent.oplet.plumbing.Isolate": "#79a7f2",
+ "org.apache.edgent.oplet.plumbing.PressureReliever": "#2ca02c",
+ "org.apache.edgent.oplet.plumbing.TextFileReader": "#c0f279",
+ "org.apache.edgent.oplet.plumbing.UnorderedIsolate": "#e279f2",
+ "org.apache.edgent.streamscope.oplets.StreamScope": "#c7c7c7"
+};
colorMap = {};
addValuesToEdges = function(graph, counterMetrics) {
http://git-wip-us.apache.org/repos/asf/incubator-edgent/blob/f05ca87d/console/servlets/webapp_content/js/index.js
----------------------------------------------------------------------
diff --git a/console/servlets/webapp_content/js/index.js b/console/servlets/webapp_content/js/index.js
index 1a4bb7d..5cc3565 100644
--- a/console/servlets/webapp_content/js/index.js
+++ b/console/servlets/webapp_content/js/index.js
@@ -766,6 +766,204 @@ var makeRows = function() {
return theRows;
};
+// Convert HSV to RGB
+var hsvToRGB = function(h, s, v) {
+ var r, g, b, i, f, p, q, t;
+ if (arguments.length === 1) {
+ s = h.s, v = h.v, h = h.h;
+ }
+ i = Math.floor(h * 6);
+ f = h * 6 - i;
+ p = v * (1 - s);
+ q = v * (1 - f * s);
+ t = v * (1 - (1 - f) * s);
+ switch (i % 6) {
+ case 0:
+ r = v, g = t, b = p;
+ break;
+ case 1:
+ r = q, g = v, b = p;
+ break;
+ case 2:
+ r = p, g = v, b = t;
+ break;
+ case 3:
+ r = p, g = q, b = v;
+ break;
+ case 4:
+ r = t, g = p, b = v;
+ break;
+ case 5:
+ r = v, g = p, b = q;
+ break;
+ }
+ return {
+ r: Math.round(r * 255),
+ g: Math.round(g * 255),
+ b: Math.round(b * 255)
+ };
+};
+
+var componentToHex = function(c) {
+ var hex = c.toString(16);
+ return hex.length == 1 ? "0" + hex : hex;
+};
+
+// Convert RGB to Hex
+var rgbToHex = function(r, g, b) {
+ return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
+};
+
+// Convert Hex to RGB
+var hexToRGB = function(hex) {
+ var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+ return result ? {
+ r: parseInt(result[1], 16),
+ g: parseInt(result[2], 16),
+ b: parseInt(result[3], 16)
+ } : null;
+};
+
+// Convert RGB to XYZ
+var rgbToXYZ = function(r, g, b) {
+ var _r = (r / 255);
+ var _g = (g / 255);
+ var _b = (b / 255);
+
+ if (_r > 0.04045) {
+ _r = Math.pow(((_r + 0.055) / 1.055), 2.4);
+ } else {
+ _r = _r / 12.92;
+ }
+
+ if (_g > 0.04045) {
+ _g = Math.pow(((_g + 0.055) / 1.055), 2.4);
+ } else {
+ _g = _g / 12.92;
+ }
+
+ if (_b > 0.04045) {
+ _b = Math.pow(((_b + 0.055) / 1.055), 2.4);
+ } else {
+ _b = _b / 12.92;
+ }
+
+ _r = _r * 100;
+ _g = _g * 100;
+ _b = _b * 100;
+
+ var X = _r * 0.4124 + _g * 0.3576 + _b * 0.1805;
+ var Y = _r * 0.2126 + _g * 0.7152 + _b * 0.0722;
+ var Z = _r * 0.0193 + _g * 0.1192 + _b * 0.9505;
+
+ return [X, Y, Z];
+};
+
+// Convert XYZ to LAB
+var xyzToLAB = function(x, y, z) {
+ var ref_X = 95.047;
+ var ref_Y = 100.000;
+ var ref_Z = 108.883;
+
+ var _X = x / ref_X;
+ var _Y = y / ref_Y;
+ var _Z = z / ref_Z;
+
+ if (_X > 0.008856) {
+ _X = Math.pow(_X, (1 / 3));
+ } else {
+ _X = (7.787 * _X) + (16 / 116);
+ }
+
+ if (_Y > 0.008856) {
+ _Y = Math.pow(_Y, (1 / 3));
+ } else {
+ _Y = (7.787 * _Y) + (16 / 116);
+ }
+
+ if (_Z > 0.008856) {
+ _Z = Math.pow(_Z, (1 / 3));
+ } else {
+ _Z = (7.787 * _Z) + (16 / 116);
+ }
+
+ var CIE_L = (116 * _Y) - 16;
+ var CIE_a = 500 * (_X - _Y);
+ var CIE_b = 200 * (_Y - _Z);
+
+ return [CIE_L, CIE_a, CIE_b];
+};
+
+// Compute Delta E using CIE94
+var getDeltaE = function(x, y, isTextiles) {
+ var x = {
+ l: x[0],
+ a: x[1],
+ b: x[2]
+ };
+ var y = {
+ l: y[0],
+ a: y[1],
+ b: y[2]
+ };
+ labx = x;
+ laby = y;
+ var k2;
+ var k1;
+ var kl;
+ var kh = 1;
+ var kc = 1;
+ if (isTextiles) {
+ k2 = 0.014;
+ k1 = 0.048;
+ kl = 2;
+ } else {
+ k2 = 0.015;
+ k1 = 0.045;
+ kl = 1;
+ }
+
+ var c1 = Math.sqrt(x.a * x.a + x.b * x.b);
+ var c2 = Math.sqrt(y.a * y.a + y.b * y.b);
+
+ var sh = 1 + k2 * c1;
+ var sc = 1 + k1 * c1;
+ var sl = 1;
+
+ var da = x.a - y.a;
+ var db = x.b - y.b;
+ var dc = c1 - c2;
+
+ var dl = x.l - y.l;
+ var dh = Math.sqrt(da * da + db * db - dc * dc);
+
+ return Math.sqrt(Math.pow((dl / (kl * sl)), 2) + Math.pow((dc / (kc * sc)), 2) + Math.pow((dh / (kh * sh)), 2));
+};
+
+// Generate a random color using the golden ratio conjugate
+var genRandomColor = function(s, v) {
+ var goldenRatioConjugate = 0.618033988749895;
+ var h = Math.random();
+ h += goldenRatioConjugate;
+ h %= 1;
+ var hsv = {
+ h: h,
+ s: s,
+ v: v
+ };
+ var rgb = hsvToRGB(hsv.h, hsv.s, hsv.v);
+ var hex = rgbToHex(rgb.r, rgb.g, rgb.b);
+ return {
+ hsv: hsv,
+ rgb: rgb,
+ hex: hex
+ };
+};
+
+var checkDeltaE = function(deltaE) {
+ return deltaE >= 15;
+};
+
vertexMap = {};
var renderGraph = function(jobId, counterMetrics, bIsNewJob) {
@@ -937,7 +1135,9 @@ var renderGraph = function(jobId, counterMetrics, bIsNewJob) {
return document.createElementNS(d3.ns.prefix.svg, 'circle');
}
});
-
+
+ var assignedOpletColors = [];
+
node.selectAll("circle")
.attr("cx", sankey.nodeWidth()/2)
.attr("cy", function(d){
@@ -950,11 +1150,53 @@ var renderGraph = function(jobId, counterMetrics, bIsNewJob) {
if (!colorMap[d.id.toString()]) {
colorMap[d.id.toString()] = color20(d.id.toString());
}
+
+ // Generate a random color that is perceptually different than all assigned colors:
+ // 1. Convert the assigned oplet colors from Hex to LAB
+ // 2. Generate a random color in the RGB color space
+ // 3. Convert RGB to XYZ
+ // 4. Convert XYZ to LAB
+ // 5. For each assigned oplet color, compute Delta E between the two LAB colors (new and assigned)
+ // 6. If Delta E >= 15, consider the color to be different enough from the other colors
if (!opletColor[d.invocation.kind]) {
- opletColor[d.invocation.kind] = color20(d.invocation.kind);
+ var assignedOpletColorsLAB = [];
+ for (var i = 0; i < assignedOpletColors.length; i++) {
+ var rgb = hexToRGB(assignedOpletColors[i]);
+ var xyz = rgbToXYZ(rgb.r, rgb.g, rgb.b);
+ var lab = xyzToLAB(xyz[0], xyz[1], xyz[2]);
+ assignedOpletColorsLAB.push(lab);
+ }
+
+ var deltaEs = [];
+ var c = null;
+ var uniqueColor = false;
+
+ while (!uniqueColor) {
+ // Use a different color scheme for non-org.apache.edgent defined oplets
+ if (d.invocation.kind.includes("org.apache.edgent")) {
+ c = genRandomColor(0.5, 0.95);
+ } else {
+ c = genRandomColor(0.99, 0.99);
+ }
+
+ var xyz = rgbToXYZ(c.rgb.r, c.rgb.g, c.rgb.b);
+ var lab = xyzToLAB(xyz[0], xyz[1], xyz[2]);
+
+ // Compare color to assigned colors and check for similarity
+ deltaEs = [];
+ for (var m = 0; m < assignedOpletColorsLAB.length; m++) {
+ deltaE = getDeltaE(lab, assignedOpletColorsLAB[m], false);
+ deltaEs.push(deltaE);
+ }
+ uniqueColor = deltaEs.every(checkDeltaE);
+ }
+
+ opletColor[d.invocation.kind] = c.hex;
}
- return getVertexFillColor(layer, d, counterMetrics);
+ var color = getVertexFillColor(layer, d, counterMetrics);
+ assignedOpletColors.push(color);
+ return color;
})
.attr("data-legend", function(d) {