你如何让d3js剧情在屏幕上运行

时间:2014-07-28 10:56:20

标签: d3.js

使用Mike {Bodocks} Path Transitions的示例我创建了一个折线图来显示数据,并在下方显示图标,以引起对图中元素的注意。 Here is a JSFiddle显示结果和相关代码:

[注意:为了演示我在这里附加了每个数据点的图像,这可能不是生产中的情况]

var data = [
    { "id": 0, "elevation": 90 }, 
    { "id": 1, "elevation": 73 }, 
    { "id": 2, "elevation": 70 }, 
    { "id": 3, "elevation": 59 }, 
    { "id": 4, "elevation": 63 }, 
    { "id": 5, "elevation": 65 }, 
    { "id": 6, "elevation": 61 }, 
    { "id": 7, "elevation": 59 }, 
    { "id": 8, "elevation": 60 }, 
    { "id": 9, "elevation": 62 }, 
    { "id": 10, "elevation": 64 }
];

var key = function (d) {
    return d.id;
};

var xScale = d3.scale.linear()
    .domain([0, data.length - 1])
    .range([0, settings.containerWidth - 16]);

var yScale = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.elevation; })])
    .range([settings.containerHeight, 0]);

var svg = d3.select("#animation-container")
    .append("svg")
    .attr("width", settings.containerWidth)
    .attr("height", settings.containerHeight);

var line = d3.svg.line()
    .x(function(d, i) { return xScale(i); })
    .y(function(d) { return yScale(d.elevation); })
    .interpolate("basis");

svg.append("g")
    .append("path")
    .datum(data, key)
    .attr("class", "line")
    .attr("d", line);

svg.append("g")
    .selectAll(".data-points")
    .data(data, key)
    .enter()
    .append('image')
    .attr("x", function (d, i) { return xScale(i); })
    .attr("y", settings.iconLine)
    .attr("xlink:href", "https://github.com/favicon.ico")
    .attr("width", settings.iconWidth)
    .attr("height", settings.iconHeight);

我的想法是,解决方案与使水平缩放正确有关,但我尝试了线性和序数尺度和转换的许多变化与更新基础数据,以使这项工作没有成功。

我的问题是:

  1. 如何允许图表和图标在屏幕外运行?
  2. 如何让图标彼此接触而不是它们之间的间隙
  3.   

    我的代码与Mikes excellent example不同的地方是我不想要的   我的用户将来回滚动,删除屏幕外数据。

    感谢。

    修改

    根据@LarsKotthoff建议,我将xScale的范围()修改为:

    var xScale = d3.scale.linear()
        .domain([0, data.length - 1])
        .range([0, (data.length - 1) * settings.iconWidth]);
    

    这有双重效果:

    1. 不要将范围的上限设置到屏幕,因为它将缩放到屏幕。将其设置为数据长度。结果是如果你有比svg宽度更多的数据,它将自然地从svg边界的边缘运行。
    2. 通过创建一个尺寸倍数的范围将所有图标连接在一起,即将范围乘以图标大小。
    3. 这里是updated JSFiddle

1 个答案:

答案 0 :(得分:1)

要使绘图超出SVG的边界,您需要做的就是调整您正在使用的刻度范围。例如,您的x比例设置为

var xScale = d3.scale.linear()
.domain([0, data.length - 1])
.range([0, settings.containerWidth - 16]);

范围决定了SVG上绘制内容的位置,目前仅限于SVG的宽度。为了使其超出范围,请将其更改为例如。

var xScale = d3.scale.linear()
.domain([0, data.length - 1])
.range([0, 2 * settings.containerWidth - 16]);

这将使x比例覆盖实际SVG宽度的两倍 - 也就是说,图形的一半将是可见的,而另一半将是"关闭屏幕"。

完整演示here