【问题标题】:Scale in different units以不同的单位缩放
【发布时间】:2017-03-15 21:51:16
【问题描述】:

如何使用 D3 转换并显示来自不同单位的正确信息

例如

所有数据都在mm..

[ 
    { label: 'sample1', x: 300 }, 
    { label: 'sample2', x: 1200 }, 
    { label: 'sample3', x: 4150 } 
]

所以,问题是,我怎样才能创建一个理解 sample3 应该在 4 之后和 5 之前指向同一位置的比例。

考虑

  1. 10000,它只是一个样本,可以是102301或任何值
  2. 如果可能的话,我想使用 D3 刻度来进行此转换

尝试

let scaleX = d3.scale.linear().domain([-10, 10]).range([0, 500]) // Missing the mm information...

【问题讨论】:

    标签: javascript d3.js scale react-d3


    【解决方案1】:

    你这里有一个概念问题:

    • 将输入(域)映射到输出(范围):这是规模的任务。
    • 格式化轴中的数字和单位(如果有):这是轴生成器的任务

    因此,在您的规模中,您必须将域设置为接受您拥有的原始、实际数据(即数据的原样):

    var scale = d3.scaleLinear()
        .domain([-10000, 10000])//the extent of your actual data
        .range([min, max]);
    

    然后,在轴生成器中,更改显示中的值。在这里,我只是将它除以 1000 并添加“mm”:

    var axis = d3.axisBottom(scale)
        .tickFormat(d => d / 1000 + "mm");
    

    请注意,我在这些 sn-ps 中使用的是 D3 v4。

    这是一个使用这些值的演示:-7500、500 和 4250。您可以看到圆圈处于适当的位置,但轴以毫米为单位显示值。

    var data = [-7500, 500, 4250];
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width", 500)
      .attr("height", 200);
    
    var scale = d3.scaleLinear()
      .domain([-10000, 10000])
      .range([20, 480]);
    
    var axis = d3.axisBottom(scale)
      .tickFormat(d => d / 1000 + "mm");
    
    var circles = svg.selectAll("foo")
      .data(data)
      .enter()
      .append("circle")
      .attr("r", 4)
      .attr("fill", "teal")
      .attr("cy", 40)
      .attr("cx", d => scale(d));
    
    var g = svg.append("g")
      .attr("transform", "translate(0,60)")
      .call(axis);
    <script src="https://d3js.org/d3.v4.js"></script>

    【讨论】:

    • 是的..这是我的答案。只有一个区别,我创建了一个scaleFormat,因为我需要将我的范围固定在 -10 到 10 之间。
    • 我相信您的答案与此不同...例如,您从不在代码中使用scaleFormat,您不同意吗?
    • 我从不使用,因为ticksFormat 应该由axis 对象使用。我不t put the complete code here. Thats 标记您的答案的原因。比我的更完整
    【解决方案2】:

    我找到了一种方法..

    const SIZE_MM = 10000
    const SIZE_PX = 500
    const scaleFormat = d3.scale.linear().domain([0, SIZE_MM]).range([-10, 10])
    const ticksFormat = d => Math.round(scaleFormat(d))
    const ticks = SIZE_MM / SIZE_PX 
    
    const lineScale = d3.scale.linear().domain([0, SIZE_MM ]).range([0, SIZE_PX])
    lineScale(9500)
    // 475
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 2020-10-10
      • 2020-08-06
      • 2020-03-13
      相关资源
      最近更新 更多