123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import { AimOutlined, CompressOutlined, ExpandOutlined, MinusOutlined, PlusOutlined, QuestionCircleFilled } from "@ant-design/icons";
- import { Button, ConfigProvider, Divider, Slider, Tooltip } from "antd";
- import React, { useEffect, useRef, useState } from "react";
- import { useFullscreen } from "ahooks";
- import { useModel } from "umi";
- import { MiniMap } from '@antv/x6-plugin-minimap';
- import insertCss from 'insert-css';
- insertCss(`
- .navigation-view {
- position: absolute;
- bottom: 32px;
- right: 32px;
- width: 330px;
- height: 210px;
- background-color: #fff;
- border: 1px solid #e9edf2;
- border-radius: 8px 8px 0 0;
- overflow: hidden;
- z-index: 1;
- box-shadow: 0 4px 10px 1px rgba(0, 0, 0, .1);
- }`);
- export default function Footer() {
- const [isFullscreen, { toggleFullscreen }] = useFullscreen(document.body);
- const navigationViewRef = useRef(null);
- const { graph, selectedCell } = useModel("flowchartModel");
- const [showNavigation, setShowNavigation] = useState(false);
- const [countCell, setCountCell] = useState(0);
- const [scale, setScale] = useState(100);
- useEffect(() => {
- if(!graph || !navigationViewRef.current) return;
- graph.use(
- new MiniMap({
- container: navigationViewRef.current,
- width: 330,
- height: 210,
- padding: 10,
- }),
- )
- }, [graph, navigationViewRef.current]);
- useEffect(() => {
- graph?.on('cell:change:*', () => {
- const count = graph?.getCells().length || 0;
- setCountCell(count > 0 ? count - 1 : 0)
- });
- graph?.on('scale', (scaleInfo) => {
- setScale(parseInt(scaleInfo.sx * 100 + ''));
- })
- }, [graph]);
- const handleZoom = (value: number) => {
- graph?.zoomTo(value / 100)
- }
- const handleZoomFit = () => {
- graph?.zoomToFit({ })
- }
- const handleOnChange = (value: number) => {
- setScale(Math.round(value));
- handleZoom(value)
- }
- return (
- <ConfigProvider componentSize="small">
- <div className="h-24px bg-white flex justify-between items-center px-16px relative">
- <div className="footer-left"></div>
- <div className="footer-right flex items-center">
- <div>图形:{selectedCell?.length}/{countCell}</div>
- <Divider type="vertical" />
- {/* <Tooltip title="模板">
- <Button type="text" icon={<i className="iconfont icon-buju" />} />
- </Tooltip> */}
- <Tooltip title="聚焦">
- {/* <Button type="text" icon={<i className="iconfont icon-buju" />} /> */}
- <Button type="text" icon={<AimOutlined />} onClick={handleZoomFit}/>
- </Tooltip>
- <Tooltip title={showNavigation ? "关闭视图导航" : "显示视图导航"}>
- <Button type="text" icon={<i className="iconfont icon-map" />} onClick={() => setShowNavigation(!showNavigation)}/>
- </Tooltip>
- <div className="navigation-view" style={{display: showNavigation ? 'block' : 'none'}} ref={navigationViewRef}></div>
- <Button type="text" icon={<MinusOutlined/>} onClick={() => handleZoom( scale - 2)}/>
- <Slider min={20} max={200} className="w-120px m-0 mx-8px" tooltip={{formatter: (val) => `${val}%`}} value={scale} onChange={handleOnChange}/>
- <Button type="text" icon={<PlusOutlined/>} onClick={() => handleZoom( scale + 2)}/>
- <Tooltip title="重置缩放">
- <div className="cursor-pointer mx-8px w-40px" onClick={handleZoomFit}>{scale}%</div>
- </Tooltip>
- {
- isFullscreen
- ? <Button type="text" icon={<CompressOutlined/>} onClick={toggleFullscreen}/>
- : <Button type="text" icon={<ExpandOutlined/>} onClick={toggleFullscreen}/>
- }
- <Divider type="vertical" />
- <Button type="text" icon={<QuestionCircleFilled/>} />
- </div>
- </div>
- </ConfigProvider>
- );
- }
|