d3實現二維曲線顏色漸變,高斯算法的曲線,彩色是前7條線合成效果。
效果截圖:javascript
代碼實現:html
<!DOCTYPE html> <meta charset="utf-8"> <style> body { margin: auto; width: 960px; } text { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .x.axis path { } .line { fill: none; stroke: url(#temperature-gradient); stroke-width: 1.5px; } .line2 { fill: none; stroke: #000000; stroke-width: 1.5px; } </style> <body> <script src="d3.v3.min.js" type="text/javascript"></script> < script type="text/javascript"> var margin = {top: 20, right: 20, bottom: 30, left: 50}, width = 500 - margin.left - margin.right, height = 300 - margin.top - margin.bottom; var x = d3.scale.linear() .range([0, width]) .domain([-10, 10]); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .interpolate("basis") .x(function(d) { return x(d.x); }) .y(function(d) { return y(d.y); }); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.on('contextmenu', function(data, index) { if (d3.event.pageX || d3.event.pageY) { var x = d3.event.pageX; var y = d3.event.pageY; } else if (d3.event.clientX || d3.event.clientY) { var x = d3.event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; var y = d3.event.clientY + document.body.scrollTop + document.documentElement.scrollTop; } d3.select('#action_div') .style('position', 'absolute') .style('left', x + 'px') .style('top', y + 'px') .style('display', 'block'); d3.event.preventDefault(); }) /d3.tsv("data.tsv", function(error, data2) {//excel打開.tsv文件 var data = new Array(); data[0] = gaussian(0.584542144,3.000837279,0.695708794); data[1] = gaussian(0.584542144,3.000837279,0.695708794); data[2] = gaussian(0.312024052,-3.024075067,0.597481057); data[3] = gaussian(0.369684397,2.007799182,0.77623234); data[4] = gaussian(0.078860455,0.000666388,0.560802636); data[5] = gaussian(0.396895767,1.024743113,0.627726103); data[6] = gaussian(0.620582259,1.007756722,0.308801211); data[7] = gaussian(0.435481848,0.500768716,0.993654477); var g8 = []; for(var i=0;i<data[0].length;i++){ var yCalc = 0; for (var j = 0; j < data.length; j++) { yCalc += data[j][i].y; } g8.push({x:data[0][i].x, y: yCalc}) } //console.log(g8); data[8] = g8;//合成的彩色曲線 //y.domain([0,5]); y.domain(d3.extent(data[data.length - 1], function(d) { return d.y; })); svg.append("linearGradient") .attr("id", "temperature-gradient") .attr("gradientUnits", "userSpaceOnUse") .attr("x1", 0).attr("y1", y(0)) .attr("x2", 0).attr("y2", y(1.5)) .selectAll("stop") .data(getOffset()) .enter().append("stop") .attr("offset", function(d) { return d.offset; }) .attr("stop-color", function(d) { return d.color; }); function getOffset(){ var os = new Array(); var max = 100; os[0] = {offset:"0%", color: getColor(0)}; for(var i = 1; i < max; i++){ os[2 * i -1] = { offset: (i/max*100) + '%', color: getColor(i/max) }; os[2 * i] = { offset: (i/max*100) + '%', color: getColor(i/max) }; } os[199] = {offset:"100%", color: getColor(1)}; return os; } //x,y axis 兩個座標軸 svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) for (var i = 0; i < data.length; i ++) { if (i < data.length - 1) { svg.append("path") .datum(data[i]) .attr("class", "line2") .attr("width","1000") .attr("height","1000") .attr("d", line); } else { svg.append("path") .datum(data[i]) .attr("class", "line") .attr("d", line); } } }); var c_r = 0; var c_g = 0; var c_b = 0; function getColor(step) { if (step < 0.25) { c_r = 0; c_g = 4 * step; c_b = 1; } else if (step < 0.5) { c_r = 0; c_g = 1; c_b = 1 - 4 * (step - 0.25); } else if (step < 0.75) { c_r = 4 * (step - 0.5); c_g = 1; c_b = 0; } else if (step <= 1) { c_r = 1; c_g = 1 - 4 * (step - 0.75); c_b = 0; } var R = Math.round(c_r * 255 + 0.0); var G = Math.round(c_g * 255 + 0.0); var B = Math.round(c_b * 255 + 0.0); var c = "rgb(" + R + ", " + G + ", " + B + ")"; c_r = 0; c_g = 0; c_b = 0; return c; } //math gaussian function高斯算法 function gaussian(h,X0,c){ var object = new Array(); var dataPoints = 500; var xRange = 20; for (var i = 0; i <dataPoints; i++) { //i控制x axis的範圍 var offset = 10; var xCalc = parseFloat(i)/(dataPoints / xRange) - offset; object.push({x: xCalc, y: h * Math.pow(Math.E, -((xCalc-X0) * (xCalc-X0) / (2*c*c)))}); } return object; } </script>