javascript - d3 : linearly interpolate only close-enough points

标签 javascript d3.js

假设我有一组具有相应日期的值,[{date: d1, value: v1}, ..., {date: dn, value: vn}],我'我喜欢使用 d3.js 进行可视化。只要后续测量在特定时间范围内(例如相隔不超过一周),我对 d3 在测量之间进行插值感到满意。

但是,当后续记录相距较远时,我不想让d3将它们连接起来。实现这一目标的最简单方法是什么?

最佳答案

你的问题不是很清楚:“插值”,我相信你的意思是“连接点”。

如果您为 x 轴使用时间刻度,D3 会自动为您连接点并创建一条线(SVG path 元素),而不管数据点中的时间间隔如何。但是有一种方法可以在该行中创建“间隙”:使用 line.defined() .根据 API:

If defined is specified, sets the defined accessor to the specified function or boolean and returns this line generator.

问题是,要使这种方法起作用,您必须在您不想设置的日期之间的数据集中设置给定值(比方说,null)划清界线(即不够接近的日期,正如您在问题中所说)。您可以手动或使用函数执行此操作。

这是一个有效的演示:在我的数据集中,我的数据从 10 月 7 日跳到 17 日(超过 1 周)。因此,我只是在这两者之间的任何日期(在我的演示中,16 月 16 日)创建了一个 null 值。然后,在行生成器中,该行使用 defined 跳转此 null 值:

d3.line().defined(function(d){return d.value != null;})

结果是该行从 7-Oct 跳到 17-Oct:

var data = [{date: "1-Oct-16",value: 14},
{date: "2-Oct-16",value: 33},
{date: "3-Oct-16",value: 12},
{date: "4-Oct-16",value: 43},
{date: "5-Oct-16",value: 54},
{date: "6-Oct-16",value: 71},
{date: "7-Oct-16",value: 32},
{date: "16-Oct-16",value: null},
{date: "17-Oct-16",value: 54},
{date: "18-Oct-16",value: 14},
{date: "19-Oct-16",value: 34},
{date: "20-Oct-16",value: 32},
{date: "21-Oct-16",value: 56},
{date: "22-Oct-16",value: 24},
{date: "23-Oct-16",value: 42},
{date: "24-Oct-16",value: 52},
{date: "25-Oct-16",value: 66},
{date: "26-Oct-16",value: 34},
{date: "27-Oct-16",value: 62},
{date: "28-Oct-16",value: 48},
{date: "29-Oct-16",value: 51},
{date: "30-Oct-16",value: 42}];

var parseDate = d3.timeParse("%d-%b-%y");

data.forEach(function (d) {
    d.date = parseDate(d.date);
});

var svg = d3.select("body")
    .append("svg")
    .attr("width", 500)
    .attr("height", 200);
		
var xScale = d3.scaleTime().range([20, 480]);
var yScale = d3.scaleLinear().range([180, 10]);

xScale.domain(d3.extent(data, function (d) {
    return d.date;
    }));
yScale.domain([0, d3.max(data, function (d) {
    return d.value;
    })]);

var xAxis = d3.axisBottom(xScale).tickFormat(d3.timeFormat("%d"));

var yAxis = d3.axisLeft(yScale);

var baseline = d3.line()
	  .defined(function(d){return d.value != null;})
    .x(function (d) {
      return xScale(d.date);
    })
    .y(function (d) {
      return yScale(d.value);
    });
		
svg.append("path") // Add the valueline path.
.attr("d", baseline(data))
.attr("fill", "none")
.attr("stroke", "teal");

svg.append("g")
    .attr("transform", "translate(0,180)")
    .call(xAxis);

svg.append("g")
.attr("transform", "translate(20,0)")
.attr("class", "y axis")
    .call(yAxis);
<script src="https://d3js.org/d3.v4.min.js"></script>

关于javascript - d3 : linearly interpolate only close-enough points,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39748271/

相关文章:

javascript - 为什么我的 Angular 拦截器没有正确缩小?

javascript - 更改 <svg> 对象路径的笔划不透明度

javascript - 如何为 d3 可折叠树中的节点分配唯一的 id

javascript - 如何使用D3对 Angular 函数绘制曲线?

javascript - 如何避免在非 IE 浏览器中使用 pushState 和 $.ajax(hash) 进行双重提交?

javascript - 仅从特定页面重定向页面

javascript - 使用 Click 或 Escape 键调用 setState

javascript - 使用 JS 查找和比较顺序 div

d3.js - d3 v4 分组条形图 - .data(fn).enter() 为空

javascript - 如何循环遍历数组以将 html 分配给工具提示