使用d3.js定位xAxis和yAxis

时间:2016-02-01 15:00:15

标签: d3.js

我有什么作品,但我想知道是否有更好的方法。

我有this页作为我的工作示例。源代码为here,此问题专门针对x轴和y轴绘制正负值。

我有drawAxes方法,如下所示:

  drawAxes(data) {
    const xAxis = d3.svg.axis()
            .scale(this.xScale);

    const yAxis = d3.svg.axis()
            .orient('left')
            .scale(this.yScale);

    const dimensions = this.getDimensions();

    this.xScale.domain(d3.extent(data, (d) => d.x));

    const minY = d3.min(data, (d) => d.y);
    const maxY = d3.max(data, (d) => d.y);

    const nonNegativeXAxis = minY >= 0 && maxY >= 0;
    const positiveAndNegativeXAxis = minY < 0 && maxY > 0;

    let yScaleDomain, xAxisPosition;

    if(nonNegativeXAxis) {
      yScaleDomain = [0, d3.max(data, (d) => d.y)];
    }  else {
      yScaleDomain = d3.extent(data, (d) => d.y);
    }

    this.yScale.domain(yScaleDomain);

    const findZeroTick = (data) => {
      return data === 0;
    };

    this.svg.append('g')
      .attr('class', 'axis y-axis')
      .style('visibility', 'hidden')
      .call(yAxis);

    if(nonNegativeXAxis) {
      yScaleDomain = [0, d3.max(data, (d) => d.y)];
      xAxisPosition = dimensions.height;
    } else if(positiveAndNegativeXAxis) {
      xAxisPosition = this.svg.selectAll(".tick").filter(findZeroTick).map((tick) => {
        return d3.transform(d3.select(tick[0]).attr('transform')).translate[1];
      });
    } else {
      yScaleDomain = d3.extent(data, (d) => d.y);
      xAxisPosition = 0;
    }

    this.svg.append('g')
      .attr('class', 'axis x-axis')
      .attr('transform', `translate(0, ${xAxisPosition})`)
      .call(xAxis);

    d3.select('.y-axis').remove();

    const minX = d3.min(data, (d) => d.x);
    const maxX = d3.max(data, (d) => d.y);

    const positiveXOnly = minX > 0 && maxX > 0;
    const negativeXOnly = minX < 0 && maxX < 0;

    let yAxisPosition;

    if(positiveXOnly) {
      yAxisPosition = 0;
    } else if(negativeXOnly) {
      yAxisPosition = dimensions.width;
    } else {
      yAxisPosition = this.svg.selectAll(".x-axis .tick").filter(findZeroTick).map((tick) => {
        return d3.transform(d3.select(tick[0]).attr('transform')).translate[0];
      });
    }

    this.svg.append('g')
      .attr('class', 'axis y-axis')
      .attr('transform', `translate(${yAxisPosition}, 0)`)
      .call(yAxis);
  }

我发现将y轴x轴定位在相反轴的0处非常困难。

我是如何做到的,首先绘制y轴但保持隐藏状态:

this.svg.append('g')
  .attr('class', 'axis y-axis')
  .style('visibility', 'hidden')
  .call(yAxis);

然后我通过选择所有刻度并找到0刻度的y坐标找到y轴上的0位置,我使用该值来定位x轴:

const findZeroTick = (data) => {
  return data === 0;
};

xAxisPosition = this.svg.selectAll(".tick").filter(findZeroTick).map((tick) => {
  return d3.transform(d3.select(tick[0]).attr('transform')).translate[1];
});

this.svg.append('g')
  .attr('class', 'axis x-axis')
  .attr('transform', `translate(0, ${xAxisPosition})`)
  .call(xAxis);

要定位yAxis,我首先删除yAxis,然后通过选择x轴上的所有刻度然后再次添加yAxis并使用检索到的值来定位yAxis来执行类似的计算:

d3.select('.y-axis').remove();

yAxisPosition = this.svg.selectAll(".x-axis .tick").filter(findZeroTick).map((tick) => {
  return d3.transform(d3.select(tick[0]).attr('transform')).translate[0];
});

this.svg.append('g')
  .attr('class', 'axis y-axis')
  .attr('transform', `translate(${yAxisPosition}, 0)`)
  .call(yAxis);

是否有更有效的方法来实现相同的结果或失败,我可以移动轴而不必删除它并重新添加它吗?

1 个答案:

答案 0 :(得分:0)

只要线性比例具有域和范围,就可以使用它来获取任何域值的像素值。例如,要获取点(0,0)的像素,您可以询问def config(apps, groups, stats_user, stats_password, stats_uri, bind_http_https, ssl_certs, templater): logger.info("generating config") config = templater.haproxy_head.format( statsUser=stats_user, statsPassword=stats_password, statsURI=stats_uri ) xScale(0)

如果这些值位于定义的范围之外(读取:svg画布尺寸,以像素为单位),您知道Y轴应分别位于最左侧或最右侧(最小或最大范围加上边距)。