С помощью вспомогательной функции interpolate мы можем добиться интерполяции точек графика, при которой рассчитываются промежуточные переходы между двумя соседними точками. Эта функция в качестве параметра одной из следующих значений:
basis
: образует b-сплайн с дублированием контрольных точек на концах отрезков
basis-open
: образует открытый b-сплайн
basis-closed
: образует закрытый b-сплайн
cardinal
: образует cardinal-сплайн с дублированием контрольных точек на концах отрезков
cardinal-open
: образует открытый cardinal-сплайн
cardinal-closed
: образует закрытый cardinal-сплайн
linear
: идентичен стандартному графику, где точки соединены линиями
linear-closed
: сегменты линий образуют замкнутые многоугольники
monotone
: кубическая интерполяция
step-before
: пошаговая интерполяция между вертикальными и горизонтальными сегментами
step-after
: пошаговая интерполяция между горизонтальными и вертикальными сегментами
Используем параметр "basis":
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://d3js.org/d3.v3.min.js"> </script> <style> .axis path, .axis line { fill: none; stroke: #333; } .axis .grid-line { stroke: #000; stroke-opacity: 0.2; } .axis text { font: 10px Verdana; } </style> <body> <script type="text/javascript"> var height = 500, width = 500, margin=30, rawData = [{x: 0, y: 55}, {x: 10, y: 67}, {x: 20, y: 74},{x: 30, y: 63}, {x: 40, y: 56}, {x: 50, y: 24}, {x: 60, y: 26}, {x: 70, y: 19}, {x: 80, y: 42}, {x: 90, y: 88}, {x: 100, y: 80} ], data=[]; var svg = d3.select("body").append("svg") .attr("class", "axis") .attr("width", width) .attr("height", height); var xAxisLength = width - 2 * margin; var yAxisLength = height - 2 * margin; var scaleX = d3.scale.linear() .domain([0, 100]) .range([0, xAxisLength]); var scaleY = d3.scale.linear() .domain([100, 0]) .range([0, yAxisLength]); for(i=0; i<rawData.length; i++) data.push({x: scaleX(rawData[i].x)+margin, y: scaleY(rawData[i].y) + margin}); var xAxis = d3.svg.axis() .scale(scaleX) .orient("bottom"); var yAxis = d3.svg.axis() .scale(scaleY) .orient("left"); svg.append("g") .attr("class", "x-axis") .attr("transform", "translate(" + margin + "," + (height - margin) + ")") .call(xAxis); svg.append("g") .attr("class", "y-axis") .attr("transform", "translate(" + margin + "," + margin + ")") .call(yAxis); d3.selectAll("g.x-axis g.tick") .append("line") .classed("grid-line", true) .attr("x1", 0) .attr("y1", 0) .attr("x2", 0) .attr("y2", - (height - 2 * margin)); d3.selectAll("g.y-axis g.tick") .append("line") .classed("grid-line", true) .attr("x1", 0) .attr("y1", 0) .attr("x2", xAxisLength) .attr("y2", 0); var line = d3.svg.line().interpolate("basis") .x(function(d){return d.x;}) .y(function(d){return d.y;}); var area = d3.svg.area().interpolate("basis") .x(function(d) { return d.x; }) .y0(height - margin) .y1(function(d) { return d.y; }); var g = svg.append("g"); g.append("path") .attr("d", area(data)) .style("fill", "lightblue"); g.append("path") .attr("d", line(data)) .style("stroke", "steelblue") .style("stroke-width", 2); </script> </body> </html>
Причем интерполяцию графика мы можем применять как к набору линий d3.svg.line().interpolate("basis")
,
так и к набору областей, если они используются: d3.svg.area().interpolate("basis")
Если мы используем другой параметр, то визуализация графика будет отличаться. Например, параметр "step-after":