如何限制d3中的动画轴标签位置?

时间:2017-01-15 23:51:38

标签: d3.js svg

我使用具有滑动x轴的d3实现图表。 Demo

当轴标签接近边缘时,它们淡出/淡出。

但是,标签会动画到svg的左右边距(灰色区域):

enter image description here

如何避免在svg边距上呈现标签?



const timeWindow = 10000;
const transitionDuration = 3000;

const xScaleDomain = (now = new Date()) =>
  [now - timeWindow, now];

const totalWidth = 500;
const totalHeight = 200;
const margin = {
  top: 30,
  right: 50,
  bottom: 30,
  left: 50
};
const width = totalWidth - margin.left - margin.right;
const height = totalHeight - margin.top - margin.bottom;

const svg = d3.select('.chart')
  .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight)
  .append('g')
    .attr('transform', `translate(${margin.left}, ${margin.top})`)

svg
  .append('rect')
    .attr('width', width)
    .attr('height', height);

// Add x axis
const xScale = d3.scaleTime()
  .domain(xScaleDomain(new Date() - transitionDuration))
  .range([0, width]);

const xAxis = d3.axisBottom(xScale);

const xAxisSelection = svg
  .append('g')
    .attr('transform', `translate(0, ${height})`)
  .call(xAxis);

// Animate
const animate = () => {
  xScale.domain(xScaleDomain());

  xAxisSelection
    .transition()
    .duration(transitionDuration)
    .ease(d3.easeLinear)
    .call(xAxis)
    .on('end', animate);
};

animate();

svg {
  margin: 30px;
  background-color: #ccc;
}

rect {
  fill: #fff;
  outline: 1px dashed #ddd;
}

<script src="https://unpkg.com/d3@4.4.1/build/d3.js"></script>
<div class="chart"></div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

你可以剪辑它:

svg.append('defs')
  .append('clipPath')
  .attr('id','myClip')
  .append('rect')
  .attr('width', width)
  .attr('height', totalHeight);

...

const xAxisSelection = svg
  .append('g')
  .attr('clip-path', 'url(#myClip)')
  ...

完整代码:

&#13;
&#13;
const timeWindow = 10000;
const transitionDuration = 3000;

const xScaleDomain = (now = new Date()) =>
  [now - timeWindow, now];

const totalWidth = 500;
const totalHeight = 200;
const margin = {
  top: 30,
  right: 50,
  bottom: 30,
  left: 50
};
const width = totalWidth - margin.left - margin.right;
const height = totalHeight - margin.top - margin.bottom;

const svg = d3.select('.chart')
  .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight)
  .append('g')
    .attr('transform', `translate(${margin.left}, ${margin.top})`)

svg.append('defs')
  .append('clipPath')
  .attr('id','myClip')
  .append('rect')
    .attr('width', width)
    .attr('height', totalHeight);

// Add x axis
const xScale = d3.scaleTime()
  .domain(xScaleDomain(new Date() - transitionDuration))
  .range([0, width]);

const xAxis = d3.axisBottom(xScale);

const xAxisSelection = svg
  .append('g')
   .attr('clip-path', 'url(#myClip)')
    .attr('transform', `translate(0, ${height})`)
  .call(xAxis);

// Animate
const animate = () => {
  xScale.domain(xScaleDomain());

  xAxisSelection
    .transition()
    .duration(transitionDuration)
    .ease(d3.easeLinear)
    .call(xAxis)
    .on('end', animate);
};

animate();
&#13;
svg {
  margin: 30px;
  background-color: #ccc;
}

rect {
  fill: #fff;
  outline: 1px dashed #ddd;
}
&#13;
<script src="https://unpkg.com/d3@4.4.1/build/d3.js"></script>
<div class="chart"></div>
&#13;
&#13;
&#13;