javascript - D3 缩放不起作用

标签 javascript svg d3.js zooming

我知道这里有一个简单的解决方案,但我尝试浏览了一些教程,但未能将它们应用到我的代码中。我通过为 3-5 个数据点的每个部分绘制一个单独的 area 创建了一个海拔图。所以,我在同一张图上发生了很多情节。正因为如此,我尝试了缩放 svg 元素的缩放技术,但一直是空的。这是我最近的尝试。希望大家能帮忙。

目前,当我尝试缩放时,它会将 x 和 y 比例重置为 [0,1] 并用填充颜色填充整个区域。

这是一个 Plunk

// ***************************** //
//             Set Up            //
// ***************************** //

// *** MAP VARIABLES ***

L.mapbox.accessToken = 'pk.eyJ1Ijoid2lsbGlhbWx1Y2UiLCJhIjoiNE1zU0xMNCJ9.X9y-S0ubezlH-aefwUZslA';
var map = L.mapbox.map('map', 'examples.map-i86nkdio')



// *** CHART VARIABLES ***

var margin = {top: 10, right: 20, bottom: 30, left: 100},
    width = 1100 - margin.left - margin.right,
    height = 150 - margin.top - margin.bottom;

// Map colors to limits
var color = d3.scale.ordinal()
    .domain([-10,-5,0,5,10])
    .range(['#a1d99b','#c7e9c0','#fdd0a2','#fdae6b','#fd8d3c','#e6550d']);

// Set up the size of the chart relative to the div
var x = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);

// Define the look of the axis
var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y).orient("left").ticks(5);

// Define an area. Areas are filled with color.
var area = d3.svg.area()
    .x(function(d) { return x(d.distance); })
    .y0(height)
    .y1(function(d) { return y(d.elevation); });

// Define the line
var valueline = d3.svg.line()
    .interpolate("linear")
    .x(function(d) { return x(d.distance); })
    .y(function(d) { return y(d.elevation); })

// Set up the SVG element
var svg = d3.select("#chart-container")
    .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 + ")")
    .call(zoomed);

// Define the zoom behavior
var zoom = d3.behavior.zoom()
    .x(x)
    .y(y)
    .scaleExtent([1, 10])
    .on("zoom", zoomed);

// Caculate the average gradient of a dataGroup.
function dataGroupGradient(dataGroup)
{
  var sum = dataGroup[0].gradient;
  for (var i = 1; i < dataGroup.length; i++)
  {
    sum += parseFloat(dataGroup[i].gradient);  
  }
  return sum/dataGroup.length;
}

// Define polyline options
// http://leafletjs.com/reference.html#polyline
var polyline_options = {
    stroke: true,
    weight: 3,
    fill: true,
    color: '#03f'
};

// Declare an array for holding the points that make up the path on the map
var line_points = [];


// ***************************** //
//     WORKING WITH THE DATA     //
// ***************************** //

// Get the data
d3.csv("first5km_Strade_Bianche.csv", function(error, data) {
    data.forEach(function(d) {
        d.distance = +d.distance;
        d.elevation = +d.elevation;
        d.gradient = +d.gradient;
        d.latitude = +d.latitude;
        d.longitude = +d.longitude;
        line_points.push([d.latitude, d.longitude]);
    });

    // Scale the range of the entire chart
    x.domain(d3.extent(data, function(d) { return d.distance; }));
    y.domain([0, d3.max(data, function(d) { return d.elevation; })]);

    // Add the overall valueline path. This path uses all of the data.
    svg.append("path")
        .attr("d", valueline(data));

    // Split the data based on "group"
    var dataGroup = d3.nest()
        .key(function(d) {
            return d.group;
        })
        .entries(data);

    // To remove white space between dataGroups, append the first element of one
    // dataGroup to the last element of the previous dataGroup.
    dataGroup.forEach(function(group, i) {
      if(i < dataGroup.length - 1) {
        group.values.push(dataGroup[i+1].values[0])
      }
    })

    // Draw the array of line_points to the map and fit the bounds.
    var polyline = L.polyline(line_points, polyline_options).addTo(map);
    map.fitBounds(polyline.getBounds());

    // Add a line and an area for each dataGroup
    dataGroup.forEach(function(d, i){
        svg.append("path")
            .datum(d.values)
            .attr("class", "area")
            .attr("d", area);
        });

    // Fill the dataGroups with color
    svg.selectAll(".area")
        .style("fill", function(d) { return color(dataGroupGradient(d)); });

    // Add the X Axis
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    // Add the Y Axis
    svg.append("g")
        .attr("class", "y axis")
        .call(yAxis);

    // Add the text label for the X axis
    svg.append("text")
        .attr("transform",
              "translate(" + (width/2) + " ," + 
                             (height+margin.bottom) + ")")
        .style("text-anchor", "middle")
        .text("Distance");

    // Add the text label for the Y axis
    svg.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 6)
        .attr("x", margin.top - (height / 2))
        .attr("dy", ".71em")
        .style("text-anchor", "end")
        .text("");

    svg.append("clipPath")
        .attr("id", "clip")
        .append("rect")
        .attr("width", width)
        .attr("height", height);

});

// *********************** //
//  Zoom specific updates  //
// *********************** //
function zoomed() {
    svg.select(".x.axis").call(xAxis);
    svg.select(".y.axis").call(yAxis);   
    svg.selectAll('path.line').attr('d', line);   
}

最佳答案

D3 的天平文档附加到 zoom behaviour指定:

# zoom.x([x])

… If the scale's domain or range is modified programmatically, this function should be called again.

您需要推迟将比例绑定(bind)到缩放监听器,直到设置比例的域:

// create the zoom listener
var zoomListener = d3.behavior.zoom()
//    Defer binding of scales until domains have been set.
//    .x(x)  
//    .y(y)
    .scaleExtent([1, 10])
    .on("zoom", zoomHandler);

加载数据并相应设置秤的域值后,您可以将秤绑定(bind)到监听器,然后将其附加到您的 svg:

// Scale the range of the entire chart
x.domain(d3.extent(data, function(d) { return d.distance; }));
y.domain([0, d3.max(data, function(d) { return d.elevation; })]);
svg.call(zoomListener.x(x).y(y));

请检查调整后的plunker看看这是否能解决您的问题。

关于javascript - D3 缩放不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29202900/

相关文章:

javascript - D3圆弧渐变

javascript - 向 svg 饼图添加填充动画

typescript - typescript 中像 SomeType<T, U, V> 这样的类型是什么意思?

javascript - 如何将图例定位到圆环图的右侧

javascript - Backbone.js 放置事件不起作用

javascript - 在旧浏览器上模拟 html5 电子邮件验证

javascript - jquery 中如何让对象旋转然后消失?

javascript - 禁用选中的字段

javascript - SVG 和响应问题

javascript - 外部 JS 文件在我的 HTML 文件中不起作用