antv-G6知识图谱安装--使用(实例)--连接线修改成动态,并添加跟随线移动的光圈,设置分支跟踪定位功能

news2024/10/7 3:21:21

这系列文章主要是完成一个图谱的自定义修改(最近太忙了长篇分段更新自己使用流程)
1. 连接线修改成动态,并添加跟随线移动的光圈
2. 自定义卡片样式和文字内容
3. 自定义伸缩节点的样式,并添加动画样式
3. 自定义弹窗样式
4. 自定义弹窗样式
5. 更新图谱
6. 设置分支跟踪定位功能

antv-G6知识图谱安装--使用(实例)

  • 官网地址➡️[添加链接描述](https://g6.antv.antgroup.com/manual/introduction)
  • 前言
  • 1. 安装---引入antv/g6
  • 2. 官网指引
  • 3. 找一个实例作自定义修改
    • 1. 先择一个dome图谱
    • 2. 在vue2+js中使用
        • 1. 创建vue文件并引入`import G6 from '@antv/g6';`
        • 2. 复制官网图谱实例(附上代码)
    • 3. 设置流动线,链接线上自定义一个运动的小球
        • 1. 官网dome地址
        • 2. 结合官网修改代码
        • 3. 运行后样式
    • 4 . 更新图谱
    • 5. 支点跟随--聚焦一个节点
      • 1. 官网地址
      • 2. graph.render();后添加聚焦节点代码
      • 3. 运行后效果
  • 下篇地址[自定义卡片--收缩节点并添加动画--自定义弹窗样式](https://blog.csdn.net/men_gqi/article/details/132476175?spm=1001.2014.3001.5502)

官网地址➡️添加链接描述

前言

提示:antv-G6初次使用(实例+分析注释)项目需要时间紧,直接网上找的加上官网信息,主要内容都有注释


1. 安装—引入antv/g6

  1. 在项目中使用 NPM 包引入
npm install --save @antv/g6
  1. 在需要用的 G6 的 JS 文件中导入:
import G6 from '@antv/g6';

在这里插入图片描述

2. 官网指引

按照一下创建一个项目之后,大概知道了图谱绘制流程,个人觉得和echart使用有点点相似
在这里插入图片描述

3. 找一个实例作自定义修改

1. 先择一个dome图谱

在这里插入图片描述

2. 在vue2+js中使用

1. 创建vue文件并引入import G6 from '@antv/g6';

2. 复制官网图谱实例(附上代码)

我不需要缩小图谱后更换样式,就删除了。

<template>
    <div class="atlasDome">
        <div id="container" class="container">
        </div>
    </div>
</template>

<script>
import G6 from '@antv/g6';
export default {
    name: "atlasDome",
    components: {
    },
    data() {
        return {
            mockData: {
                 id: 'g1',//id是唯一的不能重复
                name: 'Name1',//名字
                label: '538.90',//金额
                currency: 'Yuan',//单位
                rate: 1.0,//百分比进度条
                status: 'B',//三角形颜色,可以模拟预警信息
                variableName: 'V1',//三角形前边小名称
                variableValue: 0.341,//百分比
                variableUp: false,//也是控制三角形样式变化的
                children: [
                    {
                        id: 'g12',
                        name: 'Deal with LONG label LONG label LONG label LONG label',
                        label: '338.00',
                        rate: 0.627,
                        status: 'R',
                        currency: 'Yuan',
                        variableName: 'V2',
                        variableValue: 0.179,
                        variableUp: true,
                        children: [
                            {
                                id: 'g121',
                                name: 'Name3',
                                collapsed: true,
                                label: '138.00',
                                rate: 0.123,
                                status: 'B',
                                currency: 'Yuan',
                                variableName: 'V2',
                                variableValue: 0.27,
                                variableUp: true,
                                children: [
                                    {
                                        id: 'g1211',
                                        name: 'Name4',
                                        label: '138.00',
                                        rate: 1.0,
                                        status: 'B',
                                        currency: 'Yuan',
                                        variableName: 'V1',
                                        variableValue: 0.164,
                                        variableUp: false,
                                        children: [],
                                    },
                                ],
                            },
                            {
                                id: 'g122',
                                name: 'Name5',
                                collapsed: true,
                                label: '100.00',
                                rate: 0.296,
                                status: 'G',
                                currency: 'Yuan',
                                variableName: 'V1',
                                variableValue: 0.259,
                                variableUp: true,
                                children: [],
                            },

                        ],
                    },
                    {
                        id: 'g13',
                        name: 'Name9',
                        label: '100.90',
                        rate: 0.187,
                        status: 'B',
                        currency: 'Yuan',
                        variableName: 'V2',
                        variableValue: 0.221,
                        variableUp: true,
                        children: [
                            {
                                id: 'g131',
                                name: 'Name10',
                                label: '33.90',
                                rate: 0.336,
                                status: 'R',
                                currency: 'Yuan',
                                variableName: 'V1',
                                variableValue: 0.12,
                                variableUp: true,
                                children: [],
                            },
                            {
                                id: 'g132',
                                name: 'Name11',
                                label: '67.00',
                                rate: 0.664,
                                status: 'G',
                                currency: 'Yuan',
                                variableName: 'V1',
                                variableValue: 0.241,
                                variableUp: false,
                                children: [],
                            },
                        ],
                    },
                    {
                        id: 'g14',
                        name: 'Name12',
                        label: '100.00',
                        rate: 0.186,
                        status: 'G',
                        currency: 'Yuan',
                        variableName: 'V2',
                        variableValue: 0.531,
                        variableUp: true,
                        children: [],
                    },
                ],
            }

        };
    },
    computed: {},
    created() {
        this.$nextTick(() => {
            this.initAtial()
        })
    },
    mounted() {
    },
    methods: {
        initAtial() {
            const colors = {
                B: '#5B8FF9',
                R: '#F46649',
                Y: '#EEBC20',
                G: '#5BD8A6',
                DI: '#A7A7A7',
            };

            //  组件props
            const props = {
                data: this.mockData,
                config: {
                    padding: [20, 50],
                    defaultLevel: 3,
                    defaultZoom: 0.8,
                    modes: { default: ['zoom-canvas', 'drag-canvas'] },
                },
            };

            const container = document.getElementById('container');
            const width = container.scrollWidth;
            const height = container.scrollHeight || 500;

            // 默认配置
            const defaultConfig = {
                width,
                height,
                modes: {
                    default: ['zoom-canvas', 'drag-canvas'],
                },
                fitView: true,
                animate: true,
                defaultNode: {
                    type: 'flow-rect',
                },
                defaultEdge: {
                    type: 'extra-shape-edge',
                    // type: 'cubic-horizontal',
                    style: {
                        stroke: '#CED4D9',
                    },
                },
                layout: {
                    type: 'indented',
                    direction: 'LR',
                    dropCap: false,
                    indent: 300,
                    getHeight: () => {
                        return 60;
                    },
                },
            };

            // 自定义节点、边
            const registerFn = () => {
                /**
                 * 自定义节点
                 */
                G6.registerNode(
                    'flow-rect',
                    {
                        shapeType: 'flow-rect',
                        draw(cfg, group) {
                            const {
                                name = '',
                                variableName,
                                variableValue,
                                variableUp,
                                label,
                                collapsed,
                                currency,
                                status,
                                rate
                            } = cfg;

                            const grey = '#CED4D9';
                            const rectConfig = {
                                width: 202,
                                height: 60,
                                lineWidth: 1,
                                fontSize: 12,
                                fill: '#fff',
                                radius: 4,
                                stroke: grey,
                                opacity: 1,
                            };

                            const nodeOrigin = {
                                x: -rectConfig.width / 2,
                                y: -rectConfig.height / 2,
                            };

                            const textConfig = {
                                textAlign: 'left',
                                textBaseline: 'bottom',
                            };

                            const rect = group.addShape('rect', {
                                attrs: {
                                    x: nodeOrigin.x,
                                    y: nodeOrigin.y,
                                    ...rectConfig,
                                },
                            });

                            const rectBBox = rect.getBBox();

                            // 标签标题
                            group.addShape('text', {
                                attrs: {
                                    ...textConfig,
                                    x: 12 + nodeOrigin.x,
                                    y: 20 + nodeOrigin.y,
                                    text: name.length > 28 ? name.substr(0, 28) + '...' : name,
                                    fontSize: 12,
                                    opacity: 0.85,
                                    fill: '#000',
                                    cursor: 'pointer',
                                },
                                // 必须在G6 3.3及更高版本中分配。它可以是你想要的任何字符串,但在自定义项类型中应该是唯一的                                name: 'name-shape',
                            });

                            // 价格
                            const price = group.addShape('text', {
                                attrs: {
                                    ...textConfig,
                                    x: 12 + nodeOrigin.x,
                                    y: rectBBox.maxY - 12,
                                    text: label,
                                    fontSize: 16,
                                    fill: '#000',
                                    opacity: 0.85,
                                },
                            });

                            // 标签的货币
                            group.addShape('text', {
                                attrs: {
                                    ...textConfig,
                                    x: price.getBBox().maxX + 5,
                                    y: rectBBox.maxY - 12,
                                    text: currency,
                                    fontSize: 12,
                                    fill: '#000',
                                    opacity: 0.75,
                                },
                            });

                            // 百分比
                            const percentText = group.addShape('text', {
                                attrs: {
                                    ...textConfig,
                                    x: rectBBox.maxX - 8,
                                    y: rectBBox.maxY - 12,
                                    text: `${((variableValue || 0) * 100).toFixed(2)}%`,
                                    fontSize: 12,
                                    textAlign: 'right',
                                    fill: colors[status],
                                },
                            });

                            // 三角形比例
                            const symbol = variableUp ? 'triangle' : 'triangle-down';
                            const triangle = group.addShape('marker', {
                                attrs: {
                                    ...textConfig,
                                    x: percentText.getBBox().minX - 10,
                                    y: rectBBox.maxY - 12 - 6,
                                    symbol,
                                    r: 6,
                                    fill: colors[status],
                                },
                            });

                            // 变量名
                            group.addShape('text', {
                                attrs: {
                                    ...textConfig,
                                    x: triangle.getBBox().minX - 4,
                                    y: rectBBox.maxY - 12,
                                    text: variableName,
                                    fontSize: 12,
                                    textAlign: 'right',
                                    fill: '#000',
                                    opacity: 0.45,
                                },
                            });

                            // bottom line background
                            const bottomBackRect = group.addShape('rect', {
                                attrs: {
                                    x: nodeOrigin.x,
                                    y: rectBBox.maxY - 4,
                                    width: rectConfig.width,
                                    height: 4,
                                    radius: [0, 0, rectConfig.radius, rectConfig.radius],
                                    fill: '#E0DFE3',
                                },
                            });
                            bottomBackRect.set('capture', false);
                            // bottom percent
                            const bottomRect = group.addShape('rect', {
                                attrs: {
                                    x: nodeOrigin.x,
                                    y: rectBBox.maxY - 4,
                                    width: rate * rectBBox.width,
                                    height: 4,
                                    radius: [0, 0, 0, rectConfig.radius],
                                    fill: colors[status],
                                },
                            });

                            bottomRect.set('capture', false);
                            // 矩形
                            if (cfg.children && cfg.children.length) {
                                group.addShape('rect', {
                                    attrs: {
                                        x: rectConfig.width / 2 - 8,
                                        y: -8,
                                        width: 16,
                                        height: 16,
                                        stroke: 'rgba(0, 0, 0, 0.25)',
                                        cursor: 'pointer',
                                        fill: '#fff',
                                    },
                                    // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type
                                    name: 'collapse-back',
                                    modelId: cfg.id,
                                });

                                // collpase text
                                group.addShape('text', {
                                    attrs: {
                                        x: rectConfig.width / 2,
                                        y: -1,
                                        textAlign: 'center',
                                        textBaseline: 'middle',
                                        text: collapsed ? '+' : '-',
                                        fontSize: 16,
                                        cursor: 'pointer',
                                        fill: 'rgba(0, 0, 0, 0.25)',
                                    },
                                    // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type
                                    name: 'collapse-text',
                                    modelId: cfg.id,
                                });
                            }

                            this.drawLinkPoints(cfg, group);
                            return rect;
                        },
                        update(cfg, item) {
                            const { level, status, name } = cfg;
                            const group = item.getContainer();
                            let mask = group.find(ele => ele.get('name') === 'mask-shape');
                            let maskLabel = group.find(ele => ele.get('name') === 'mask-label-shape');
                            if (level === 0) {
                                group.get('children').forEach(child => {
                                    if (child.get('name')?.includes('collapse')) return;
                                    child.hide();
                                })
                                if (!mask) {
                                    mask = group.addShape('rect', {
                                        attrs: {
                                            x: -101,
                                            y: -30,
                                            width: 202,
                                            height: 60,
                                            opacity: 0,
                                            fill: colors[status]
                                        },
                                        // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type
                                        name: 'mask-shape',
                                    });
                                    maskLabel = group.addShape('text', {
                                        attrs: {
                                            fill: '#fff',
                                            fontSize: 20,
                                            x: 0,
                                            y: 10,
                                            text: name.length > 28 ? name.substr(0, 16) + '...' : name,
                                            textAlign: 'center',
                                            opacity: 0,
                                        },
                                        // must be assigned in G6 3.3 and later versions. it can be any string you want, but should be unique in a custom item type
                                        name: 'mask-label-shape',
                                    });
                                    const collapseRect = group.find(ele => ele.get('name') === 'collapse-back');
                                    const collapseText = group.find(ele => ele.get('name') === 'collapse-text');
                                    collapseRect?.toFront();
                                    collapseText?.toFront();
                                } else {
                                    mask.show();
                                    maskLabel.show();
                                }
                                mask.animate({ opacity: 1 }, 200);
                                maskLabel.animate({ opacity: 1 }, 200);
                                return mask;
                            } else {
                                group.get('children').forEach(child => {
                                    if (child.get('name')?.includes('collapse')) return;
                                    child.show();
                                })
                                mask?.animate({ opacity: 0 }, {
                                    duration: 200,
                                    callback: () => mask.hide()
                                });
                                maskLabel?.animate({ opacity: 0 }, {
                                    duration: 200,
                                    callback: () => maskLabel.hide()
                                });
                            }
                            this.updateLinkPoints(cfg, group);
                        },
                        setState(name, value, item) {
                            if (name === 'collapse') {
                                const group = item.getContainer();
                                const collapseText = group.find((e) => e.get('name') === 'collapse-text');
                                if (collapseText) {
                                    if (!value) {
                                        collapseText.attr({
                                            text: '-',
                                        });
                                    } else {
                                        collapseText.attr({
                                            text: '+',
                                        });
                                    }
                                }
                            }
                        },
                        getAnchorPoints() {
                            return [
                                [0, 0.5],
                                [1, 0.5],
                            ];
                        },
                    },
                    'rect',
                );

                G6.registerEdge(
                    'flow-cubic',
                    {
                        getControlPoints(cfg) {
                            let controlPoints = cfg.controlPoints; // 指定controlPoints
                            if (!controlPoints || !controlPoints.length) {
                                const { startPoint, endPoint, sourceNode, targetNode } = cfg;
                                const { x: startX, y: startY, coefficientX, coefficientY } = sourceNode
                                    ? sourceNode.getModel()
                                    : startPoint;
                                const { x: endX, y: endY } = targetNode ? targetNode.getModel() : endPoint;
                                let curveStart = (endX - startX) * coefficientX;
                                let curveEnd = (endY - startY) * coefficientY;
                                curveStart = curveStart > 40 ? 40 : curveStart;
                                curveEnd = curveEnd < -30 ? curveEnd : -30;
                                controlPoints = [
                                    { x: startPoint.x + curveStart, y: startPoint.y },
                                    { x: endPoint.x + curveEnd, y: endPoint.y },
                                ];
                            }
                            return controlPoints;
                        },
                        getPath(points) {
                            const path = [];
                            path.push(['M', points[0].x, points[0].y]);
                            path.push([
                                'C',
                                points[1].x,
                                points[1].y,
                                points[2].x,
                                points[2].y,
                                points[3].x,
                                points[3].y,
                            ]);
                            return path;
                        },
                    },
                    'single-line',
                );
            };

            registerFn();

            const { data } = props;
            let graph = null;

            const initGraph = (data) => {
                if (!data) {
                    return;
                }
                const { onInit, config } = props;
                const tooltip = new G6.Tooltip({
                    // offsetX和offsetY包含父容器的内边距
                    offsetX: 20,
                    offsetY: 30,
                    // 允许工具提示显示的项目类型
                    // 允许出现 tooltip 的 item 类型
                    itemTypes: ['node'],
                    // 自定义提示条的内容
                    // 自定义 tooltip 内容
                    getContent: (e) => {
                        const outDiv = document.createElement('div');
                        //outDiv.style.padding = '0px 0px 20px 0px';
                        const nodeName = e.item.getModel().name;
                        let formatedNodeName = '';
                        for (let i = 0; i < nodeName.length; i++) {
                            formatedNodeName = `${formatedNodeName}${nodeName[i]}`;
                            if (i !== 0 && i % 20 === 0) formatedNodeName = `${formatedNodeName}<br/>`;
                        }
                        outDiv.innerHTML = `${formatedNodeName}`;
                        return outDiv;
                    },
                    shouldBegin: (e) => {
                        if (e.target.get('name') === 'name-shape' || e.target.get('name') === 'mask-label-shape') return true;
                        return false;
                    },
                });
                graph = new G6.TreeGraph({
                    container: 'container',
                    ...defaultConfig,
                    ...config,
                    plugins: [tooltip],
                });
                if (typeof onInit === 'function') {
                    onInit(graph);
                }
                graph.data(data);
                graph.render();

                const handleCollapse = (e) => {
                    const target = e.target;
                    const id = target.get('modelId');
                    const item = graph.findById(id);
                    const nodeModel = item.getModel();
                    nodeModel.collapsed = !nodeModel.collapsed;
                    graph.layout();
                    graph.setItemState(item, 'collapse', nodeModel.collapsed);
                };
                graph.on('collapse-text:click', (e) => {
                    handleCollapse(e);
                });
                graph.on('collapse-back:click', (e) => {
                    handleCollapse(e);
                });



            };

            initGraph(data);

            if (typeof window !== 'undefined')
                window.onresize = () => {
                    console.log(container.scrollWidth, container.scrollHeight)
                    if (!graph || graph.get('destroyed')) return;
                    if (!container || !container.scrollWidth || !container.scrollHeight) return;
                    graph.changeSize(container.scrollWidth, container.scrollHeight);
                };
        }

    }
};
</script>

<style lang="scss" scoped>
.atlasDome {
    width: 1920px;
    height: 1080px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #03132F;

}

.container {
    width: 1000px;
    height: 800px;
    background-color: #ffffff;
}
</style>

3. 设置流动线,链接线上自定义一个运动的小球

1. 官网dome地址

https://g6.antv.antgroup.com/zh/examples/scatter/edge/#edge
在这里插入图片描述

2. 结合官网修改代码

在这里插入图片描述

     // 使用额外的矩形自定义边缘
            G6.registerEdge(
                'extra-shape-edge',
                {
                    afterDraw(cfg, group) {
                        // 获取图形组中的第一个图形,在这里就是边的路径图形
                        const shape = group.get('children')[0];
                        // 获取路径上的0.25位点坐标 // 在该点上放置一个圆形
                        const quatile = shape.getPoint(0.25);
                        const quatileColor = cfg.quatileColor || '#9cdff1';//这里可以在数据中设置,来动态更新颜色

                        const circle = group.addShape('circle', {
                            attrs: {
                                r: 3,
                                fill: quatileColor || '#9cdff1',
                                x: quatile.x,
                                y: quatile.y,
                            },
                        });
                        circle.animate(
                            (ratio) => {
                                ratio ;
                                const tmpPoint = shape.getPoint(ratio);
                                return {
                                    x: tmpPoint.x,
                                    y: tmpPoint.y,
                                };
                            },
                            {
                                repeat: true, // 是否重复执行动画
                                duration: 2000, // the duration for executing once
                            },
                        ); 
                        let index = 0;
                        // 定义动画逻辑
                        shape.animate(
                            () => {
                                index -= 0.8;
                                if (index > 55) {
                                    index = 0;
                                }
                                // 设置线型和线型偏移量
                                const res = {
                                    lineDash:[4, 2, 1, 2], // 设置虚线的实际线段长度和间隔长度
                                    lineDashOffset: -index, // 设置虚线的偏移量
                                };
                                // 返回修改后的配置,包括线型和线型偏移量
                                return res;
                            },
                            {
                                repeat: true, // 是否循环执行动画
                                duration: 5000,// 单次动画执行的时间
                            },
                        );
                    },
                    update: undefined,
                },
                'cubic',
            );

3. 运行后样式

屏幕录制2023-09-11 14.03.38

4 . 更新图谱

要把graph设置成全局变量或者放在this上

       <button @click="update"> 更新图谱</button>
        // 更新图谱
        update() {
            // graph是Graph的实例
            graph.changeData(this.mockData);
            // 若不指定该参数,则使用当前图上的数据重新渲染
            graph.changeData();
            // 根据提供的数据渲染视图。
            graph.render();
        }

5. 支点跟随–聚焦一个节点

1. 官网地址

https://g6.antv.antgroup.com/zh/examples/interaction/position/#moveAnimate
在这里插入图片描述

2. graph.render();后添加聚焦节点代码

    function handleNodeClick(event) {
                    const item = event.item;
                    // animately move the graph to focus on the item.
                    // the second parameter controlls whether move with animation, the third parameter is the animate configuration
                    graph.focusItem(item, true, {
                        easing: 'easeCubic',
                        duration: 500,
                    });
                }

                // listen to the node click event
                graph.on('node:click', handleNodeClick);

3. 运行后效果

聚焦节点

下篇地址自定义卡片–收缩节点并添加动画–自定义弹窗样式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1011564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis缓存更新策略、详解并发条件下数据库与缓存的一致性问题以及消息队列解决方案

0、前言 我们知道&#xff0c;缓存由于在内存中&#xff0c;数据处理速度比直接操作数据库要快很多&#xff0c;因此常常将数据先读到缓存中&#xff0c;再进行查询、更新等操作。 但与之而来的问题就是&#xff0c;内存中的数据不仅没有持久化&#xff0c;而且需要保证…

Dajngo02_第一个Django案例

Dajngo02_第一个Django案例 经过之前学习&#xff0c;我们已经可以创建Django环境 现在开始尝试快速使用Django开发一个案例 案例&#xff1a;利用Django实现一个查看当前时间的web页面。 在django中要提供数据展示给用户,一般情况下我们需要完成3个步骤&#xff1a; 在urls.…

如何选择合适的预测性维护工具和平台

随着技术的不断进步&#xff0c;预测性维护&#xff08;Predictive Maintenance&#xff0c;简称PdM&#xff09;已经成为许多企业提高生产效率、减少停机时间和维护成本的核心策略。然而&#xff0c;选择适合自己业务需求的PdM工具和平台可能并不容易。本文将为您提供一些关键…

传统机器学习总结以及深度学习初识

传统机器学习总结以及深度学习初识 文章目录 前言一、传统机器学习总结1.1. 监督学习算法&#xff08;Supervised Learning&#xff09;1.2. 无监督学习算法&#xff08;Unsupervised Learning&#xff09; 二、深度学习初识三、github与gitee的介绍3.1. GitHub&#xff1a;3.2…

Sqlserver 监控使用磁盘空间情况

最近遇到一个小问题&#xff1a;为了保存以往的一些数据&#xff0c;间了大量临时表&#xff0c;导致SQLserver 数据增长过快&#xff0c;不得不想个办法监控磁盘空间使用情况。 网上一般有几种办法&#xff1a; 一是使用 dm_os_volume_stats函数&#xff0c;缺点是 无法获取非…

【实践篇】MySQL执行计划详解

文章目录 本文知识大纲速览1. 前言2. 基本介绍1. 什么是执行计划2. 如何查看执行计划3. 执行计划的组成部分 3. 执行计划的关键元素1. id2. select_type3. table:4. type:5. possible_keys:6. key:7. key_len8. ref:9. rows:10. Extra 4. 底层原理5. 执行计划示例解读本文知识图…

本地引入 Axios 报错

目录 报错信息&#xff1a; 报错截图&#xff1a; ​编辑报错原因&#xff1a; 解决方法&#xff1a; ​编辑运行结果成功&#xff1a; 报错信息&#xff1a; Cannot read properties of undefined (reading post) TypeError: Cannot read properties of undefined (rea…

SpringBoot,Mybatis 使用Java8(JSR310)时间日期规范

目录 一. 依赖二. 前台三. Controller&#xff0c;Form&#xff0c;Service四. 数据库类型五. 效果 一. 依赖 ⏹若使用的是SpringBoot <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifac…

Microsoft 365跨平台协同办公功能,实现Mac、iOS、Windows用户的实时无缝协作

Microsoft 365 for Mac(Office 365)现已更新&#xff0c;最新版本的Microsoft 365 现已支持跨平台协同办公&#xff0c;接下来为你介绍一些使用office 365 Mac版进行创作及写作的好方法。 Microsoft 365 在全平台共用相同的代码库&#xff0c;这意味着使用 Mac、ios 和Windows…

【日积月累】SpringBoot启动流程

目录 SpringBoot启动流程 1.前言2.构造一个SpringApplication的实例&#xff0c;完成初始化的工作SpringApplication实例构造完之后调用run方法&#xff0c;启动SpringApplication3.SpringBoot启动代码SpringBootConfigurationComponentScanEnableAutoConfiguration 总结参考…

随手笔记(四十六)——idea source root错乱

一般问题会出现在这里&#xff0c;写着别的项目的项目名&#xff0c;就是因为reload了别的项目的maven文件&#xff0c;借鉴了很多网上的说法&#xff0c;比如改project Structure里面改子项目的source。确实讲得挺好&#xff0c;就是不会用&#xff1b;所以最后的解决方案就是…

多云系列|10个关键的多云战略:简介

随着VMware继续向客户介绍多云问题以及VMware跨云服务在云智能计算历程中的优势&#xff0c;有一个问题经常被提及&#xff0c;“我如何开始&#xff1f;”。本博客系列旨在为客户提供指导&#xff0c;并回顾多云的十大领域&#xff0c;介绍我们应该关注哪些方面。此外&#xf…

引领UI设计生产工具进入AI时代,猿辅导旗下Motiff发布三大AI功能

近期&#xff0c;IXDC 2023国际体验设计大会在北京国家会议中心举行&#xff0c;共邀请全球800企业&#xff0c;1000名设计师共襄主题为“设计领导力”的创新盛会。作为全球最具影响力的创新设计大会之一&#xff0c;大会围绕创新、系统、商业三个关键维度&#xff0c;结合在AI…

MySQL优化第二篇

MySQL优化第二篇 性能分析小表驱动大表慢查询日志日志分析工具mysqldumpslow Show Profile进行SQL分析&#xff08;重中之重&#xff09; 七种JOIN 1、inner join &#xff1a;可以简写为join&#xff0c;表示的是交集&#xff0c;也就是两张表的共同数据 sql语句&#xff1a…

Recognize Anything:一个强大的图像标记模型

Recognize Anything是一种新的图像标记基础模型&#xff0c;与传统模型不同&#xff0c;它不依赖于手动注释进行训练;相反&#xff0c;它利用大规模的图像-文本对。RAM的开发过程包括四个关键阶段: 通过自动文本语义解析获得大规模的无标注图像标签。结合标题和标注任务&#…

网络电视盒子哪个品牌好?测评工作室深入分析电视盒子排名

电视盒子只需要联网就可以收看海量资源&#xff0c;不需要每月缴费&#xff0c;玩游戏、上网课、K歌都不在话下&#xff0c;对新手来说电视盒子如何选择&#xff1f;网络电视盒子哪个品牌好&#xff1f;工作室购入了最热销的15款电视盒子经过多角度对比后整理了电视盒子排名&am…

Linux内核源码分析 (B.x)Linux页表的映射

Linux内核源码分析 (B.x)Linux页表的映射 文章目录 Linux内核源码分析 (B.x)Linux页表的映射一、ARM32页表1、页表术语2、虚拟地址到物理地址转换3、一级页表项4、二级页表项 二、ARM64页表1、ARMv8-A架构2、4KB大小页4级映射 三、Linux内核中关于页表的函数和宏1、查询页表2、…

第三方ipad笔哪个牌子好用?开学季比较好用的电容笔

新学期有什么电容笔值得入手&#xff1f;这款平替电容笔&#xff0c;名为Apple Pencil&#xff0c;唯一的区别就是它的压力感应功能&#xff0c;同时拥有重力压感以及倾斜压感&#xff0c;而平替电容笔仅只拥有倾斜压感一种功能&#xff0c;不过它的压力感应能力很强&#xff0…

034:vue项目利用qrcodejs2生成二维码示例

第034个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

无涯教程-JavaScript - IF函数

描述 如果条件为TRUE,则IF函数返回一个值,如果条件为FALSE,则返回另一个值。 语法 IF (logical_test, value_if_true, [value_if_false]) 争论 Argument描述Required/Optionallogical_testThe condition you want to test.Requiredvalue_if_trueThe value that you want re…