You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by GitBox <gi...@apache.org> on 2018/12/24 16:28:19 UTC

[GitHub] wu-sheng closed pull request #212: Update: update traceTree

wu-sheng closed pull request #212: Update: update traceTree
URL: https://github.com/apache/incubator-skywalking-ui/pull/212
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/package.json b/package.json
index d080282..ea3d263 100755
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
     "cytoscape-cose-bilkent": "^4.0.0",
     "cytoscape-dagre": "^2.2.1",
     "d3": "^5.7.0",
+    "d3-tip": "^0.9.1",
     "dva": "^2.2.3",
     "dva-loading": "^2.0.3",
     "enquire-js": "^0.2.1",
diff --git a/src/components/TraceTree/d3-trace.js b/src/components/TraceTree/d3-trace.js
index 3d8a709..1645581 100644
--- a/src/components/TraceTree/d3-trace.js
+++ b/src/components/TraceTree/d3-trace.js
@@ -17,7 +17,7 @@
 
 /* eslint-disable */
 import * as d3 from 'd3';
-
+import d3tip from 'd3-tip';
 export default class TraceMap {
   constructor(el) {
     this.type = {
@@ -44,7 +44,7 @@ export default class TraceMap {
       .remove();
     this.width = this.el.clientWidth;
     this.height = this.el.clientHeight;
-    this.draw(this.data,this.row,this.showSpanModal);
+    this.draw(this.data, this.row);
   }
   draw(data, row, showSpanModal) {
     this.showSpanModal = showSpanModal;
@@ -72,7 +72,9 @@ export default class TraceMap {
       .append('svg')
       .attr('width', this.width)
       .attr('height', this.height);
-    this.timeGroup = this.body.append('g').attr('transform', d => 'translate(5,30)');
+    this.timeGroup = this.body
+      .append('g')
+      .attr('transform', d => 'translate(5,30)');
     const main = this.body
       .append('g')
       .attr('transform', d => 'translate(0,' + this.row.length * 9 + ')');
@@ -84,155 +86,188 @@ export default class TraceMap {
       .append('g')
       .attr('transform', `translate(5,20)`)
       .call(this.xAxis);
+
+    this.updatexAxis(this.root);
     this.update(this.root);
   }
-  update(source) {
+  updatexAxis(source) {
     const treeData = this.treemap(this.root);
     const nodes = treeData.descendants(),
       links = treeData.descendants().slice(1);
     let index = -1;
     nodes.forEach(function(d) {
       d.y = d.depth * 200;
-      d.timeX = ++index * 7;
-    });
-
-    this.body.call(this.getZoomBehavior(this.svg));
-
-    const node = this.svg.selectAll('g.node').data(nodes, d => {
-      return d.id || (d.id = ++this.i);
+      d.timeX = ++index * 12;
     });
+    // time
     const timeNode = this.timeGroup.selectAll('g.time').data(nodes, d => {
-      return d.id || (d.id = ++this.j);
+      return d.id;
     });
+    this.timeTip = d3tip()
+      .attr('class', 'd3-tip')
+      .offset([-10, 0])
+      .html(function(d) {
+        return d.data.label;
+      });
+    this.body.call(this.timeTip);
 
-    // time
+    const that = this;
     const timeEnter = timeNode
       .enter()
       .append('g')
       .attr('class', 'time')
-      .attr('transform', d => 'translate(' + 0 + ',' + d.timeX + ')');
+      .attr('transform', d => 'translate(' + 0 + ',' + d.timeX + ')')
+      .on('mouseover', function(d, i) {
+        that.timeTip.show(d, that.timeUpdate._groups[0][i].children[1]);
+        that.tip.show(d, that.nodeUpdate._groups[0][i]);
+      })
+      .on('mouseout', function(d, i) {
+        that.timeTip.hide(d, that.timeUpdate._groups[0][i].children[1]);
+        that.tip.hide(d, that.nodeUpdate._groups[0][i]);
+      })
+      .on('click', (d, i) => {
+        this.showSpanModal(
+          d.data,
+          { width: '100%', top: -10, left: '0' },
+          d3.select(that.timeUpdate._groups[0][i]).append('rect')
+        );
+        d3.event.stopPropagation();
+      });
+    this.timeEnter = timeEnter;
     timeEnter
       .append('rect')
-      .attr('height', 5)
+      .attr('height', 10)
+      .attr('width', this.width)
+      .attr('y', -4)
+      .attr('class', 'time-bg');
+    timeEnter
+      .append('rect')
+      .attr('class', 'time-inner')
+      .attr('height', 8)
       .attr('width', d => {
         if (!d.data.endTime || !d.data.startTime) return 0;
         return this.xScale(d.data.endTime - d.data.startTime) + 1;
       })
       .attr('rx', 2)
       .attr('ry', 2)
-      .attr(
-        'x',
-        d => (!d.data.endTime || !d.data.startTime ? 0 : this.xScale(d.data.startTime - this.min))
+      .attr('x', d =>
+        !d.data.endTime || !d.data.startTime
+          ? 0
+          : this.xScale(d.data.startTime - this.min)
       )
       .attr('y', -3)
-      .style('fill', d => `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}`);
-    var timeUpdate = timeEnter.merge(timeNode);
-
-    timeUpdate
+      .style(
+        'fill',
+        d =>
+          `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}`
+      );
+    this.timeUpdate = timeEnter.merge(timeNode);
+    this.timeUpdate
       .transition()
       .duration(600)
       .attr('transform', function(d) {
         return 'translate(' + 0 + ',' + d.timeX + ')';
       });
+
     const timeExit = timeNode
       .exit()
       .transition()
       .duration(600)
       .attr('transform', function(d) {
-        return 'translate(' + 0 + ',' + 8 + ')';
+        return 'translate(' + 0 + ',' + 10 + ')';
       })
       .remove();
+  }
+  update(source) {
+    const treeData = this.treemap(this.root);
+    const nodes = treeData.descendants(),
+      links = treeData.descendants().slice(1);
+    let index = -1;
+    nodes.forEach(function(d) {
+      d.y = d.depth * 200;
+      d.timeX = ++index * 10;
+    });
+    this.tip = d3tip()
+      .attr('class', 'd3-tip')
+      .offset([-10, 0])
+      .html(function(d) {
+        return d.data.label;
+      });
+
+    this.body.call(this.getZoomBehavior(this.svg));
+    this.body.call(this.tip);
+    const node = this.svg.selectAll('g.node').data(nodes, d => {
+      return d.id || (d.id = ++this.i);
+    });
     // node
+    const that = this;
     const nodeEnter = node
       .enter()
       .append('g')
       .attr('class', 'node')
       .attr('transform', function(d) {
         return 'translate(' + source.y0 + ',' + source.x0 + ')';
-      });
+      })
+      .on('mouseover', function(d, i) {
+        that.tip.show(d, this);
+        that.timeTip.show(d, that.timeUpdate._groups[0][i].children[1]);
+      })
+      .on('mouseout', function(d, i) {
+        that.tip.hide(d, this);
+        that.timeTip.hide(d, that.timeUpdate._groups[0][i].children[1]);
+      })
+    .on('click', (d, i) => {
+      this.showSpanModal(
+        d.data,
+        { width: '100%', top: -10, left: '0' },
+        d3.select(nodeEnter._groups[0][i]).append('rect')
+      );
+      d3.event.stopPropagation();
+    });
     nodeEnter
       .append('rect')
       .attr('class', 'block')
       .attr('x', '0')
-      .attr('y', '-16')
-      .attr('rx', 4)
-      .attr('ry', 4)
+      .attr('y', '-20')
       .attr('fill', d => (d.data.isError ? '#ff57221a' : '#f7f7f7'))
-      .attr('stroke', d => (d.data.isError ? '#ff5722aa' : '#e4e4e4'))
-      .on('click', (d, i) => {
-        this.showSpanModal(
-          d.data,
-          { width: '100%', top: -10, left: '0' },
-          d3.select(nodeEnter._groups[0][i]).append('rect')
-        );
-      })
-      .on('mouseenter', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 1);
-      })
-      .on('mouseleave', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 0);
-      });
-
-    const tooltip = nodeEnter
-      .append('g')
-      .attr('opacity', 0)
-      .attr('transform', function(d) {
-        return 'translate(0,-40)';
-      });
+      .attr('stroke', d => (d.data.isError ? '#ff5722aa' : '#e4e4e4'));
 
-    tooltip
+    nodeEnter
       .append('rect')
-      .attr('class', 'tooltip-box')
-      .attr('rx', 4)
-      .attr('ry', 4)
-      .attr('width', function(d) {
-        return d.data.label.length * 6 + 20;
-      });
-    tooltip
-      .append('text')
-      .attr('dy', 14)
-      .attr('fill', '#fafafa')
-      .attr('dx', 10)
-      .text(function(d) {
-        return d.data.label;
+      .attr('class', 'content')
+      .style('fill', '#fff')
+      .attr('stroke', d => {
+        console.log(d);
+        return d.data.isError ? '#ff5722aa' : '#e4e4e4';
       });
+    nodeEnter
+      .append('rect')
+      .attr('class', 'service')
+      .attr('x', '-0.5')
+      .attr('y', '-20.5')
+      .style(
+        'fill',
+        d =>
+          `${this.sequentialScale(this.list.indexOf(d.data.serviceCode))}`
+      );
     nodeEnter
       .append('text')
-      .attr('dy', -4)
-      .attr('x', 5)
+      .attr('dy', 13)
+      .attr('dx', 10)
+      .attr('stroke', '#333')
       .attr('text-anchor', function(d) {
         return 'start';
       })
       .text(function(d) {
-        return d.data.label.length > 23 ? d.data.label.slice(0, 23) : d.data.label;
-      })
-      .on('click', (d, i) => {
-        this.showSpanModal(
-          d.data,
-          { width: '100%', top: -10, left: '0' },
-          d3.select(nodeEnter._groups[0][i]).append('rect')
-        );
-        d3.event.stopPropagation();
-      })
-      .on('mouseenter', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 1);
-      })
-      .on('mouseleave', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 0);
+        return d.data.label.length > 19
+          ? d.data.label.slice(0, 19)
+          : d.data.label;
       });
 
     nodeEnter
       .append('text')
-      .attr('dy', 12)
-      .attr('x', 8)
+      .attr('dy', -7)
+      .attr('dx', 12)
       .attr('text-anchor', function(d) {
         return 'start';
       })
@@ -244,78 +279,45 @@ export default class TraceMap {
       })
       .text(function(d) {
         return d.data.layer;
-      })
-      .on('click', (d, i) => {
-        this.showSpanModal(
-          d.data,
-          { width: '100%', top: -10, left: '0' },
-          d3.select(nodeEnter._groups[0][i]).append('rect')
-        );
-        d3.event.stopPropagation();
-      })
-      .on('mouseenter', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 1);
-      })
-      .on('mouseleave', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 0);
       });
 
     nodeEnter
       .append('text')
-      .attr('dy', 12)
-      .attr('x', 70)
+      .attr('dy', -7)
+      .attr('x', 95)
+      .attr('stroke', '#333')
       .attr('text-anchor', function(d) {
         return 'start';
       })
       .text(function(d) {
-        return d.data.endTime ? d.data.endTime - d.data.startTime + ' ms' : d.data.traceId;
-      })
-      .on('click', (d, i) => {
-        this.showSpanModal(
-          d.data,
-          { width: '100%', top: -10, left: '0' },
-          d3.select(nodeEnter._groups[0][i]).append('rect')
-        );
-        d3.event.stopPropagation();
-      })
-      .on('mouseenter', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 1);
-      })
-      .on('mouseleave', function(currNode, i) {
-        d3.select(nodeEnter._groups[0][i])
-          .select('g')
-          .attr('opacity', 0);
+        return d.data.endTime
+          ? d.data.endTime - d.data.startTime + ' ms'
+          : d.data.traceId;
       });
 
     nodeEnter
       .append('circle')
       .attr('class', 'node')
       .attr('r', 4)
-      .attr('cx', '150')
+      .attr('cx', '158')
       .style('fill', function(d) {
         return d._children ? '#8543e0aa' : '#fff';
       })
       .on('click', click);
 
-    var nodeUpdate = nodeEnter.merge(node);
+    this.nodeUpdate = nodeEnter.merge(node);
 
-    nodeUpdate
+    this.nodeUpdate
       .transition()
       .duration(600)
       .attr('transform', function(d) {
         return 'translate(' + d.y + ',' + d.x + ')';
       });
 
-    nodeUpdate
+    this.nodeUpdate
       .select('circle.node')
       .attr('r', 4)
-      .attr('cx', '156')
+      .attr('cx', '158')
       .style('fill', function(d) {
         return d._children ? '#8543e0aa' : '#fff';
       })
@@ -373,10 +375,12 @@ export default class TraceMap {
 
     function diagonal(s, d) {
       return `M ${s.y} ${s.x}
-      L  ${d.y + 158} ${d.x}`;
+      C ${s.y - 30} ${s.x}, ${d.y + 188} ${d.x},
+      ${d.y + 158} ${d.x}`;
     }
-    const that = this;
-    function click(d) {
+    function click(d, i) {
+      that.tip.hide(d, this);
+      that.timeTip.hide(d, that.timeUpdate._groups[0][i]);
       if (d.children) {
         d._children = d.children;
         d.children = null;
@@ -384,7 +388,9 @@ export default class TraceMap {
         d.children = d._children;
         d._children = null;
       }
+      that.updatexAxis(d);
       that.update(d);
+      d3.event.stopPropagation();
     }
   }
   getZoomBehavior(g) {
@@ -394,7 +400,9 @@ export default class TraceMap {
       .on('zoom', () => {
         g.attr(
           'transform',
-          `translate(${d3.event.transform.x},${d3.event.transform.y})scale(${d3.event.transform.k})`
+          `translate(${d3.event.transform.x},${d3.event.transform.y})scale(${
+            d3.event.transform.k
+          })`
         );
       });
   }
diff --git a/src/components/TraceTree/style.less b/src/components/TraceTree/style.less
index 28f95a8..90093ff 100644
--- a/src/components/TraceTree/style.less
+++ b/src/components/TraceTree/style.less
@@ -14,30 +14,79 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
- :global(.trace-tree .node) {
+
+:global(.trace-tree) {
+  height: 1000px;
+}
+:global(.trace-tree .node) {
+  cursor: pointer;
+}
+:global(.trace-tree .node circle) {
+  stroke: #ddd;
+  stroke-width: 1.5px;
+}
+:global(.trace-tree .time-inner) {
+  cursor: pointer;
+}
+:global(.trace-tree .time-bg) {
+  fill: #fff;
   cursor: pointer;
 }
- :global(.trace-tree .node circle) {
-    stroke: #8543e0aa;
-    stroke-width: 1.5px;
+:global(.trace-tree .time:hover) {
+  :global(.time-bg){
+  fill: rgba(0, 0, 0, 0.1);
   }
+}
 :global(.trace-tree .node text) {
-    font: 12px sans-serif;
-    stroke-width: 0.5;
-  }
+  font-size: 12px;
+  font-family: 'Courier New', Courier, monospace;
+  stroke-width: 0.5;
+}
 :global(.trace-tree .node .block) {
-    width: 150px;
-    height: 34px;
-  }
+  width: 158px;
+  height: 40px;
+}
+:global(.trace-tree .node .content) {
+  width: 158px;
+  height: 20px;
+}
+:global(.trace-tree .node .service) {
+  width: 7px;
+  height: 41px;
+}
 :global(.trace-tree .link) {
-    fill: none;
-    stroke: #8543e055;
-    stroke-width: 2px;
-  }
+  fill: none;
+  stroke: #ddd;
+  stroke-width: 1.5px;
+}
 :global(.trace-tree .domain) {
-    opacity: 0;
-  }
-:global(.trace-tree .tooltip-box) {
-    fill: #333;
-    height: 20px !important;
-  }
+  opacity: 0;
+}
+:global(.d3-tip) {
+  line-height: 1;
+  padding: 6px;
+  background: rgba(0, 0, 0, 0.8);
+  color: #fff;
+  border-radius: 4px;
+  font-size: 12px;
+}
+
+/* Creates a small triangle extender for the tooltip */
+:global(.d3-tip:after) {
+  box-sizing: border-box;
+  display: inline;
+  font-size: 10px;
+  width: 100%;
+  line-height: 1;
+  color: rgba(0, 0, 0, 0.8);
+  content: '\25BC';
+  position: absolute;
+  text-align: center;
+}
+
+/* Style northward tooltips specifically */
+:global(.d3-tip.n:after) {
+  margin: -2px 0 0 0;
+  top: 100%;
+  left: 0;
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services