javascript - D3 Sunburst: Determine Leaf Color by Data and have its Parents Inherit that Color -


so new d3 visualizations , have run roadblock in learning. have pretty basic sunburst set running off data determines if test had "failure" or "success". failure or success represented outer ring of sunburst data's result.

i'm trying change outer ring's color based on success or failure. example if test result success, color green , if failure turn red. feel there way i'm overlooking.

also once color has been determined, want it's parent arcs, way innermost ring, "inherit" color , red have higher priority. if 1 group of test has failure in it, arc represents group red well.

prtg's sunburst works in manner , cant find connection between 2 implement functionality.

i'm using basic sunburst code d3's examples:

define(function(require, exports, module) { var _ = require('underscore'); var simplesplunkview = require("splunkjs/mvc/simplesplunkview");   var nester = require("../underscore-nest/underscore-nest"); var d3 = require("../d3/d3");  require("css!./sunburst.css");  window.nester = nester; var animation_duration = 750;  // milliseconds  var sunburst = simplesplunkview.extend({     moduleid: module.id,      classname: "splunk-toolkit-sunburst",       options: {         managerid: null,           data: 'preview',          charttitle: null,         valuefield: null,         categoryfields: null,         truncatevalue: 0,         formatlabel: _.identity,         formattooltip: function(d) {             return (d.name || "total") + ": " + d.value;         }     },      output_mode: "json_rows",      initialize: function() {         simplesplunkview.prototype.initialize.apply(this, arguments);          this.settings.on("change:valuefield", this.render, this);         this.settings.on("change:categoryfields", this.render, this);         this.settings.on("change:formatlabel change:formattooltip change:charttitle", this.render, this);          // set resize callback.          $(window).resize(_.debounce(_.bind(this._handleresize, this), 20));     },      _handleresize: function() {         this.render();     },      createview: function() {         // here wet initial view layout         var margin = {top: 30, right: 30, bottom: 30, left: 30};         var availablewidth = parseint(this.settings.get("width") || this.$el.width());         var availableheight = parseint(this.settings.get("height") || this.$el.height());          this.$el.html("");          var svg = d3.select(this.el)             .append("svg")             .attr("width", availablewidth)             .attr("height", availableheight)             .attr("pointer-events", "all");          // returned object gets passed updateview viz         return { container: this.$el, svg: svg, margin: margin};     },      // making data how want updateview job     formatdata: function(data) {         var valuefield = this.settings.get('valuefield');         var rawfields = this.resultsmodel.data().fields;         var fieldlist = this.settings.get("categoryfields");         if(fieldlist){             fieldlist = fieldlist.split(/[ ,]+/);         }         else{             fieldlist = this.resultsmodel.data().fields;         }         var objects = _.map(data, function(row) {             return _.object(rawfields, row);         });         var dataresults = nester.nest(objects, fieldlist, function(children) {             var total = 0;             _.each(children, function(child){                 var size = child[valuefield] || 1;                 total += size;             });             return total;         });         dataresults['name'] = this.settings.get("charttitle") || "";         data = {             'results': dataresults,             'fields': fieldlist         };         return data;     },      updateview: function(viz, data) {         var = this;         var formatlabel = this.settings.get("formatlabel") || _.identity;         var formattooltip = this.settings.get("formattooltip") || function(d) { return d.name; };         var truncatevalue = this.settings.get("truncatevalue");         var containerheight = this.$el.height();         var containerwidth = this.$el.width();           // clear svg         var svg = $(viz.svg[0]);         svg.empty();         svg.height(containerheight);         svg.width(containerwidth);          // add graph group child of main svg         var graphwidth = containerwidth - viz.margin.left - viz.margin.right;         var graphheight = containerheight - viz.margin.top - viz.margin.bottom;         var graph = viz.svg             .append("g")             .attr("width", graphwidth)             .attr("height", graphheight)             .attr("transform", "translate("                       + ((graphwidth/2) + viz.margin.left ) + ","                       + ((graphheight/2) + viz.margin.top ) + ")");          var radius = math.min(graphwidth, graphheight) / 2;          var color = d3.scale.category20().range(["#98df8a"]);          var colora = d3.scale.category20().range(["#98df8a"]);  //green         var colorb = d3.scale.category20().range(["#d62728"]);  //red         var colorc = d3.scale.category20().range(["#bcbd22"]);  //yellow          var x = d3.scale.linear()             .range([0, 2 * math.pi]);          var y = d3.scale.linear()             .range([0, radius]);          var partition = d3.layout.partition()             .value(function(d) { return d['value']; });          var arc = d3.svg.arc()             .startangle(function(d) { return math.max(0, math.min(2 * math.pi, x(d.x))); })             .endangle(function(d) { return math.max(0, math.min(2 * math.pi, x(d.x + d.dx))); })             .innerradius(function(d) { return math.max(0, y(d.y)); })             .outerradius(function(d) { return math.max(0, y(d.y + d.dy)); });          var root = data.results;          var g = graph.selectall("g")             .data(partition.nodes(root))             .enter().append("g");          var leaves = d3.selectall("rect").filter(function(d) {             return d.children === null; });          var path = g.append("path")             .attr("d", arc)             .style("fill", function(d) {return color((d.children ? d : d.parent).name); })             .on("click", click);          path.append("title")             .text(formattooltip);          var textanchorpos = function(depthmarker) {             return function(d) {                 return (d.depth === depthmarker) ? 'middle' : ((x(d.x + d.dx / 2) > math.pi) ? "end" : "start");             };         };          var texttransform = function(depthmarker) {              return function(d) {                 // objects @ origin don't need rotated                 var angle = x(d.x + d.dx / 2) * 180 / math.pi + (d.depth === depthmarker ? 0 : -90);                 // objects @ origin don't need moved.                 // "5" pads text off drawn circle.                 var translation = d.depth === depthmarker ? 0 : (y(d.y) + 5);                 var rotate = angle;                 return "rotate(" + rotate + ")translate(" + (translation) + ")rotate(" + (angle > 90 ? -180 : 0) + ")";             };         };          var text = g.append("text")             .attr("text-anchor", textanchorpos(0))             .attr("transform", texttransform(0))             .attr("dy", ".2em")             .attr("x", 0)             .text(function(d) {                 var slicewidth = math.abs(math.max(0, y(d.y)) - math.max(0, y(d.y + d.dy)));                 var formatted = formatlabel(d.name);                  // trunctate title                 return formatted.substring(0, slicewidth / truncatevalue);              })             .on("click", click);          text.append("title")             .text(formattooltip);          function click(d) {             // "at depth" object treated differently;             // centered , not rotated.             var depthmarker = d.depth;             // fade out text elements             text.transition().attr("opacity", 0);             path.transition()               .duration(animation_duration)               .attrtween("d", arctween(d))               .each("end", function(e, i) {                   // check if animated element's data e lies                   // within visible angle span given in d ,                   // element d or possible child of d                   if ((e.x >= d.x && e.x < (d.x + d.dx)) && (e.depth >= d.depth)) {                      // selection of associated text element                     var arctext = d3.select(this.parentnode).select("text");                     // fade in text element , recalculate positions                     arctext.transition().duration(animation_duration)                         .attr("opacity", 1)                         .attr("text-anchor", textanchorpos(depthmarker))                         .attr("transform", texttransform(depthmarker))                         .attr("dy", ".2em")                         .attr("x", 0);                   }               });         }          // interpolate scales!         function arctween(d) {           var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),               yd = d3.interpolate(y.domain(), [d.y, 1]),               yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);           return function(d, i) {             return                 ? function(t) { return arc(d); }                 : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };           };         }     } }); return sunburst; 

});

the coloring happens here:

var path = g.append("path")             .attr("d", arc)             .style("fill", function(d) {return color((d.children ? d : d.parent).name); })             .on("click", click); 

so might able examine test-state of element get's passed anonymous function (in style call) , return 'green' or 'red'. might quite straight forward leaves, little trickier parents. since must discover looking @ parent element if has children failed tests return 'red', else return 'green'.


Comments

Popular posts from this blog

android - Gradle sync Error:Configuration with name 'default' not found -

java - Andrioid studio start fail: Fatal error initializing 'null' -

html - jQuery UI Sortable - Remove placeholder after item is dropped -