当前位置: 首页 > news >正文

d3.js

D3:Data-Driven Documents
• 通过D3提供的接口来基于数据操控文档的各个图元。

标题对于D3(本讲解)最为重要的标签,主要操作的对象(画布)

HTML - 导入D3.js
D3.js作为JavaScript的外库,必须先将其导入,如:

  • Python的import,C/C++的include、

  • Java的import、node.js的require… … …

  • 通过Script标签导入

    1. 直接通过互联网链接
      https://d3js.org/d3.v5.min.js
    2. 通过本地服务器链接(推荐)
      ./d3.min.js
    3. 通过unpkg链接
      https://unpkg.com/browse/d3@5.15.0/dist/d3.js

    尽可能使用本地的d3.min.js库。

svg-可缩放矢量模型

  • svg d3用来绘制的"画布"
  • 可缩放矢量图形(英语:scalable vector graphics,svg)
  • svg是d3.js主要操作的对象
    • const svg=de3.select(‘svg’)
    • d3.js获取svg对象
  • svg同时也是一个容器,用于包含画在上面的各个图元
  • svg作为矢量图,不会随着图片的缩放而发生失真

image.png

引入svg

  <svg height="200" width="200" style="display:block;margin:0 auto"><g transfrom="translate(0,60)"><rect width=100 height=100 fill="#eee" /><circle r=15 fill="#72bf67" cx=25 cy=30></circle><circle r=15 fill="RGB(100,149,237)" cx=75 cy=30></circle><g transform="translate(15,60) rotate(10)"><path d="M0,0 A40,40 10 0,0 65,0" fill="none" stroke="gray" stroke-width=5></path></g></g></svg>

HTML–文档对象模型

  • HTML -> DOM
  • DOM -> Document Object Model
  • 对于根节点的操作会影响到子节点;
  • 最常用的父节点 中的
    • Axis可封装成一个group
    • Legend(图例)可封装成一个group

image.png

https://en.wikipedia.org/wiki/File:DOM-model.svg

JavaScript – D3中的常用接口

  • 模板字符串:
    • let a = 10;
    • let myString = abc-${a}; (myString最终为’abc-10’)
  • 数组 a = [1, 2, 3]
  • 对象 a = {name: ‘Shao-Kui’, age: 24.3, lab: ‘cscg’}
    • D3数据可视化中常见对象数组,如:
      • a = [{name: ‘Shao-Kui’, age: 25.3, dept: ‘cs’},
      • {name: ‘Wen-Yang’, age: 23, dept: ‘cs’},
      • {name: ‘Yuan’, age: 29, dept: ‘cs’}]
  • 数组的排序 a.sort()
    • 可加入回调函数来替代缺省的排序方案,如对日期排序
    • a.sort(function(a,b){ return new Date(b.date) - new Date(a.date); }
  • 数组的查询 a.find( d => d.name === ‘Wen-Yang’)
  • 把字符串转换成数值:+(‘3.14’)
  • D3.js经常读取CSV、JSON等文件,会涉及大量的数组、对象的操作!

D3语法基础概览

  • 使用D3获取、修改、增加与删除节点(图元)
  • 数据的读取 – CSV
  • D3.js的数值计算。
  • 比例尺:
    • 线性比例尺(Linear Scale)
    • “条带”比例尺(Band Scale)
  • 坐标轴的绘制:
    • Margin。
  • Data-Join基础
  • 基于D3的基础语法与Data-Join绘制柱状图

元素(标签)的标识

  • 当我们在一个同学群体中(比如微信群)对某些同学发出通知时
    • 学号为2020123456的同学在东主楼集合
    • 计算机系研一的同学在东主楼集合
  • 在一个群体中,索引个体:
    • 通过唯一的标识索引到唯一的个体
    • 通过共同点索引到一批个体

元素(标签)的标识

  • 操作元素首先需要知道元素的标识
    • 即要得到已有或已经创建的元素
  • 元素的ID
    • 可以唯一找到元素的标识符
  • 元素的Class
    • 人为赋予的“类别”可以标记元素的集合,其中的元素标签可以不相同
  • 元素的标签
    • HTML自带的标签名称,可以找到一批同类别的物体,如所有的“矩形”
    • 使用自带的标签往往难以直接索引到目标元素
    • , ,

image.png

使用D3查询SVG

  • d3.select(…)
    • d3.select(‘#rect1’)
    • 查询ID为’rect1’的元素
    • #表示后面的字符串是一个ID
    • 只找一个,若有重名也只返回第一个
  • d3.selectAll(…)
    • d3.selectAll(‘.class1’)
    • 查询所有class是’class1’的元素
    • d3.selectAll(‘rect’)
    • 查询所有标签是’rect’的元素(rect为SVG中的矩形标签)
    • 有多少返回多少
    • 可配合Data-Join选取‘不存在’的图元
  • ID前加‘#’,Class前加‘.’ ,标签名前不加符号。
  • 基于层级的查询:
    • d3.select(‘#maingroup rect’)
    • d3.selectAll('.tick text’)
    • d3.selectAll(‘#secondgroup rect’)
  • 如:’#secondgroup rect’
    • 首先会找到id为secondgroup的标签
    • 进一步找到secondgroup的子标签中是rect的
    • 仍然是对rect做查询,只是结果通过父标签做了筛选
  • d3.select(…)也可用于查询类别,如
    • d3.select(‘.class1’)
    • 但只会返回找到的第一个元素
  • 因此对于class、标签名称的查询建议使用d3.selectAll
  • 对于特定某一个元素的查询建议使用d3.select

使用D3设置SVG中的属性

  • 常见的属性
    • id, class(特殊的属性,可以使用.attr设置)
    • x, y, cx, cy
    • fill, stroke
    • height, width, r (圆的半径)
    • transform -> translate, rotate, scale
  • SVG的属性非常多,且属性的取值 **范围&类型 **各不同
    • tip1: 尽可能记住一些常见的属性,以提高编程速度
    • tip2: 遇到不认识or想要设置某个属性,一定要查阅

https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute

  • 屏幕空间的坐标系与常见坐标系不同
    • 左上方为原点
    • Y、X分别垂直向下、水平向右

image.png

element.attr(…)

  • 设置元素的属性: element.attr(‘attr_name’, ‘attr_value’)
    • 两个参数:属性名、设置的值
    • rect1.attr(‘y’, ‘100’)
    • d3.select(‘#rect1’).attr(‘y’, ‘100’)
  • 获取元素的属性: element.attr(‘attr_name’)
    • 一个参数:属性名
  • 链式调用
    • selection.attr(…).attr(…).attr(…)
    • .attr(…)返回的是选择的图元本身

修改整组属性

  • DOM
    • 父节点的属性会影响子节点
    • 子节点的属性会相对于父节点
  • 下方代码可以直接移动组内所有元素
    • d3.select('#maingroup’)
    • .attr(‘transform’, ‘translate(200, 100)’)

image.png

image.png


使用D3 添加&**删除 **SVG元素

  • element.append(…)
    • const myRect = svg.append(‘rect’);
    • const myRect = d3.select(‘#mainsvg’).append(‘rect’)
    • const myRect = d3.select(‘#mainsvg’).append(‘rect’).attr(‘x’, ‘100’)
  • D3的链式添加(调用)
    • const myRect = d3.select(‘#mainsvg’).append(‘g’).attr(‘id’, ‘maingroup’)
    • .append(‘rect’).attr(‘fill’, ‘yellow’)
  • element.remove()
    • 会移除整个标签
  • Tip:在debug的过程中可以考虑使用’opacity’属性hack出移除的效果
    • element.attr(‘opacity’, ‘0’)

操控SVG

image.png

数据的读取 – CSV数据

  • 第一行为属性列表,后续每行对应一‘条’数据。
  • CSV本质上是纯文本,区别于EXCEL的格式。

image.png

image.png

  • d3.csv(…):

    • 读取目标路径下的某一个CSV文件。
    • 例:d3.csv(‘static/data/hello.csv’);
  • d3.csv是一个JavaScript异步函数:

    • 不可以直接获得它的返回值,如:
    • let myData = d3.csv(‘static/data/hello.csv’); ❌
  • d3.csv(‘path/to/data.csv’).then( data => { // ‘数据读取后的代码逻辑’ } )

    • 要通过.then( **data **=> {…} )的方式来获得读取后的数据。
    • then(…)中的 ‘data => {…}’ 是一个函数
    • 函数接受的输入(参数),即data,为读取后的数据。
  • JavaScript异步机制

    • d3.csv作为异步函数,即便没有读取好数据,后面的代码也会继续执行
    • d3.csv被调用后,其返回值是一个JavaScript的‘Promise’对象(object)
    • Promise‘询问’:数据读取好了之后要做什么?‘做什么’即对应.then()中函数的内容。
  • 代码调用示例:

image.png

  • 读取后的数据格式(接口)与原本的CSV结构不同。

image.png

D3.js的数值计算

  • 数据可视化常涉及对数据的处理与计算:
    • 下述三个接口分别用于计算数组的最大值、最小值、[最小值,最大值]。
  • d3.max(array)
    • 返回数组中的最大值。
    • d3.max([5,4,6,1,8,16,9]) // 16
  • d3.min(array)
    • 返回数组中的最小值。
    • d3.min([5,4,6,1,8,16,9]) // 1
  • d3.extent(array)
    • 同时返回最小值与最大值,以数组的形式,即[最小值,最大值]。
    • d3.extent([5,4,6,1,8,16,9]) // [1, 16]
  • 数组中的内容可以是任意对象:
    • 每个对象可能包含多个属性。
    • 具体取哪个属性的最大值通过回调函数来提示d3.max、d3.min与d3.extent。
  • 例:
    • let a = [ {name: ‘Shao-Kui’, age:25, height: 176}, {name:‘Wen-Yang’, age:24, height: 180}, {name:‘Liang Yuan’, age: 29, height: 172}, {name:‘Wei-Yu’, age:23, height: 173}]
    • d3.max(a, d => d.age) // 29
    • d3.max(a, d => d.height) // 180
    • d3.extent(a, d => d.height) // [172, 180]
    • d3.min(a, d => d.age) // 23

比例尺

  • 比例尺用于把实际数据空间映射到屏幕(画布)空间,即两个空间的转化。
  • 常用于映射数据and创建坐标轴。
  • 区别主要在于数据的尺度不同

image.png
image.png

Scale - Linear

  • d3.scaleLinear():
    • 定义一个线性比例尺,返回的是一个函数
    • let scale = d3.scaleLinear(); // scale为函数
  • scale.domain([min_d, max_d]).range([min, max]):
    • 设置比例尺的定义域值域
    • 线性比例尺的定义域和值域都是连续的(Continuous),需分别给出最大值与最小值。
    • const scale = d3.scaleLinear().domain([20, 80]).range([0, 120]);
  • 比例尺本质上是一个函数
    • scale(20) // 0
    • scale(50) // 60
  • 常结合读取的数据与d3.max等接口连用:
    • const xScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.value)]).range([0, innerWidth]);

image.png

image.png

Scale - Band

  • d3.scaleBand():
    • 定义一个‘条带’比例尺,返回的是一个函数
    • let scale = d3.scaleBand();
  • scale.domain(array).range([min, max]):
    • 设置比例尺的定义域与值域
    • Band比例尺的定义域是离散的(Discrete),值域是连续的。
    • const scale = d3.scaleBand().domain([‘a’, ‘b’, ‘c’]).range([0, 120]);
  • 比例尺本质上是一个函数
    • scale(‘b’) // 40
    • scale(‘c’) // 80

image.png

  • 常结合JavaScript的array.map接口一起使用:
    • let a = [{name: ‘Shao-Kui’, value:6}, {name:‘Wen-Yang’, value:6}, {name:‘Yuan Liang’, value:16}]
    • a.map(d => d.name) // [‘Shao-Kui’, ‘Wen-Yang’, ‘Yuan Liang’]
    • const yScale = d3.scaleBand().domain(data.map(d => d.name)).range([0, innerHeight])
    • scale.padding(0.1):
      • 设置条带的间距占各自区域的比重。
    • scale.bandwidth():
      • 返回条带的长度。

image.png

引入坐标轴

  • 一个坐标轴为一个group( ),通常需要两个坐标轴。
  • 坐标轴中包含:
    • 一个 用于横跨坐标轴的覆盖范围
    • 若干个刻度(.tick)
      • 每个刻度也是一个group
    • 每个刻度下属还会包含一个 和一个
      • 用于展示坐标轴的轴线,如左到右或上到下
      • 用于展示坐标轴的刻度值,如实数、姓名、日期
    • (可选)一个标签用以描述坐标轴
  • 坐标轴的定义通常需要比例尺。

image.png

  • 定义坐标轴(获得结果仍是函数):

    • const yAxis = d3.axisLeft(yScale);
    • const xAxis = d3.axisBottom(xScale);
    • axisLeft:左侧坐标轴。
    • axisBottom:底侧坐标轴。
    • 坐标轴的刻度对应比例尺的定义域。
    • 坐标轴在画布的绘制对应比例尺的值域。
    • 仅是对坐标轴的定义,还未绘制。
  • 绘制坐标轴:

    • const yAxisGroup = g.append(‘g’).call(yAxis);
    • const xAxisGroup = g.append(‘g’).call(xAxis);
    • 实际配置后会发现 中增添了与坐标轴相关的元素
  • 任何坐标轴在初始化之后会默认放置在坐标原点,需要进一步的平移。

  • 关于 selection.call(…)

  • 函数的输入为另一个函数

  • 另一个函数以selection本身(即图元)作为输入

  • 另一个函数中会根据函数体的内容修改selection对应的图元。

  • 定义一个空白的 ,D3会帮助我们定义好 另一个函数,我们通过.call(…)让 得以在 另一个函数中修改。

    • const yAxis = d3.axisLeft(yScale);
    • const yAxisGroup = g.append(‘g’).call(yAxis);

配置坐标轴

  • 可以对坐标轴的风格进行修改:
    • 坐标轴本质上是图元的集合。
    • d3.selectAll(‘.tick text’).attr(‘font-size’, ‘2em’);
    • .tick是D3对于坐标轴定义的统一class
  • 坐标轴的标签加入不在D3-Axis接口的负责范围内:
    • 通过对坐标轴的 标签 .append(‘text’)来实现
    • (左)纵轴坐标需要 .attr(‘transform’, ‘rotate(-90)’) 来旋转
    • 纵轴坐标旋转后,x / y 会颠倒甚至取值范围相反
    • 回忆DOM:父节点的属性会影响子节点,而坐标轴默认的’fill’属性是 ‘none’,因此请一定手动设置文字颜色 .attr(‘fill’, ‘black’)

引入坐标轴 - Margin

  • SVG对于D3.js是一个“画布”。
  • SVG范围外的任何内容属于画布之外,浏览器将不予显示。
    • 然而坐标轴通常初始化在所在父节点的左上角。
  • 定义Margin:
    • const margin = {top: 60, right: 30, bottom: 60, left: 200}
  • 计算实际操作的 inner 长/宽
    • const innerWidth = width - margin.left - margin.right;
    • const innerHeight = height - margin.top - margin.bottom;
  • 在SVG下额外定义一个组作为新的根节点
    • const g = svg.append(‘g’).attr(‘id’, ‘maingroup’).attr(‘transform’, translate(${margin.left}, ${margin.top}));
  • Tip: HTML确实在样式表中提供margin属性,然而设置其他图元的位置,仍需要计算innerWidth(Height)。

引入坐标轴

  • 调用示例:
    • 比例尺可通过坐标轴可视化。

image.png

Data-Join

  • 本质上是将数据与图元进行绑定:

    • 每个国家的人数绑定到矩形的长度;
    • 疫情感染的人数比例绑定到圆的半径;
    • 产品的销量绑定到矩形的长度;
    • 各类别商品的销售占比绑定到扇形的弧度。
  • Why?

    • 以数据为中心(Data-Driven)的可视化操作:
      • 根据数据自动调整图元的属性。
      • .attr(…)接口可基于图元自己绑定的数据自动调整属性值
    • 数据发生变化时可以自动对图元增删改查:
      • 不再需要手动添加、‘修改’、删除图元。
      • 根据数据的增加or删除or更新,自动补充or移除or更新图元。
  • Data-Join并不是必要的操作,不使用Data-Join同样可以画出所有可视化作品。

  • Data-Join只是让D3.js编程变得更高效且语法更简洁。

  • d3.selectAll(‘.class’)**.data( dataArray ) **

  • dataArray在保证是一个数组的前提下可以是任何形式:

    • 例: [0, 2, 32, 18];
    • 例:[{name: ‘Sebastian’, value:384}, {name:’ Ciel’, value:32}, {name:‘Wen-Yang’, value:16}, {name:‘Shao-Kui’, value:19}];
  • .data(…)只考虑数据和图元数目相同的情况:

    • dataArray是一个数组,其中的每‘条’数据会与一个图元绑定。
  • 默认的绑定按照双方的索引顺序:

    • (Data的Key:后续D3中会讨论。)
  • 不调用.data(…),则图元不会与任何数据绑定

  • 数据的更新只需要重新绑定另一个 dataArray 即可。

image.png

  • 调用形式:
    • **d3.selectAll(‘.class’).data(myData).join(‘图元’).attr(d => …).attr((d, i) => …) **
    • .join(…)会根据数据的条目补全or删除图元。
  • 若有新增的数据,则会自动增加对应图元。
  • 若有修改的数据,则会自动更新对应图元。
  • 若有删除的数据,则会自动移除对应图元。

image.png

Data-Join – 用函数设置图元属性

  • selection.attr(‘attrbuteName’, ‘value’)
    • 通过值设置属性
  • selection.attr(‘attrbuteName’, (d, i) => {…})
    • 通过函数设置属性,函数的输入为绑定的数据,返回值为图元得到的属性值
    • d为Data-Join中,‘.data(array)’绑定给每个图元的数据。
    • i为Data-Join中,‘.data(array)’绑定图元的顺序,即图元对应原本数组的第几个
    • 例:d3.selectAll(‘rect’).attr(‘width’, (d, i) => 1000 * d.age )
    • 例:d3.selectAll(‘circle’).attr(‘cy’, (d, i) => 200 * i + 30);
    • 由于绑定数据的不同,故得到的结果也不同。
  • 设置图元属性的函数遵循如下规则(顺序性):
    • 函数可仅使用 d => {…},即只有一个参数,但此时函数体无法使用索引。
    • 即使未使用到绑定的数据,如需使用索引,仍需要完整的写出 (d, i) => {…}。

基于D3的基础语法与Data-Join绘制柱状图

  • 数据来源:
    • https://www.kaggle.com/gregorut/videogamesales

image.png

Tip:颜色 – ‘fill’属性

  • PlanA:人为定义一系列颜色组合
  • PlanB:使用D3提供的颜色组合(见下页)
  • PlanC:采样

image.png

image.png

image.png

Tip:D3提供的各种色盘

  • 定义一个离散数据到离散数据的映射
    • 如:每个水果对应到某个颜色

image.png

  • D3.js的内嵌(自带)配色方案?
    • https://github.com/d3/d3-scale-chromatic

image.png
image.png
image.png

网络数据的数据结构?

  • 网络数据包括节点的集合与边的集合:
    • 节点与边通常分布在不同的文件中,通过节点的ID索引
  • D3.js也没有统一的网络数据结构规范:
    • 只要能整理成D3.js对应接口接受的格式即可
  • 常见的数据形式:
    • 【节点列表】+【连接矩阵】
    • 【节点数、边数与基于ID的连接】
    • 【节点列表】+【边列表】

image.png【节点数、边数与基于ID的连接】
image.pngimage.png【节点列表】+【边列表】
image.pngimage.png【连接矩阵】

d3力模拟基础

  • d3的力模拟与“transition”是完全不同的两个体系
  • let nodes = [{}, {}, {}, {}, {}, {}];
  • let simulation = d3.forceSimulation(nodes) 定义后会发生…
    • 补全nodes中每个节点的数据结构:
      • 包括index, x, y, vx, vy,后两者为速度。
    • 开始模拟粒子运动:
      • 粒子质量为1。
      • 不断地通过内部timer触发’tick’事件。
    • 根据一系列的‘’来计算每个例子的加速度、速度、位置…
      • ‘力’都是哪来的呢?

image.png

不同力的作用

  • d3.forceManyBody().strength( value ):
    • 粒子之间两两的作用力,类似于‘万有引力’。
    • .strength(value)’用来设置力的大小,value为正互相吸引,为负则互相排斥。
  • d3.forceCenter(w, h).strength( value ):
    • 指向某一个中心的力,会尽可能让粒子向中心靠近。
    • .strength(…)的用法同上。
    • ‘d3.forceCenter(w, h)’中的‘w’与‘h’为中心的位置,通常为画布的中心。
  • d3.forceLink(links).strength(strength).distance(distance):
    • 部分粒子之间的两两作用力,不同于‘d3.forceManyBody’。
    • 'd3.forceLink’中,每个节点仅仅会与一部分节点有力的作用。
    • 有链接的节点间,受力的作用,保持在特定的距离即靠近互斥远离吸引
    • 是否有链接需要通过图的边集合给出。
    • .strength( vs )’ 与 ‘.distance( vd )’分别设置力的大小预期的距离
  • Link要通过一个数据格式给出,即link的source与target。
  • 格式非常类似于‘d3.hierarchy’给出的root.links()

image.png

编程实例:

image.png

image.png


‘Tic-Toc’

  • forceSimulation会通过每次‘tick’来更新当前节点的状态:
    • 状态包括位置、速度、加速度等。
  • 更新后的状态仅仅为‘状态’:
    • 不会反映到任何图元,仅修改数据。
    • 需要添加修改图元属性的回调函数
  • 人为设置每次tick要如何更新图元
    • simulation.on(‘tick’, ticked);
  • 在初始化每个图元后,只要为simulation配置了’tick’的回调,simulation会自动开始模拟。

image.png

基于‘d3-force’实现力导图

数据来源:http://networkrepository.com/socfb-Caltech36.php

编程实例:

image.png
image.png

Tip:带权重的图?

  • d3.forceLink(links).strength(…).distance(…):
    • 本质上根据link的权重设置forceLink的strength与distance。
    • 分别输入回调函数,基于每一个‘link’元素来设置各自的力与距离。
  • 编程实例:

image.png

相关文章:

d3.js

D3&#xff1a;Data-Driven Documents • 通过D3提供的接口来基于数据操控文档的各个图元。 标题对于D3(本讲解)最为重要的标签&#xff0c;主要操作的对象(画布) HTML - 导入D3.js D3.js作为JavaScript的外库&#xff0c;必须先将其导入&#xff0c;如&#xff1a; Python的…...

okhttp关于header修改

在项目开发中&#xff0c;需要和后台定义一些规则,比如一些请求头信息&#xff0c;Content-Type&#xff0c;User-Agent。不能使用默认的&#xff0c;那么就得我们自己配置全局的。 基于okhttp4.0以上版本修改步骤&#xff1a; 创建我们自己的MediaType, create已经被废弃 val…...

pytorch代码实现注意力机制之Flatten Attention

Flatten Attention 介绍&#xff1a;最新注意力Flatten Attention&#xff1a;聚焦的线性注意力机制构建视觉 Transformer 在将 Transformer 模型应用于视觉任务时&#xff0c;自注意力机制 (Self-Attention) 的计算复杂度随序列长度的大小呈二次方关系&#xff0c;给视觉任务…...

激光雷达和人工智能

几十年来&#xff0c;激光雷达一直是许多行业中非常有用的工具&#xff0c;但直到最近&#xff0c;随着人工智能&#xff08;AI&#xff09;解决方案的引入&#xff0c;我们才开始认识到它的真正潜力。激光雷达&#xff0c;又称光探测和测距&#xff0c;是一种遥感技术。它利用…...

【算法练习Day44】最长递增子序列最长连续递增序列最长重复子数组

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 最长递增子序列最长连续递增…...

STM32H743XX/STM32H563XX芯片烧录一次后,再次上电无法烧录

近期在使用STM32H563ZIT6这款芯片在开发板上使用正常&#xff0c;烧录到自己打的板子就遇到了芯片烧录一次后&#xff0c;再次上电无法烧录的问题。 遇到问题需要从以下5点进行分析。 首先看下开发板的原理图 1.BOOT0需要拉高。 2.NRST脚在开发板上是悬空的。这里我建议大家…...

21. 合并两个有序链表 --力扣 --JAVA

题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 解题思路 判断特殊情况&#xff0c;如&#xff1a;两个列表中其中一个为空&#xff1b;创建一个初始节点用于返回&#xff1b;通过while循环来逐个遍历链表&#xff0…...

Linux 基本语句_10_进程

进程和程序的区别&#xff1a; 程序是一段静态的代码&#xff0c;是保存在非易失储存器上的制令和数据的有序集合&#xff0c;没有任何执行的概念&#xff1b;而进程是一个动态的概念&#xff0c;它是程序的一次执行过程&#xff0c;包括了动态创建、调度、执行和消亡的整个过程…...

矩阵起源加入 OpenCloudOS 操作系统开源社区,完成技术兼容互认证

近日&#xff0c;超融合异构云原生数据库 MatrixOne企业版软件 V1.0 完成了与 OpenCloudOS 的相互兼容认证&#xff0c;测试期间&#xff0c;整体运行稳定&#xff0c;在功能、性能及兼容性方面表现良好。 一、产品简介 矩阵起源 MatrixOrigin 致力于建设开放的技术开源社区和…...

3D物理模拟和视觉特效软件SideFX Houdini mac中文介绍

SideFX Houdini for mac是一款3D物理模拟和视觉特效软件&#xff0c;几乎所有好莱坞特效电影里的物理模拟&#xff0c;包括碎裂&#xff0c;烟尘&#xff0c;碰撞&#xff0c;火焰&#xff0c;流体等模拟&#xff0c;都看得到它的身影。其独特的节点式操作方式&#xff0c;尤其…...

GPT-4.0网页平台-ChatYY

ChatYY的优势&#xff1a; 1. 支持大部分AI模型&#xff0c;且支持AI绘画&#xff1a; 2. 问答响应速度极快&#xff1a; 3. 代码解析&#xff1a; 4. 支持文档解读&#xff1a; 5. PC、移动端均支持&#xff1a; 访问直达&#xff1a;ChatYY.com...

mysql,redis导入导出数据库数据

mysql 导出数据 导出整个数据库&#xff1a; mysqldump -u 用户名 -p 数据库名 > 导出文件.sql 例如&#xff0c;如果你的用户名是 root&#xff0c;数据库名是 mydatabase&#xff0c;你可以运行以下命令&#xff1a; mysqldump -u root -p mydatabase > 导出文件.sql…...

conda修改虚拟环境名称

conda 修改虚拟环境名称 conda 不能直接更改名称&#xff0c;但是可以通过克隆环境解决 新建环境&#xff08;克隆旧环境&#xff09; conda create --name 新环境名 --clone 旧环境名 删除原环境 conda remove --name 旧环境名 --all 查看现有环境 conda env list conda i…...

c语言,将奇数和偶数分类

题目&#xff1a;输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分。 思路&#xff1a;像冒泡排序那样&#xff0c;相邻两个数比较&#xff0c;两个都是偶数则不…...

前端设计模式之【观察者模式】

文章目录 前言介绍实现优缺点应用场景后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端设计模式 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&#…...

HTTPS安全相关-通信安全的四个特性-ssl/tls

230-TLS是什么 1.http不安全 由于 HTTP 天生“明文”的特点&#xff0c;整个传输过程完全透明&#xff0c;任何人都能够在链路中截获、修改或者伪造请求 / 响应报文&#xff0c;数据不具有可信性 &#xff1b; “代理服务”。它作为 HTTP 通信的中间人&#xff0c;在数据上下…...

并查集:Leetcode765 情侣牵手

n 对情侣坐在连续排列的 2n 个座位上&#xff0c;想要牵到对方的手。 人和座位由一个整数数组 row 表示&#xff0c;其中 row[i] 是坐在第 i 个座位上的人的 ID。情侣们按顺序编号&#xff0c;第一对是 (0, 1)&#xff0c;第二对是 (2, 3)&#xff0c;以此类推&#xff0c;最后…...

如何设计一个网盘系统的架构

1. 概述 现代生活中已经离不开网盘&#xff0c;比如百度网盘。在使用网盘的过程中&#xff0c;有没有想过它是如何工作的&#xff1f;在本文中&#xff0c;我们将讨论如何设计像百度网盘这样的系统的基础架构。 2. 系统需求 2.1. 功能性需求 用户能够上传照片/文件。用户能…...

【代码随想录】算法训练计划17

1、 110.平衡二叉树 题目&#xff1a; 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 思路&#xff1a; 经典后序遍历&#xff0c;感…...

“护肤品销售策略:从“免费拼团”到“3人回本大放送”“

有一个销售护肤品的团队&#xff0c;他们家399块钱一套的护肤品&#xff0c;他们在小程序这一个渠道&#xff0c;只用了23天的时间&#xff0c;就卖出去了2000多万的营业额&#xff0c;你敢信吗&#xff1f; 那么23天的时间&#xff0c;他们是怎么卖出去2000多万的呢&#xff1…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...