如何创建可感知Observable Plot宽边距等属性的独立比例尺?
Observable Plot 独立比例尺的维度映射问题
我需要创建**独立比例尺(standalone scale)**并使用其scale.apply()方法,但该方法仅返回[0,1]范围的归一化值,而非结合图表宽度、边距等维度后的实际像素值。而plot.scale()返回的比例尺则能给出基于图表维度的实际数值,但问题在于我需要在创建图表的marks配置中就用到scale.apply(),这就陷入了“鸡生蛋”的矛盾——还没创建图表就拿不到plot.scale(),提前创建的独立比例尺又不带维度信息。
尝试过在创建独立比例尺时传入图表维度参数,但被完全忽略;也想过在回调里直接访问最终的比例尺,但没法实现。
目前的临时解决办法有两种:
- 两次创建图表:先生成一个图表拿到
plot.scale(),再用这个比例尺重新创建最终图表。在Svelte组件场景下,只有第一个实例需要这么做,可以隐藏一个“一次性”的组件来完成这个过程。 - 先生成一个极简的“占位”图表获取比例尺,再用它来构建真正的目标图表。
问题演示代码
HTML
<!DOCTYPE html> <script src="https://cdn.jsdelivr.net/npm/d3@7"></script> <script src="https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6"></script> <div id="myplot"></div>
CSS
#myplot { height: 200px; }
JavaScript
const data = [{ text: 'Weekend', utc: new Date('2024-06-16'), end: new Date('2024-06-17'), },{ text: 'Weekdays', utc: new Date('2024-06-17'), end: new Date('2024-06-22'), }, { text: 'Weekend', utc: new Date('2024-06-22'), end: new Date('2024-06-23'), }] // 构造独立比例尺 const scale = Plot.scale({x: {domain: [new Date('2024-06-16'), new Date('2024-06-23')]}}) // 创建图表 const plot = Plot.plot({ height: 150, width: 800, marginRight: 12, marginLeft: 12, marks: [ Plot.rectY(data, { x1: (d) => d.utc, x2: (d) => d.end, y: 1, fill: (d) => d.text == 'Weekend' ? 'lightgray': 'beige' }), Plot.text(data, { x: (d) => (Number(d.utc) + Number(d.end))/2, text: 'text' }), ], }); // 对比两种比例尺的输出 function compareScales(value) { console.log({ value, '独立scale': scale.apply(value), 'plot.scale': plot.scale('x').apply(value) }) } compareScales(new Date('2024-06-16')) compareScales(new Date('2024-06-17')) compareScales(new Date('2024-06-23')) const div = document.querySelector('#myplot'); div.append(plot);
内容的提问来源于stack exchange,提问作者Leftium
相关产品推荐
相关产品推荐

