React+Storybook中JSXGraph数轴如何保持1:1单位纵横比实现响应式设计
解决React+Storybook中JSXGraph响应式1:1单位比例问题
核心思路
放弃JSXGraph自带的keepAspectRatio属性,通过动态计算坐标范围+监听窗口resize的方式,手动控制画板的boundingbox,既保证容器宽度100%、高度固定400px,又维持x/y轴单位长度1:1的比例,同时避免内容溢出边界。
具体实现步骤
1. React组件代码实现
import React, { useEffect, useRef } from 'react'; import JXG from 'jsxgraph'; const ResponsiveJSXGraph = () => { const boardRef = useRef(null); const boardInstance = useRef(null); useEffect(() => { if (!boardRef.current) return; // 初始化画板逻辑 const initBoard = () => { const container = boardRef.current; const containerWidth = container.offsetWidth; const fixedHeight = 400; // 计算最大可容纳的1:1单位范围:取宽/2、高/2中的较小值 // 这里的"2"对应坐标范围[-maxUnit, maxUnit],可根据需求调整 const maxUnit = Math.min(containerWidth / 2, fixedHeight / 2); // 初始化画板,禁用自带的比例控制 boardInstance.current = JXG.JSXGraph.initBoard(boardRef.current, { boundingbox: [-maxUnit, maxUnit, maxUnit, -maxUnit], // [xmin, ymax, xmax, ymin] keepAspectRatio: false, showNavigation: false, zoom: { wheel: false }, // 禁用滚轮缩放避免比例混乱 pan: { enabled: false } // 禁用平移,如需平移需额外处理比例 }); // 绘制示例数轴 boardInstance.current.create('axis', [[0, 0], [1, 0]], { name: 'x轴' }); boardInstance.current.create('axis', [[0, 0], [0, 1]], { name: 'y轴' }); }; initBoard(); // 监听窗口resize,实时更新坐标范围 const handleResize = () => { if (!boardInstance.current || !boardRef.current) return; const container = boardRef.current; const containerWidth = container.offsetWidth; const fixedHeight = 400; const maxUnit = Math.min(containerWidth / 2, fixedHeight / 2); // 更新画板的boundingbox,自动适配容器尺寸 boardInstance.current.setBoundingBox([-maxUnit, maxUnit, maxUnit, -maxUnit]); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); boardInstance.current?.destroy(); }; }, []); return ( <div ref={boardRef} style={{ width: '100%', height: '400px', overflow: 'hidden', // 防止内容溢出容器 border: '1px solid #eee' // 可选,方便查看容器边界 }} /> ); }; export default ResponsiveJSXGraph;
2. Storybook配置
直接在stories文件中引入组件即可,无需额外配置:
import ResponsiveJSXGraph from './ResponsiveJSXGraph'; export default { title: 'JSXGraph/ResponsiveAxis', component: ResponsiveJSXGraph, }; export const Default = () => <ResponsiveJSXGraph />;
3. 关键细节说明
- 禁用
keepAspectRatio:JSXGraph自带的该属性会强制画板整体等比例缩放,导致非正方形容器内的内容溢出,必须关闭。 - 动态计算
boundingbox:每次resize时根据容器的实际宽度和固定高度,计算出能完全容纳的最大1:1坐标范围,保证x/y轴单位长度一致。 - 禁用缩放和平移:如果需要保留这类交互,需额外添加逻辑,确保操作时维持1:1的单位比例,避免失衡。
overflow: hidden:给容器添加该样式,可避免极端情况下的内容溢出(如计算误差)。
内容的提问来源于stack exchange,提问作者lena mashukova
相关产品推荐
相关产品推荐

