画笔上下文中的路径显示太小

时间:2018-04-17 07:30:33

标签: javascript jquery d3.js

我正在尝试使用此bl.ock作为参考创建带有画笔和缩放的折线图。折线图路径看起来很好,但画笔上下文中的路径显示为1px * 1px。我的猜测是路径没有得到x和y来正确创建路径。

var chartfn = (function(window, d3) {
  var svg, chartWrapper, width, height, height2, parseDate, x, x2, y, y2, xAxis, xAxis2, yAxis, brush, zoom, line, line2, clip, Line_chart, focus, context, FAxisX, FAxisY, CAxisX, CBrush, zoomRect, margin = {},
    margin2 = {}

  var data = [{
    "key": "2017-08-12 00:00:00",
    "value": {
      "distance": 5536
    }
  }, {
    "key": "2017-08-13 00:00:00",
    "value": {
      "distance": "0"
    }
  }, {
    "key": "2017-08-14 00:00:00",
    "value": {
      "distance": 16453
    }
  }, {
    "key": "2017-08-15 00:00:00",
    "value": {
      "distance": 6884
    }
  }, {
    "key": "2017-08-16 00:00:00",
    "value": {
      "distance": 17311
    }
  }, {
    "key": "2017-08-17 00:00:00",
    "value": {
      "distance": 11091
    }
  }, {
    "key": "2017-08-18 00:00:00",
    "value": {
      "distance": "0"
    }
  }, {
    "key": "2017-08-19 00:00:00",
    "value": {
      "distance": "0"
    }
  }, {
    "key": "2017-08-20 00:00:00",
    "value": {
      "distance": "0"
    }
  }, {
    "key": "2017-08-21 00:00:00",
    "value": {
      "distance": 9868
    }
  }, {
    "key": "2017-08-22 00:00:00",
    "value": {
      "distance": 9745
    }
  }, {
    "key": "2017-08-23 00:00:00",
    "value": {
      "distance": "0"
    }
  }];




  init(data);


  function init(data) {
    parseDate = d3.timeParse("%Y-%m-%d %H:%M:%S");
    data.forEach(function(d) {
      d.date = parseDate(d.key);
    })

    svg = d3.select('#chart');
    chartWrapper = svg.append('g')

    x = d3.scaleTime().domain(d3.extent(data, function(d) {
      return d.date;
    }));
    y = d3.scaleLinear().domain([0, d3.max(data, function(d) {
      return d.value['distance'];
    })]);
    x2 = d3.scaleTime().domain(x.domain());
    y2 = d3.scaleLinear().domain(y.domain());

    brush = d3.brushX();
    zoom = d3.zoom().scaleExtent([1, Infinity]);

    line = d3.line()
      .curve(d3.curveMonotoneX)
      .x(function(d) {
        return x(d.date);
      })
      .y(function(d) {
        return y(d.value['distance']);
      });

    line2 = d3.line()
      .curve(d3.curveMonotoneX)
      .x(function(d) {
        return x2(d.date);
      })
      .y(function(d) {
        return y2(d.value['distance']);
      });

    clip = chartWrapper.append('defs').append('svg:clipPath')
      .attr('id', 'clip')
      .append('svg:rect')
      .attr('x', 0)
      .attr('y', 0)
    Line_chart = chartWrapper.append('g')
      .attr('class', 'focus')

    Line_chart.append('path')
      .datum(data)
      .attr("class", "line")
      .attr("d", line);

    focus = chartWrapper.append('g')
      .attr('class', 'focus')
    context = chartWrapper.append('g')
      .attr('class', 'context')

    context.append("path")
      .datum(data)
      .attr("class", "line")
      .attr("d", line2);

    FAxisX = focus.append("g")
      .attr("class", "axis axis--x")

    FAxisY = focus.append("g")
      .attr("class", "axis axis--y")

    CAxisX = context.append("g")
      .attr("class", "axis axis--x")

    CBrush = context.append("g")
      .attr("class", "brush")

    zoomRect = chartWrapper.append('rect')
      .attr('class', 'zoom')

    render();
  };

  function render() {
    $container = $('#chart-container')
    updateDimensions($container.width(), $container.height());
    svg.attr('width', width + margin.right + margin.left)
      .attr('height', height + margin.top + margin.bottom);
    chartWrapper.attr('transform', 'translate(' + 0 + ',' + margin.top + ')');

    x.range([0, width]);
    x2.range([0, width]);
    y.range([height, 0]);
    y2.range([height2, 0]);

    xAxis = d3.axisBottom(x);
    xAxis2 = d3.axisBottom(x2);
    yAxis = d3.axisLeft(y);

    brush.extent([
        [0, 0],
        [width, height2]
      ])
      .on("brush end", brushed);

    zoom.translateExtent([
        [0, 0],
        [width, height]
      ])
      .extent([
        [0, 0],
        [width, height]
      ])
      .on("zoom", zoomed);

    clip.attr("width", width)
      .attr("height", height);

    Line_chart.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .attr("clip-path", "url(#clip)");

    context.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")")
    // .attr("clip-path", "url(#clip)");
    focus.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    FAxisX.attr("transform", "translate(0," + height + ")")
      .call(xAxis);

    FAxisY.call(yAxis);

    CAxisX.attr("transform", "translate(0," + height2 + ")")
      .call(xAxis2);

    CBrush.call(brush)
      .call(brush.move, x.range());

    zoomRect.attr("width", width)
      .attr("height", height)
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .call(zoom);
  }

  function updateDimensions(winWidth, winHeight) {
    margin = {
        top: 10,
        right: 30,
        bottom: 110,
        left: 40
      },
      margin2 = {
        top: 430,
        right: 30,
        bottom: 40,
        left: 40
      },
      width = winWidth - margin.left - margin.right,
      height = winHeight - margin.top - margin.bottom,
      height2 = winHeight - margin2.top - margin2.bottom;
  }




  function brushed() {
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom
    var s = d3.event.selection || x2.range();
    x.domain(s.map(x2.invert, x2));
    Line_chart.select(".line").attr("d", line);
    focus.select(".axis--x").call(xAxis);
    svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
      .scale(width / (s[1] - s[0]))
      .translate(-s[0], 0));
  }

  function zoomed() {
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
    var t = d3.event.transform;
    x.domain(t.rescaleX(x2).domain());
    Line_chart.select(".line").attr("d", line);
    focus.select(".axis--x").call(xAxis);
    context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
  }

  return {
    render: render
  }
})(window, d3);

window.addEventListener('resize', chartfn.render)
body{
  background: aliceblue;
}

text{
  fill: black;
}

#chart-container {
  height: 500px;
  width: 960px;
}

.line {
  fill: none;
  stroke: green;
  stroke-width: 2.5px;
}

.zoom {
  cursor: move;
  fill: none;
  pointer-events: all;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js'></script>

<div id='chart-container'>
  <svg id='chart'></svg>
</div>

我在上面添加了一个片段来展示我尝试过的内容。似乎还无法弄清楚我哪里出错了。

1 个答案:

答案 0 :(得分:0)

只缺少两行代码。 line2 shold也会在brushed()zoomed()中重新绘制。

 function brushed() {
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom
    var s = d3.event.selection || x2.range();
    x.domain(s.map(x2.invert, x2));
    Line_chart.select(".line").attr("d", line);

    // New line
    context.select(".line").attr("d", line2);

    focus.select(".axis--x").call(xAxis);
    svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
        .scale(width / (s[1] - s[0]))
        .translate(-s[0], 0));
}

function zoomed() {
    if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
    var t = d3.event.transform;
    x.domain(t.rescaleX(x2).domain());
    Line_chart.select(".line").attr("d", line);

    // New line
    context.select(".line").attr("d", line2);

    focus.select(".axis--x").call(xAxis);
    context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
}

希望这有帮助。