123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import {
- AimOutlined,
- CompressOutlined,
- ExpandOutlined,
- MinusOutlined,
- PlusOutlined,
- QuestionCircleFilled,
- } from "@ant-design/icons";
- import { Button, ConfigProvider, Divider, Slider, Tooltip } from "antd";
- import React, { useEffect, useMemo, useRef, useState } from "react";
- import { useFullscreen } from "ahooks";
- import { useModel } from "umi";
- import { MiniMap } from "@antv/x6-plugin-minimap";
- import insertCss from "insert-css";
- import { TopicType } from "@/enum";
- 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 [showNavigation, setShowNavigation] = useState(false);
- const [scale, setScale] = useState(100);
- const { selectedCell, graph } = useModel("mindMapModel");
- useEffect(() => {
- if (!graph || !navigationViewRef.current) return;
- graph.use(
- new MiniMap({
- container: navigationViewRef.current,
- width: 330,
- height: 210,
- padding: 10,
- })
- );
- }, [graph, navigationViewRef.current]);
- graph?.on("scale", (args) => {
- setScale(args.sx * 100);
- });
- const countInfo = useMemo(() => {
- return {
- selectedNodeCount: selectedCell.filter((cell) => cell.isNode()).length,
- selectedNodeTextCount: selectedCell.reduce(
- (a, b) => a + b.data?.label?.length || 0,
- 0
- ),
- nodeCount: graph?.getNodes().length || 0,
- textCount:
- graph?.getNodes().reduce((a, b) => a + b.data?.label?.length || 0, 0) ||
- 0,
- };
- }, [selectedCell, graph]);
- const handleZoom = (value: number) => {
- graph?.zoomTo(value / 100);
- };
- const handleZoomFit = () => {
- graph?.zoomTo(1);
- };
- const handleOnChange = (value: number) => {
- setScale(value);
- handleZoom(value);
- };
- const handleFocusCenter = () => {
- const center = graph
- ?.getCells()
- .find((cell) => cell.data?.type === TopicType.main);
- center && graph?.centerCell(center);
- };
- return (
- <ConfigProvider componentSize="small">
- <div className="absolute w-full h-24px left-0 bottom-0 bg-white flex justify-between items-center px-16px">
- <div className="footer-left"></div>
- <div className="footer-right flex items-center">
- <div className="mr-8px">
- 字数:
- {countInfo.selectedNodeCount
- ? `${countInfo.selectedNodeTextCount}/`
- : ""}
- {countInfo.textCount}
- </div>
- <div>
- 主题数:
- {countInfo.selectedNodeCount
- ? `${countInfo.selectedNodeCount}/`
- : ""}
- {countInfo.nodeCount}
- </div>
- <Divider type="vertical" />
- <Tooltip title="模板">
- <Button type="text" icon={<i className="iconfont icon-buju" />} />
- </Tooltip>
- <Tooltip title="定位到中心主题">
- <Button
- type="text"
- icon={<AimOutlined />}
- onClick={handleFocusCenter}
- />
- </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>
- );
- }
|