2016-11-21 7 views
6

मैं x और y अक्ष के साथ d3.js .v4 ग्राफ पर काम कर रहा हूं और मुझे आपकी मदद चाहिए।d3.js कस्टम वक्र चरण दौर

विवरण:

xAxis रैखिक इस छवि की तरह उस पर पथ के साथ बढ़ाया है। round corner on d3.curveStep

मैं यहाँ अटक कर रहा हूँ और इस छवि path with rounded corner

पर की तरह पथ बनाने के लिए समाधान नहीं मिल सकता है इस लाइन समारोह के लिए अपने कोड

// the path generator for the line chart 
 
line = d3.line() 
 
    .x(function(d, i) { 
 
    return xScale(i); 
 
    }) 
 
    .y(function(d, i) { 
 
    return yScale(d); 
 
    }) 
 
    .curve(d3.curveStep);

मैंने कोशिश की है कार्डिनल, मोनोटोन और कैटमुल बुथ के साथ वांछित पथ संग्रहित नहीं कर सकते हैं।

क्या d3.curveStep पर कोनों को गोल करना संभव है?

उत्तर

7

मुझे अंततः इस प्रश्न पर वापसी के लिए कुछ समय मिला। custom curve को लागू करने का यह एक शानदार अवसर है। मैंने अनिवार्य रूप से स्रोत कोड को d3.curveStepBefore पर चुरा लिया और अपनी आवश्यकताओं के अनुरूप संशोधित किया।

function Step(context, t) { 
 
    this._context = context; 
 
    this._t = t; 
 
} 
 

 
Step.prototype = { 
 
    areaStart: function() { 
 
    this._line = 0; 
 
    }, 
 
    areaEnd: function() { 
 
    this._line = NaN; 
 
    }, 
 
    lineStart: function() { 
 
    this._x = this._y = NaN; 
 
    this._point = 0; 
 
    }, 
 
    lineEnd: function() { 
 
    if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); 
 
    if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); 
 
    if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; 
 
    }, 
 
    point: function(x, y) { 
 
    x = +x, y = +y; 
 
    switch (this._point) { 
 
     case 0: 
 
     case 0: 
 
     this._point = 1; 
 
     this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); 
 
     break; 
 
     case 1: 
 
     this._point = 2; // proceed 
 
     default: 
 
     { 
 
      var xN, yN, mYb, mYa; 
 
      if (this._t <= 0) { 
 
      xN = Math.abs(x - this._x) * 0.25; 
 
      yN = Math.abs(y - this._y) * 0.25; 
 
      mYb = (this._y < y) ? this._y + yN : this._y - yN; 
 
      mYa = (this._y > y) ? y + yN : y - yN; 
 

 
      this._context.quadraticCurveTo(this._x, this._y, this._x, mYb); 
 
      this._context.lineTo(this._x, mYa); 
 
      this._context.quadraticCurveTo(this._x, y, this._x + xN, y); 
 
      this._context.lineTo(x - xN, y); 
 

 
      } else { 
 
      var x1 = this._x * (1 - this._t) + x * this._t; 
 

 
      xN = Math.abs(x - x1) * 0.25; 
 
      yN = Math.abs(y - this._y) * 0.25; 
 
      mYb = (this._y < y) ? this._y + yN : this._y - yN; 
 
      mYa = (this._y > y) ? y + yN : y - yN; 
 

 
      this._context.quadraticCurveTo(x1, this._y, x1, mYb); 
 
      this._context.lineTo(x1, mYa); 
 
      this._context.quadraticCurveTo(x1, y, x1 + xN, y); 
 
      this._context.lineTo(x - xN, y); 
 
      } 
 
      break; 
 
     } 
 
    } 
 
    this._x = x, this._y = y; 
 
    } 
 
}; 
 

 
stepRound = function(context) { 
 
    return new Step(context, 0.5); 
 
}; 
 

 
stepRoundBefore = function(context) { 
 
    return new Step(context, 0); 
 
}; 
 

 
stepRoundAfter = function(context) { 
 
    return new Step(context, 1); 
 
};
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    document.addEventListener("DOMContentLoaded", function(event) { 
 

 
     var width = 500, 
 
     height = 500, 
 
     N = 10; 
 

 
     var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width', width) 
 
     .attr('height', height); 
 

 
     var points = []; 
 
     for (var i = 0; i < N; i++) { 
 
     points.push({ 
 
      x: (width/N) * i + (width/N/2), 
 
      y: Math.random() * height 
 
     }); 
 
     } 
 

 
     var line1 = d3.line() 
 
     .x(function(d) { 
 
      return d.x; 
 
     }) 
 
     .y(function(d) { 
 
      return d.y; 
 
     }) 
 
     .curve(stepRound); 
 

 
     var line2 = d3.line() 
 
     .x(function(d) { 
 
      return d.x; 
 
     }) 
 
     .y(function(d) { 
 
      return d.y; 
 
     }) 
 
     .curve(d3.curveStep); 
 

 
     svg.append('path') 
 
     .datum(points) 
 
     .attr('d', line1) 
 
     .attr('fill', 'none') 
 
     .attr('stroke', 'orange') 
 
     .attr('stroke-width', '3px'); 
 

 
     svg.append('path') 
 
     .datum(points) 
 
     .attr('d', line2) 
 
     .attr('fill', 'none') 
 
     .attr('stroke', 'steelblue') 
 
     .attr('stroke-width', '1px'); 
 

 
    }); 
 
    </script> 
 
</body> 
 

 
</html>

+0

आपके समय के लिए मार्क धन्यवाद! मुझे इसकी ही आवश्यकता थी। अब मुझे यह पता लगाने की आवश्यकता है कि इस कोड को वक्रस्टेप के लिए कैसे संपादित करें। वर्तमान वक्रस्टेप (गोलाकार) पृष्ठभूमि रेखा वाले ग्रिड के साथ गठबंधन करने के लिए मेरे लाइन पथ को धक्का दें लेकिन पथ को उस ग्रिड के बीच होना चाहिए। – stojkosd

+0

@djstojadin, अद्यतन उत्तर देखें। मैंने 'वक्रस्टेप' और 'वक्रस्टेपएटर' लागू किया। – Mark

+0

बकाया! आप पर अच्छा। –

 संबंधित मुद्दे