LogicFlow 学习笔记——4. LogicFlow 基础 边 Edge

2024-06-13 20:52

本文主要是介绍LogicFlow 学习笔记——4. LogicFlow 基础 边 Edge,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

边 Edge

和节点一样,LogicFlow 也内置一些基础的边。LogicFlow 的内置边包括:

  1. 直线 - line
  2. 直角折现 - polyline
  3. 贝塞尔曲线 - bezier

新建 src/views/Example/LogicFlow/Example08.vue 并编写如下代码:

<script setup lang="ts">
// 导入 LogicFlow 库及其样式
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'
// 导入 Vue 的 onMounted 钩子,用于组件挂载后的操作
import { onMounted } from 'vue'// 配置项,用于设定 LogicFlow 的交互模式,禁止图表的滚动、移动和缩放功能
const SilentConfig = {stopScrollGraph: true,stopMoveGraph: true,stopZoomGraph: true
}// 定义图表数据,包括各种形状的节点和连接它们的边
const data = {nodes: [{id: '1', // 节点的唯一标识符type: 'rect', // 节点的类型为矩形x: 100, // 矩形的 x 坐标y: 100, // 矩形的 y 坐标text: '矩形1' // 节点上显示的文本},{id: '2',type: 'ellipse', // 节点类型为椭圆x: 500,y: 100,text: '椭圆2'},{id: '3',type: 'polygon', // 节点类型为多边形x: 100,y: 250,text: '多边形3'},{id: '4',type: 'diamond', // 节点类型为菱形x: 300,y: 250,text: '菱形4'}],edges: [{sourceNodeId: '1', // 边的起始节点 IDtargetNodeId: '2', // 边的目标节点 IDstartPoint: {x: 100, // 起始点的 x 坐标y: 60 // 起始点的 y 坐标},endPoint: {x: 500, // 结束点的 x 坐标y: 50 // 结束点的 y 坐标},type: 'polyline' // 连接线类型为折线},{sourceNodeId: '2',targetNodeId: '3',type: 'line' // 连接线类型为直线},{sourceNodeId: '2',targetNodeId: '4',type: 'bezier' // 连接线类型为贝塞尔曲线}]
}// 当 Vue 组件挂载完成后执行的操作
onMounted(() => {// 创建 LogicFlow 实例,并指定容器和其他配置const lf = new LogicFlow({container: document.getElementById('container')!, // 获取 DOM 元素作为图表的容器grid: true, // 启用网格...SilentConfig // 应用静默模式配置})// 使用预定义的数据渲染图表lf.render(data)lf.translateCenter() // 将图表内容居中显示
})
</script><template><h3>Example08</h3><div id="container"></div><!-- 容器用于展示 LogicFlow 图表 -->
</template><style>
#container {/* 定义容器的宽度和高度 */width: 100%;height: 500px;
}
</style>

运行后效果如下:
在这里插入图片描述

选择自定义边继承的内置边

// 直线
import { LineEdge, PolylineEdgeModel } from "@logicflow/core";
// 折线
import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
// 贝塞尔曲线
import { BezierEdge, BezierEdgeModel } from "@logicflow/core";

基于继承的自定义边

和节点一样,LogicFlow 的边也支持基于继承的自定义机制。同样也只需同时继承viewmodel。但是和节点不一样的是,由于边的编辑复杂度问题,绝大多数情况下,自定义边时不推荐自定义 view。只需要在自定义 edgeModel 中样式类即可。

新建 src/views/Example/LogicFlow/component/Sequence/index.ts 代码内容如下:

// 从 @logicflow/core 导入 PolylineEdge 和 PolylineEdgeModel 类
import { PolylineEdge, PolylineEdgeModel } from '@logicflow/core'// 创建一个名为 SequenceModel 的类,继承自 PolylineEdgeModel
class SequenceModel extends PolylineEdgeModel {// 设置属性方法setAttributes() {this.offset = 20 // 设置折线的偏移量为 20,这可能影响折线的布局或外观}// 获取动画样式方法getAnimation() {const animation = super.getAnimation() // 调用父类的方法获取默认动画设置animation.stroke = 'blue' // 设置动画的颜色为蓝色return animation // 返回配置后的动画对象}// 获取边的样式方法getEdgeStyle() {const style = super.getEdgeStyle() // 调用父类的方法获取默认边的样式const { properties } = this // 从当前模型中获取属性if (properties.isActived) {style.strokeDasharray = '4 4' // 如果边处于激活状态,设置虚线样式}style.stroke = 'orange' // 设置边的颜色为橙色return style // 返回配置后的样式对象}// 获取文本样式方法getTextStyle() {const style = super.getTextStyle() // 调用父类的方法获取默认文本样式style.color = '#3451F1' // 设置文本颜色为深蓝色style.fontSize = 30 // 设置文本字体大小为 30if (style.background) {style.background.fill = '#F2F131' // 如果有背景,设置背景颜色为浅黄色}return style // 返回配置后的文本样式}// 获取轮廓样式方法getOutlineStyle() {const style = super.getOutlineStyle() // 调用父类的方法获取默认轮廓样式style.stroke = 'red' // 设置轮廓的颜色为红色if (style.hover) {style.hover.stroke = 'red' // 如果有悬停样式,设置悬停时轮廓的颜色也为红色}return style // 返回配置后的轮廓样式}
}// 导出一个对象,包含类型、视图和模型的配置
export default {type: 'Sequence', // 自定义边的类型标识view: PolylineEdge, // 使用 PolylineEdge 作为视图model: SequenceModel // 使用 SequenceModel 作为模型
}

之后新增 src/views/Example/LogicFlow/Example09.vue,内容如下:

<script setup lang="ts">
// 导入 LogicFlow 库及其样式
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'
// 导入 Vue 的 onMounted 钩子,用于组件挂载后的操作
import { onMounted } from 'vue'
import Sequence from './component/Sequence'// 配置项,用于设定 LogicFlow 的交互模式,禁止图表的滚动、移动和缩放功能
const SilentConfig = {stopScrollGraph: true,stopMoveGraph: true,stopZoomGraph: true
}// 定义图表数据,包括各种形状的节点和连接它们的边
const data = {nodes: [{id: '1',type: 'rect',x: 100,y: 100,text: '矩形'},{id: '2',type: 'circle',x: 300,y: 100,text: '圆形'},{id: '3',type: 'ellipse',x: 500,y: 100,text: '椭圆'},{id: '4',type: 'polygon',x: 100,y: 250,text: '多边形'},{id: '5',type: 'diamond',x: 300,y: 250,text: '菱形'},{id: '6',type: 'text',x: 500,y: 250,text: '纯文本节点'}],edges: [{sourceNodeId: '1',targetNodeId: '3',startPoint: {x: 100,y: 60},endPoint: {x: 500,y: 50},text: '333',type: 'Sequence'},{sourceNodeId: '3',targetNodeId: '4',type: 'line'},// TODO{sourceNodeId: '3',targetNodeId: '5',type: 'bezier'}]
}// 当 Vue 组件挂载完成后执行的操作
onMounted(() => {// 创建 LogicFlow 实例,并指定容器和其他配置const lf = new LogicFlow({container: document.getElementById('container')!, // 获取 DOM 元素作为图表的容器grid: true, // 启用网格...SilentConfig // 应用静默模式配置})lf.register(Sequence)// 使用预定义的数据渲染图表lf.render(data)lf.translateCenter() // 将图表内容居中显示
})
</script><template><h3>Example08</h3><div id="container"></div><!-- 容器用于展示 LogicFlow 图表 -->
</template><style>
#container {/* 定义容器的宽度和高度 */width: 100%;height: 500px;
}
</style>

页面效果如下:
在这里插入图片描述

自定义边文本位置

默认情况下,边上文本的位置是用户双击点击边时的位置。如果是通过 API 的方式给边添加的文本,文本位置按照如下规则。

  • line:起点和终点中间
  • poyline:最长线段中间
  • bezier:起点、终点、调整点中间
    LogicFlow支持开发者自定义文本位置,例如文本位置永远在边起点旁边。定义方式为将属性customTextPosition设置为 true,然后重写getTextPosition方法,此方法发回的坐标就是文本的坐标。

新建 src/views/Example/LogicFlow/component/CustomEdge2/index.ts 代码如下:

// 导入 @logicflow/core 中的 PolylineEdge 和 PolylineEdgeModel
import { PolylineEdge, PolylineEdgeModel } from '@logicflow/core'// 定义一个自定义的边模型
class CustomEdgeModel extends PolylineEdgeModel {customTextPosition = true // 设置一个属性来标识是否自定义文本位置getTextStyle() {const style = super.getTextStyle() // 获取默认的文本样式// const { x: x1 } = this.pointsList[0];// const { x: x2 } = this.pointsList[1];// // if (x1 === x2) {// //   // 垂直// //   style.textWidth = 20;// // } else {// //   style.textWidth = 200;// // }style.className = 'custom-text' // 为文本样式添加一个自定义的类名,用于CSS样式定制return style}// 重写获取文本位置的方法getTextPosition() {const position = super.getTextPosition() // 获取默认的文本位置const currentPositionList = this.points.split(' ') // 将点列表字符串分割为单个点const pointsList = [] // 初始化一个数组来存储点对象// 遍历当前点列表,将字符串转换为点对象currentPositionList &&currentPositionList.forEach((item) => {const [x, y] = item.split(',')pointsList.push({ x: Number(x), y: Number(y) })})if (currentPositionList.length > 1) {let [x1, y1]: string[] | number[] = currentPositionList[0].split(',')let [x2, y2]: string[] | number[] = currentPositionList[1].split(',')let distence = 50 // 设置默认文本偏移距离x1 = Number(x1)y1 = Number(y1)x2 = Number(x2)y2 = Number(y2)// 计算文本的新位置,根据点的相对位置来调整if (x1 === x2) {// 如果 x 坐标相同,表示线是垂直的// 垂直if (y2 < y1) {distence = -50 // 如果第二个点在第一个点之上,调整偏移方向}position.y = y1 + distenceposition.x = x1} else {// 如果线是水平的或斜的if (x2 < x1) {distence = -50 // 如果第二个点在第一个点之左,调整偏移方向}position.x = x1 + distenceposition.y = y1 - 10 // 小幅下移文本,使其不直接覆盖在线上}}return position}
}class CustomEdge extends PolylineEdge {}export default {type: 'CustomEdge2',model: CustomEdgeModel,view: CustomEdge
}

之后新增 src/views/Example/LogicFlow/Example10.vue 代码如下:

<script setup lang="ts">
// 导入 LogicFlow 库及其样式
import LogicFlow from '@logicflow/core'
import '@logicflow/core/dist/style/index.css'
// 导入 Vue 的 onMounted 钩子,用于组件挂载后的操作
import { onMounted } from 'vue'
import CustomEdge2 from './component/CustomEdge2'// 配置项,用于设定 LogicFlow 的交互模式,禁止图表的滚动、移动和缩放功能
const SilentConfig = {stopScrollGraph: true,stopMoveGraph: true,stopZoomGraph: true
}// 定义图表数据,包括各种形状的节点和连接它们的边
const data = {nodes: [{id: 'rect_2',type: 'circle',x: 450,y: 300},{id: 'rect_3',type: 'rect',x: 150,y: 100}],edges: [{sourceNodeId: 'rect_3',targetNodeId: 'rect_2',type: 'CustomEdge2',text: '连线文本'}]
}// 当 Vue 组件挂载完成后执行的操作
onMounted(() => {// 创建 LogicFlow 实例,并指定容器和其他配置const lf = new LogicFlow({container: document.getElementById('container')!, // 获取 DOM 元素作为图表的容器grid: true, // 启用网格...SilentConfig // 应用静默模式配置})lf.register(CustomEdge2)lf.setDefaultEdgeType('CustomEdge2')lf.setTheme({edgeText: {textWidth: 100,overflowMode: 'autoWrap',fontSize: 10,background: {fill: '#FFFFFF'}}})// 使用预定义的数据渲染图表lf.render(data)lf.translateCenter() // 将图表内容居中显示
})
</script><template><h3>Example10</h3><div id="container"></div><!-- 容器用于展示 LogicFlow 图表 -->
</template><style>
#container {/* 定义容器的宽度和高度 */width: 100%;height: 500px;
}
</style>

页面结果如下:
在这里插入图片描述

自定义节点之间边的类型

默认情况下,通过从锚点手动连接节点生成的边为初始化edgeType指定的类型,也可以通过lf.setDefaultEdgeType(edgeType)来指定。但是当需要不同的节点之间连接的边类型不一样时,就只有自定义节点之间边的类型了。

const lf = new LogicFlow({...,// 默认边edgeType: 'bezier',// 移动已有边时会有 currentEdge 信息, 否则为空edgeGenerator: (sourceNode, targetNode, currentEdge) => {// 起始节点类型 rect 时使用 自定义的边 custom-edgeif (sourceNode.type === 'rect') return 'custom-edge'}
})

自定义箭头

1.1.27版本后,LogicFlow支持单独自定义连线两端的箭头。和之前的自定义方式一样,支持通过主题自定义大小等基本数据和通过重写对应的方法实现完全的自定义。

主题设置

lf.setTheme({arrow: {offset: 4, // 箭头垂线长度verticalLength: 2, // 箭头底线长度},
});

自定义箭头形状

在自定义连线 view 的时候,可以重写 getEndArrowgetStartArrow 方法来实现自定义连线两端的图形,这两个方法可以返回的任意 svg 图形。
这里以通过连线属性中的 arrowType 来控制连线不同的外观为例。

class Connection extends PolylineEdge {getEndArrow() {const { model, graphModel } = this.props;const {id,properties: { arrowType },} = model;const { stroke, strokeWidth } = this.getArrowStyle();const pathAttr = {stroke,strokeWidth,};if (arrowType === "empty") {// 空心箭头return h("path", {...pathAttr,fill: "#FFF",d: "M -10 0  -20 -5 -30 0 -20 5 z",});} else if (arrowType === "half") {// 半箭头return h("path", {...pathAttr,d: "M 0 0 -10 5",});}return h("path", {...pathAttr,d: "M 0 0 -10 -5 -10 5 z",});}
}

自定义调整点样式

在初始化 LogicFlow 实例的时候,可以通过参数 adjustEdgeStartAndEnd 来开启调整边的起始点和结束点的功能。

在自定义连线 view 的时候,可以重写 getAdjustPointShape 方法来实现自定义调整点的样式。

// lf.js
const lf = new LogicFlow({adjustEdgeStartAndEnd: true,
});
// edge.js
class CustomEdge extends LineEdge {getAdjustPointShape(x, y, edgeModel) {return h("g", {}, [h("image", {x: x - 9,y: y - 9,width: 18,height: 18,cursor: "move",href: "data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIyMnB4IiBoZWlnaHQ9IjIycHgiIHZlcnNpb249IjEuMSI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iNyIgc3Ryb2tlPSIjZmZmIiBmaWxsPSIjMjliNmYyIi8+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iMyIgc3Ryb2tlPSIjZmZmIiBmaWxsPSJ0cmFuc3BhcmVudCIvPjwvc3ZnPg==",}),]);}
}

以下为完整的样例代码,新建 src/views/Example/LogicFlow/Example11.vue 代码如下:

<script setup lang="ts">
// 导入 LogicFlow 核心库及其样式
import LogicFlow, {h, // 用于创建虚拟DOM节点LineEdge, // 基础线边类LineEdgeModel, // 基础线边模型PolylineEdge, // 基础折线边类PolylineEdgeModel // 基础折线边模型
} from '@logicflow/core'
import '@logicflow/core/dist/style/index.css' // 导入默认样式// 导入 Vue 的 onMounted 生命周期钩子
import { onMounted } from 'vue'
// 导入自定义边模块
import CustomEdge2 from './component/CustomEdge2'// 配置项,用于限制用户交互,禁用图形的滚动、移动和缩放功能
const SilentConfig = {stopScrollGraph: true,stopMoveGraph: true,stopZoomGraph: true
}// 自定义的连接类继承自 PolylineEdge,用于定义箭头的类型和样式
class Connection extends PolylineEdge {getEndArrow() {const { model } = this.props // 获取边的模型属性const {properties: { arrowType }} = model // 从模型中提取箭头类型const { stroke, strokeWidth } = model.getArrowStyle() // 获取箭头的样式const pathAttr = {stroke,strokeWidth}// 根据箭头类型返回不同的 SVG path 元素if (arrowType === 'empty') {// 空心箭头return h('path', {...pathAttr,fill: '#FFF',d: 'M -10 0  -20 -5 -30 0 -20 5 z'})} else if (arrowType === 'half') {// 半箭头return h('path', {...pathAttr,d: 'M 0 0 -10 5'})}// 默认实心箭头return h('path', {...pathAttr,d: 'M 0 0 -10 -5 -10 5 z'})}
}// 自定义的边视图,用于自定义边上的控制点形状
class CustomEdge extends LineEdge {getAdjustPointShape(x: any, y: any, edgeModel: any) {console.log(edgeModel) // 打印边模型信息// 返回一个含有 SVG 图像的组,用于表示控制点return h('g', {}, [h('image', {x: x - 9,y: y - 9,width: 18,height: 18,cursor: 'move',href: 'data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSIyMnB4IiBoZWlnaHQ9IjIycHgiIHZlcnNpb249IjEuMSI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iNyIgc3Ryb2tlPSIjZmZmIiBmaWxsPSIjMjliNmYyIi8+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iMyIgc3Ryb2tlPSIjZmZmIiBmaWxsPSJ0cmFuc3BhcmVudCIvPjwvc3ZnPg=='})])}
}// 定义图表数据,包括节点和边
const data = {nodes: [// 定义节点信息{id: 'rect_2',type: 'circle',x: 450,y: 300},{id: 'rect_3',type: 'rect',x: 300,y: 100},{id: 'rect_4',type: 'rect',x: 100,y: 100}],edges: [// 定义边信息{sourceNodeId: 'rect_4',targetNodeId: 'rect_2',type: 'CustomEdge',text: '连线文本1',startPoint: {x: 100,y: 100 + 40}},{sourceNodeId: 'rect_4',targetNodeId: 'rect_3',type: 'Connection',text: '连线文本2',startPoint: {x: 100,y: 100 - 40},endPoint: {x: 300,y: 100 - 40},pointsList: [{x: 100,y: 100 - 40},{x: 100,y: 100 - 80},{x: 300,y: 100 - 80},{x: 300,y: 100 - 40}],properties: {arrowType: 'empty' // 指定箭头类型}},{sourceNodeId: 'rect_3',targetNodeId: 'rect_2',type: 'CustomEdge2',text: '连线文本3'}]
}// 在 Vue 组件挂载后,初始化 LogicFlow 实例并渲染图表
onMounted(() => {const lf = new LogicFlow({container: document.getElementById('container')!, // 指定图表的 DOM 容器grid: true, // 启用网格显示adjustEdgeStartAndEnd: true, // 自动调整边的起始和结束位置...SilentConfig // 应用静默模式配置})lf.register(CustomEdge2) // 注册自定义边类型lf.register({type: 'Connection',model: PolylineEdgeModel,view: Connection})lf.register({type: 'CustomEdge',model: LineEdgeModel,view: CustomEdge})lf.setDefaultEdgeType('CustomEdge2') // 设置默认边类型lf.setTheme({edgeText: {textWidth: 100, // 设置文本框宽度overflowMode: 'autoWrap', // 自动换行模式fontSize: 10, // 字体大小background: {fill: '#FFFFFF' // 文本背景色}}})lf.render(data) // 渲染图表数据lf.translateCenter() // 居中显示图表
})
</script><template><h3>Example10</h3><div id="container"></div><!-- 图表容器 -->
</template><style>
#container {width: 100%;height: 500px;
}
</style>

效果如下:
在这里插入图片描述


样例代码
官方文档


这篇关于LogicFlow 学习笔记——4. LogicFlow 基础 边 Edge的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1058400

相关文章

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

Vim使用基础篇

本文内容大部分来自 vimtutor,自带的教程的总结。在终端输入vimtutor 即可进入教程。 先总结一下,然后再分别介绍正常模式,插入模式,和可视模式三种模式下的命令。 目录 看完以后的汇总 1.正常模式(Normal模式) 1.移动光标 2.删除 3.【:】输入符 4.撤销 5.替换 6.重复命令【. ; ,】 7.复制粘贴 8.缩进 2.插入模式 INSERT

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口