本文介绍了D3缩放不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这里有一个简单的解决方案,但我已经尝试了一些教程并且无法将它们应用到我的代码中。我已经为3-5个数据点的每个段绘制了一个单独的区域,从而创建了一个高程图。所以,我在同一个图表上发生了不少情节。因此我尝试了缩放 svg 元素的缩放技术,但是已经空了。这是我最近的尝试。希望你们能帮忙。



目前,当我尝试缩放时,它会将x和y刻度重置为[0,1]并用填充填充整个区域这是指定:

您需要将比例缩放到缩放侦听器,直到设置了比例的域:

  //创建缩放监听器
var zoomListener = d3.behavior.zoom()
/ /延迟比例绑定直到设置域。
// .x(x)
// .y(y)
.scaleExtent([1,10])
.on(zoom,zoomHandler);

加载数据并相应地设置了比例的域值后,您可以将比例绑定到监听器,然后将其附加到您的 svg

  //缩放整个图表的范围
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));

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


I know there's an easy solution here, but I've tried to run through a few tutorials and failed in applying them to my code. I've created an elevation chart by plotting a separate area for each segment of 3-5 data points. So, I have quite a few plots happening on the same graph. Because of this I've tried zooming techniques that zoom on the svg element, but have been coming up empty. Here's my latest attempt. Hopefully you guys can help.

Currently, when I try to zoom, it resets the x and y scales to [0,1] and fills the entire area with the fill color.

Here's a 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's documentation of scales being attached to the zoom behaviour specifies:

You need to defer binding of your scales to the zoom listener until the domains of the scales are set:

// 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);

After data has been loaded and the scales' domain values have been set accordingly you may bind the scales to the listener and after that attach it to your 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));

Please check the adjusted plunker to see if this solves your problem.

这篇关于D3缩放不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 00:35