D3 V4:Zoom&拖动多系列折线图

时间:2016-09-08 06:21:50

标签: javascript angularjs d3.js angular angular-cli

我在Angular2项目中使用d3 4.2.2绘制图表。我创建了一个多系列折线图并添加了缩放和拖动属性。现在图表正在放大鼠标滚动事件,但它只能缩放X轴和Y轴。它只能拖动X轴和Y轴但图表无法拖动。当我进行缩放或拖动时,这些事件仅适用于两个轴,但不适用于图表。以下是我对我的代码所做的事情。

// set the dimensions and margins of the graph
    var margin = {
        top: 20,
        right: 80,
        bottom: 30,
        left: 50
      },
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    var zoom = d3.zoom()
      .scaleExtent([1, 5])
      .translateExtent([[0, -100], [width + 90, height + 100]])
      .on("zoom", zoomed);

    var svg = d3.select(this.htmlElement).append("svg")
      .attr("class", "line-graph")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .attr("pointer-events", "all")
      .call(zoom);

    var view = svg.append("rect")
      .attr("class", "view")
      .attr("x", 0.5)
      .attr("y", 0.5)
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .style("fill", "#EEEEEE")
      .style("stroke", "#000")
      .style("stroke-width", "0px");

    // parse the date / time
    var parseDate = d3.timeParse("%Y-%m-%d");

    // set the ranges
    var x = d3.scaleTime().range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);
    var z = d3.scaleOrdinal(d3.schemeCategory10);

    // define the line
    var line = d3.line()
      .x( (d) => {
        return x(d.date);
      })
      .y( (d) => {
        return y(d.lookbookcount);
      });

    z.domain(d3.keys(data[0]).filter(function (key) {
      return key !== "date";
    }));

    // format the data
    data.forEach( (d)=> {
      d.date = parseDate(d.date);
    });

    var lookBookData = z.domain().map(function (name) {
      return {
        name: name,
        values: data.map( (d) => {
          return {date: d.date, lookbookcount: d[name], name: name};
        })
      };
    });

    x.domain(d3.extent(data, (d) => {
      return d.date;
    }));

    y.domain([
      d3.min([0]),
      d3.max(lookBookData, (c) => {
        return d3.max(c.values,
          (d) => {
            return d.lookbookcount;
          });
      })
    ]);

    z.domain(lookBookData.map( (c) => {
      return c.name;
    }));

    var xAxis = d3.axisBottom(x)
      .ticks(d3.timeDay.every(1))
      .tickFormat(d3.timeFormat("%d/%m"));

    var yAxis = d3.axisLeft(y)
      .ticks(10);

    // Add the X Axis
    var gX = svg.append("g")
      .style("font", "14px open-sans")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);


    // Add the Y Axis
    var gY = svg.append("g")
      .style("font", "14px open-sans")
      .attr("class", "axis axis--x")
      .call(yAxis)
      .style("cursor", "ns-resize");

    // Add Axis labels
    svg.append("text")
      .style("font", "14px open-sans")
      .attr("text-anchor", "end")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em")
      .text("Sales / Searches");

    svg.append("text")
      .style("font", "14px open-sans")
      .attr("text-anchor", "end")
      .attr("dx", ".71em")
      .attr("transform", "translate(" + width + "," + (height +
        (margin.bottom)) + ")")
      .text("Departure Date");

    var chartdata = svg.selectAll(".chartdata")
      .data(lookBookData)
      .enter().append("g")
      .attr("class", "chartdata");

    chartdata.append("path")
      .classed("line", true)
      .attr("class", "line")
      .attr("d", function (d) {
        return line(d.values);
      })
      .style("fill", "none")
      .style("stroke", function (d) {
        return z(d.name);
      })
      .style("stroke-width", "2px");

    chartdata.append("text")
      .datum(function (d) {
        return {
          name: d.name, value: d.values[d.values.length - 1]
        };
      })
      .attr("transform", function (d) {
        return "translate(" +
          x(d.value.date) + "," + y(d.value.lookbookcount) + ")";
      })
      .attr("x", 3)
      .attr("dy", "0.35em")
      .style("font", "14px open-sans")
      .text(function (d) {
        return d.name;
      });

    // add the dots with tooltips
    chartdata.selectAll(".circle")
      .data(function (d) {
        return d.values;
      })
      .enter().append("circle")
      .attr("class", "circle")
      .attr("r", 4)
      .attr("cx", function (d) {
        console.log(d);
        return x(d.date);
      })
      .attr("cy", function (d) {
        return y(d.lookbookcount);
      })
      .style("fill", function (d) { // Add the colours dynamically
        return z(d.name);
      });  

    function zoomed() {
      view.attr("transform", d3.event.transform);
      gX.call(xAxis.scale(d3.event.transform.rescaleX(x)));
    }

    function resetted() {
      svg.transition()
        .duration(750)
        .call(zoom.transform, d3.zoomIdentity);
    }

任何建议都将受到高度赞赏。

谢谢

0 个答案:

没有答案