|
| 1 | +export function getScale(fig, channel, plot) { |
| 2 | + const scale = fig.scale(channel); |
| 3 | + if (scale) return scale; |
| 4 | + |
| 5 | + const proj = fig.projection(); |
| 6 | + if (proj && (channel === 'x' || channel === 'y')) { |
| 7 | + const type = plot.getAttribute('projectionType'); |
| 8 | + return projectionScale(proj, type, channel); |
| 9 | + } |
| 10 | +} |
| 11 | + |
| 12 | +function projectionScale(proj, type, channel) { |
| 13 | + const { offset, translate: [tx, ty], scale, width, height } = proj; |
| 14 | + const planar = type === 'identity' || type === 'reflect-y'; |
| 15 | + |
| 16 | + let range; |
| 17 | + let apply; |
| 18 | + let invert; |
| 19 | + |
| 20 | + if (channel === 'x') { |
| 21 | + range = [offset[0], offset[0] + width]; |
| 22 | + apply = planar ? x => x * scale + tx |
| 23 | + : v => proj.stream([v, 0])[0]; |
| 24 | + invert = planar ? x => (x - tx) / scale |
| 25 | + : proj.invert ? x => proj.invert([(x - tx) / scale, 0])[0] |
| 26 | + : null; |
| 27 | + } else { |
| 28 | + range = [offset[1], offset[1] + height]; |
| 29 | + apply = type === 'identity' ? y => y * scale + ty |
| 30 | + : type === 'reflect-y' ? y => -y * scale + ty |
| 31 | + : v => proj.stream([0, v])[1]; |
| 32 | + invert = type === 'identity' ? y => (y - ty) / scale |
| 33 | + : type === 'reflect-y' ? y => (ty - y) / scale |
| 34 | + : proj.invert ? y => proj.invert([0, (y - ty) / scale])[1] |
| 35 | + : null; |
| 36 | + } |
| 37 | + |
| 38 | + return { |
| 39 | + type: planar || type === 'equirectangular' ? 'linear' : `${type}-x`, |
| 40 | + domain: range.map(v => invert(v)), |
| 41 | + range, |
| 42 | + apply, |
| 43 | + invert |
| 44 | + }; |
| 45 | +} |
0 commit comments