anichart.js 是一款将数据转化为动态柱状图/线性图的 js/ts 工具,可导出视频。
github: https://github.com/Jannchie/anichart.js
中文使用指南:https://github.com/Jannchie/anichart.js/blob/main/README-CN.md
docs 目录中有更详细的使用方法(英文)。
在线演示:https://xoyozo.net/Demo/BarGraph
目前 release 版本 3.0.0。
这里有一点常用设置示例:https://codesandbox.io/s/anichart-2x-m3xbz?file=/main.js
设置画布尺寸
stage.canvas.width = 1000;
stage.canvas.height = 500;
重设尺寸不会重新计算内部元素的大小和位置,因此对响应式布局不太友好。
配置柱状图
示例:
const barChart = new ani.BarChart({
dy: 2, // 文字下沉
imageField: 'logo', // 图标字段名
itemCount: 16, // 最多显示条数
dateFormat: '%Y年%-m月', // 日期格式
barGap: 10, // 柱条间距
barInfoFormat: () => '', // 隐藏柱条上的文字
});
stage.addChild(barChart);
循环播放
setInterval(function () {
if (!stage.playing) {
stage.sec = 0;
stage.play();
}
}, 1000);
众所周知,VMware Workstation 中分配的硬盘大小与实际的 .vmdk 文件尺寸是不一致的。
譬如为虚拟机创建了一块 60GB 的硬盘,安装完系统后使用了 20GB 的空间,此时在宿主机上查看到的 .vmdk 的大小是 20GB。
当虚拟机的磁盘空间不足时,可以在 VMware 中扩展容量或添加硬盘。
扩展容量:虚拟机 - 设置 - 硬件 - 硬盘 - 扩展 - 设置最大磁盘大小。譬如设置为 160GB,那么虚拟机的磁盘 0 的大小会变成 160GB,C 盘 60GB 不变,在磁盘管理中可以将未分配的 100GB 创建为 D 盘。
添加硬盘:虚拟机 - 设置 - 硬件 - 添加 - 硬盘 - 设置最大磁盘大小。譬如设置为 100GB,那么虚拟机会增加一块大小为 100GB 的磁盘 1,在磁盘管理中可以将它创建为 100GB 的 D 盘。
当虚拟机内删除文件后,观察到 .vmdk 文件的大小并没有相应地减小,网上搜索后找到很多办法,但未测试成功。索性删除并重装系统比较方便,如果虚拟机里安装了许多软件不方便重装的朋友继续研究。
不要使用 CSS 方式设置 canvas 的宽高,应使用属性来设置其尺寸。
直接设置属性:
<canvas id="canvas" width="400" height="300"></canvas>
因属性值是以 px 为单位的,如果项目全程使用 rem 等其它尺寸单位,可通过 JS 来设置
var canvas = document.getElementById('canvas');
coatingW = $('#coating_frame').width();
coatingH = $('#coating_frame').height();
canvas.width = coatingW;
canvas.height = coatingH;
按材料
铅酸电池 | 成本低、低温性好、性价比高;能量密度低、寿命短、体积大、安全性差。 |
镍氢电池 | 成本低、技术成熟、寿命长、耐用;能量密度低、体积大、电压低、有电池记忆效应。含有重金属,遗弃后对环境造成污染。 |
锰酸锂电池 | 成本低、安全性和低温性能好的正极材料,但是其材料本身并不太稳定,容易分解产生气体,因此多用于和其它材料混合使用,以降低电芯成本,但其循环寿命衰减较快,容易发生鼓胀,高温性能较差、寿命相对短。 |
磷酸铁锂电池 | 是一种使用磷酸铁锂(LiFePO4)作为正极材料,碳作为负极材料的锂离子电池。具有工作电压高、能量密度大、循环寿命长、安全性能好、自放电率小、无记忆效应的优点。电池温度处于500-600℃时,其内部化学成分才开始分解,并且穿刺、短路、高温都不会燃烧或者爆炸,使用寿命也较长。但车辆续航里程一般,当温度低于-5℃时,充电效率低,不适合北方在冬天充电的需求。 |
三元锂电池 | 是指正极材料使用镍钴锰酸锂(Li(NiCoMn)O2)或者镍钴铝酸锂的三元正极材料的锂电池。能量密度高、循环寿命长、不惧低温;高温下稳定不足。能量密度可达最高,但高温性相对较差,关于续航里程有要求的纯电动汽车,其是主流方向,且适合北方天气,低温时电池更加稳定。 |
按制造和封装形式
1865电池 | 18650是锂离子电池的鼻祖。日本SONY公司当年为了节省成本而定下的一种标准性的锂离子电池型号,其中18表示直径为18mm,65表示长度为65mm,0表示为圆柱形电池。优点:容量大、寿命长、安全性能高、电压高、没有记忆效应、内阻小、可串联或并联组合成18650锂电池组、使用范围广。 |
2170电池 | 2017年1月4日,特斯拉官方宣布新一代锂电池“2170”开始量产。直径为21mm、高度70mm。 |
4680电池 | 2020年9月特斯拉发布了的新型电池类型,据介绍,相较2170电池,该电池能量方面提高5倍,续航里程提高16%,动力方面提高6倍。2022年初开始量产。 |
刀片电池 | 是比亚迪于2020年3月29日发布的电池产品。该电池采用磷酸铁锂技术。“刀片电池”通过结构创新,在成组时可以跳过“模组”,大幅提高了体积利用率,最终达成在同样的空间内装入更多电芯的设计目标。相较传统电池包,“刀片电池”的体积利用率提升了50%以上,也就是说续航里程可提升50%以上,达到了高能量密度三元锂电池的同等水平。 |
麒麟电池 | 2022年3月26日,宁德时代首席科学家吴凯在2022年电动汽车百人会论坛上表示:宁德时代通过不断技术迭代,推出了第三代CTP技术,其系统重量、能量密度及体积能量密度继续引领行业最高水平。在相同的化学体系、同等电池包尺寸下,麒麟电池包的电量,相比4680系统可以提升13%。第三代CTP技术,兼顾极速、无损、安全、高效等优势,适用磷酸铁锂、三元电池,涵盖乘用车、商用车领域。 |
如果您想在 MySQL 数据库的所有表的所有字段中搜索文本字符串,您可以使用 phpMyAdmin 非常轻松地完成此操作。以下是搜索每个 MySQL / MariaDB 数据库表的步骤。
1) 选择所需的数据库
第一步是选择要搜索的数据库。不要选择表格,只需选择要搜索的数据库。(如果您选择一个表格,您将在第 2 步中获得不同的搜索表单。)
在这张图片中,我展示了我想搜索一个名为 db_bbs2021 的数据库:
2) 转到搜索表单
如图所示,然后您要单击 phpMyAdmin“搜索”选项卡。当你这样做时,你会看到一个看起来像这样的表单:
现在您所要做的就是填写您的搜索条件。
3) 填写您的搜索条件
在我的例子中,我想搜索字符串“xoyozo”,我想查看每个 MySQL 数据库表,所以我将该字符串放在“要搜索的内容”字段中,然后选择每个数据库表:
4) 按“执行”并浏览结果
完成这些操作后,只需按“执行”按钮,稍等片刻,然后浏览结果即可。此图显示了结果的样子:
结果中显示“浏览”和“删除”链接的任何行都表示在该数据库表中找到了搜索字符串。当您单击浏览时,phpMyAdmin 将向您显示相关结果。
概括
总而言之,如果您需要在整个 MySQL 数据库及其所有表中搜索字符串,这种方法对我来说效果很好。
缺点
若数据库尺寸过大或服务器配置较低,在执行过程中可能会出现
m① R②
x① R②
① 表示屏幕尺寸,一般有 15、17 等
② 表示第几代,对应 CPU 和显卡的不同,数字越大越新
相同 ① 与 ② 的情况下仍有细分款式,对应内存、硬盘、屏幕分辨率刷新率等不同
x 系列是全新的系列,是 m 系列的更新款(m 系列不再更新),相比 m 系列提升了散热性能
屏幕尺寸 | 型号 | 处理器 | 显卡 | 发布时间 |
14.0 英寸 | x14 R1 | 12 代 i7 | 30 系 | 2022年1月 |
15.6 英寸 | m15 R4 | 10 代 i7/i9 | 30 系 | |
m15 R5 | 锐龙 R7-5800H | 30 系 | ||
m15 R6 | 11 代 i7 | 30 系 | ||
m15 R7 | 12 代 i7 | 30 系 | 2022年2月 | |
x15 R1 | 11 代 i7/i9 | 30 系 | ||
x15 R2 | 12 代 i9 | 30 系 | 2022年2月 | |
16.0 英寸 | m16 | 13 代 i7/i9 | 40 系 | 2023年2月 |
x16 | 13 代 HK | 40 系 | 2023年2月 | |
17.3 英寸 | m17 R3 | 10 代 i7 | 20 系 | |
m17 R4 | 10 代 i7 | 30 系 | ||
m17 R5 | 锐龙 R7/R9 | 30 系 | 2022年3月 | |
x17 R1 | 11 代 i7/i9 | 30 系 | ||
x17 R2 | 12 代 i9K | 30 系 | 2022年2月 | |
18英寸 | m18 | 13 代 i9 | 40 系 | 2023年2月 |
x15 是板载内存,x17 是卡槽内存
x 系列屏幕有 1K165Hz / 1K360Hz / 2K240Hz(15寸独有)/ 4K120Hz(17寸独有)
x 系列有 2 个 M.2 硬盘位,没有 2.5 寸硬盘位
Area-51m R(数字):可拆 CPU
Area-51m R2:10 代 i7,20 系显卡
以上规则整理于 2021 年 7 月,随着时间的推移,以上信息将逐渐失效。
“Web 部署”方式发布 ASP.NET Core 网站项目可解决发布到本地文件夹再通过 FTP 上传到 IIS 中会遇到的文件被锁定/占用的问题。相对于手动停止网站甚至结束进程来说,Web 部署更为方便。
服务器管理器 - 添加角色和功能 - 服务器角色 - Web 服务器(IIS) - 管理工具 - 管理服务
安装 Web Deploy
下载 Web 部署,安装时选择“完整”
在“服务”中设置“Web Management Service”和“Web 部署代理服务”自动启用。(若没有找到“Web 部署代理服务”,检查安装 Web Deploy 时是否勾选全部)
IIS 管理器 - 管理服务 - 启用远程连接
这里我们不使用 Windows 凭据(本地用户),而使用 IIS 管理器用户。
端口默认 8172,需要在防火墙中允许该端口。在阿里云 ECS 的安全组规则中添加该端口允许。
创建 IIS 管理器用户
打开后右侧添加用户,以“iisWebDeploy”为例
配置 IIS 管理器权限
选择单个网站
给整个网站目录添加 LOCAL SERVICE 的完全控制权限 2023年在 Windows Server 2022 上未设置 LOCAL SERVICE 的权限也能部署成功,所以忽略此步骤!2024年同样在 Windows Server 2022 上未设置 LOCAL SERVICE 部署失败,设置后部署成功。
发布
【建议】设置用户 WDeployAdmin 与 WDeployConfigWriter 的密码永不过期,否则会遇到:在远程计算机上处理请求时出错。
一些已知错误的解决办法:
若遇到已下载的 Microsoft SQL Server 2012 Transact-SQL ScriptDom 签名验证失败,手动下载安装即可:Microsoft SQL Server 2012 SP4 功能包,选择 SqlDom.msi(有两个同名文件,感觉上尺寸较大的应该是 x64,我没有具体对比,安装大的成功了)。
若遇到 SQL Server 2012 SP1 Shared Management Object (x86 / x64) 下载失败,同样点击上面的链接,选择 SharedManagementObjects.msi 下载安装。
Web Deploy 安装失败,如果 Web Deploy for Hosting Servers 下载失败,可以尝试安装 Web Deploy without bundled SQL support (last)。
如果是新项目,记得在 IIS 对应的网站中添加“IIS 管理器权限”中添加用户。
连接对话框中的“站点名称”或“网站名”必须与 IIS 中的网站名称一致。
还是无法连接?查看 IIS 管理服务中的 SSL 证书是否过期。
Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失败。检查输出窗口了解更多详细信息。尝试在“控制面板-卸载或更改程序”中修复 Microsoft Web Deploy 程序。
nuget 安装组件:MetadataExtractor
从文件流读取文件信息:
public IActionResult UploadFile([FromForm(Name = "[]")]IFormFile file)
{
var md = ImageMetadataReader.ReadMetadata(file.OpenReadStream());
var dic = new Dictionary<string, string>();
foreach (var m in md)
{
foreach (var t in m.Tags)
{
dic.Add(m.Name + " - " + t.Name, t.Description);
}
}
return Ok(dic);
}
结果演示:
从结果中可以看到计算的尺寸、拍摄设备、拍摄时间等信息。
MetadataExtractor 是一个简单而轻便的库,用于从图像和视频文件中读取元数据。
MetadataExtractor 从 JPEG、TIFF、WebP、PSD、PNG、BMP、GIF、ICO、PCX 和相机 RAW 文件读取 Exif、IPTC、XMP、ICC、Photoshop、WebP、PNG、BMP、GIF、ICO、PCX 元数据。
此外,还支持 MOV 和相关的 QuickTime 视频格式,例如 MP4、M4V、3G2、3GP。
相机制造商特定的支持包括爱克发,佳能,卡西欧,DJI,爱普生,富士胶片,柯达,京瓷,徕卡,美能达,尼康,奥林巴斯,松下,宾得,Recononyx,三洋,Sigma / Foveon 和索尼型号。
使用 JS 根据屏幕宽度来计算页面尺寸和字体大小并不是一个好办法。
rem 单位是跟随网页根元素的 font-size 改变而自动改变的,是一个相对的长度单位,非常适合在不同手机界面上自适应屏幕大小。
一般的手机浏览器的默认字体大小为 16px。即:
:root { font-size: 16px; } /* 在 HTML 网页中,:root 选择器相当于 html */
也就是说,如果我定义一个宽度为 1rem,那么它的实际宽度为 16px。反过来说,如果设计稿宽度为 1000px,那么相当于 1000÷16=62.5rem。因此,我们设置一个 62.5rem 的宽度,即可正常显示 1000px 的设计效果。
为了适应不同屏幕尺寸的手机,只需按比例换算更改 :root 的 font-size 即可。这个比例是由“窗口宽度 ÷ 设计稿宽度”得到的,姑且称它为“窗设比”。
以 iPhone X 逻辑宽度 375px 为例,设计稿宽度 1000px 时,窗设比为:0.375。:root 的 font-size 将会被重置为 16 * 0.375 = 6px。上面的 62.5rem 宽度将对应 iPhone X 宽度为 62.5 * 6 = 375px,正好是屏幕逻辑宽度。
根据这个思路,理论上,我们只需要使用 CSS 将 :root 的 font-size 设置为 1px,然后使用 JS 重置为与“窗设比”相乘的积(本例中将被重置为 0.375px)。这样,我们可以不通过换算,只需要更改单位,将设计稿中的 500px 直接写入到 CSS 为 500rem,即可实现在 iPhone X 上显示逻辑宽度为(500 * 0.375 =)187.5px,即设计稿中的 1/2 宽度对应到屏幕上 1/2 的宽度。
实际上,部分安卓手机(如华为某旗舰机)不支持 :root 的 font-size 小于 12px,其它一些浏览器也会出现小于 12px 的文字以 12px 显示。
为了避免在任何环节出现小于 12px 的 font-size 值,且不增加设计稿尺寸到 CSS 数值的换算难度,我们设计了以下思路:
约定“设样比(设计稿的 px 值与 CSS 的 rem 值的比)”为 100;
使用 JS 将 :root 的 font-size 重置为“设样比”与“窗设比(窗口宽度 ÷ 设计稿宽度)”的乘积;
计算 CSS 时的 rem 值只需从设计稿中获取 px 值再除以“设样比”100 即可。
这样做的另一个好处是,不用要求设计师必须按多少尺寸来设计,当然按主流尺寸来建议是可行的。
完整代码(jQuery 版):
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>Index</title>
<style>
body { margin: 0; text-align: center; }
#app { margin: 0 auto; background-color: #EEE; display: none; }
/* 长度计算方法:从设计稿获得长度(例如 160px),除以 px2rem 值(本例为 100),得到 1.6rem */
.whole { background-color: #D84C40; width: 10rem; }
.half { background-color: #3296FA; width: 5rem; }
.half2 { background-color: #3296FA; width: 5rem; margin-left: 5rem; }
</style>
</head>
<body>
<div id="app">
<div class="whole">100%</div>
<div class="half">50%</div>
<div class="half2">50%</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// [函数] 重置尺寸
function fn_resize() {
// 设计稿宽度(px)
var designsWidth = 1000;
// 约定的“设计稿 px 值与 CSS rem 值的比”,为方便计算,一般无需改动
var px2rem = 100;
// 限制 #app 的最大宽度为设计稿宽度
$('#app').css('max-width', designsWidth).css('min-height', $(window).height());
// 重置 :root 的 font-size
var appWidth = Math.min($(window).width(), designsWidth);
$(':root').css('font-size', px2rem * appWidth / designsWidth);
$('#app').show();
}
// 页面加载完成后重置尺寸
$(fn_resize);
// 改变窗口大小时重置尺寸
$(window).resize(fn_resize);
</script>
</body>
</html>
完整代码(Vue2 版):
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>Index</title>
<style>
body { margin: 0; text-align: center; }
#app { margin: 0 auto; background-color: #EEE; }
/* 长度计算方法:从设计稿获得长度(例如 160px),除以 px2rem 值(本例为 100),得到 1.6rem */
.whole { background-color: #D84C40; width: 10rem; }
.half { background-color: #3296FA; width: 5rem; }
.half2 { background-color: #3296FA; width: 5rem; margin-left: 5rem; }
</style>
</head>
<body>
<div id="app" v-bind:style="{ maxWidth: designsWidth + 'px', minHeight: appMinHeight + 'px' }" style="display: none;" v-show="appShow">
<div class="whole">100%</div>
<div class="half">50%</div>
<div class="half2">50%</div>
<div>appWidth: {{ appWidth }}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
var app = new Vue({
el: '#app',
data: {
// 设计稿宽度(px)
designsWidth: 1000,
// 约定的“设计稿 px 值与 CSS rem 值的比”,为方便计算,一般无需改动
px2rem: 100,
// #app 的 width
appWidth: 0, // 勿改
appMinHeight: 0, // 勿改
appShow: false, // 勿改
},
mounted: function () {
// 页面加载完成后重置尺寸
this.fn_resize();
const that = this;
// 改变窗口大小时重置尺寸
window.onresize = () => {
return (() => {
console.log('RUN window.onresize()');
that.fn_resize();
})();
};
},
watch: {
// 侦听 appWidth 更改 root 的 font-size
appWidth: function () {
console.log('RUN watch: appWidth');
var root = document.getElementsByTagName("html")[0];
root.style.fontSize = (this.px2rem * this.appWidth / this.designsWidth) + 'px';
this.appShow = true;
}
},
methods: {
fn_resize: function () {
console.log('RUN methods: fn_resize()');
this.appWidth = Math.min(document.body.clientWidth, this.designsWidth);
this.appMinHeight = document.documentElement.clientHeight;
}
}
});
</script>
</body>
</html>
完整代码(Vue3 版):
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
<title>Index</title>
<style>
body { margin: 0; text-align: center; }
#app > div { display: none; margin: 0 auto; background-color: #EEE; }
/* 长度计算方法:从设计稿获得长度(例如 160px),除以 px2rem 值(本例为 100),得到 1.6rem */
.whole { background-color: #D84C40; width: 10rem; }
.half { background-color: #3296FA; width: 5rem; }
.half2 { background-color: #3296FA; width: 5rem; margin-left: 5rem; }
</style>
</head>
<body>
<div id="app">
<div style="display: none;" v-bind:style="{ maxWidth: designsWidth + 'px', minHeight: appMinHeight + 'px', display: appShow ? 'block' : 'none' }">
<div class="whole">100%</div>
<div class="half">50%</div>
<div class="half2">50%</div>
<div>appWidth: {{ appWidth }}</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
<script>
const app = Vue.createApp({
data: function () {
return {
// 设计稿宽度(px)
designsWidth: 1000,
// 约定的“设计稿 px 值与 CSS rem 值的比”,为方便计算,一般无需改动
px2rem: 100,
// #app 的 width
appWidth: 0, // 勿改
appMinHeight: 0, // 勿改
appShow: false, // 勿改
}
},
mounted: function () {
// 页面加载完成后重置尺寸
this.fn_resize();
const that = this;
// 改变窗口大小时重置尺寸
window.onresize = () => {
return (() => {
console.log('RUN window.onresize()');
that.fn_resize();
})();
};
},
watch: {
// 侦听 appWidth 更改 root 的 font-size
appWidth: function () {
console.log('RUN watch: appWidth');
var root = document.getElementsByTagName("html")[0];
root.style.fontSize = (this.px2rem * this.appWidth / this.designsWidth) + 'px';
this.appShow = true;
}
},
methods: {
fn_resize: function () {
console.log('RUN methods: fn_resize()');
this.appWidth = Math.min(document.body.clientWidth, this.designsWidth);
this.appMinHeight = document.documentElement.clientHeight;
}
}
});
const vm = app.mount('#app');
</script>
</body>
</html>
示例中 CSS 初始 :root 的 font-size 为 16px(一个较小值,防止页面加载时瞬间出现大号文字影响用户体验),经过 fn_resize 后,:root 的 font-size 被设置为(100 * 375 / 1000 =)37.5px(iPhone X 中),那么宽度为 1000px 的设计稿中的 500px 换算到 CSS 中为 5rem,也即 37.5 * 5 = 187.5px,就是 iPhone X 的屏幕宽度的一半。
示例中 id 为 app 的 div 是用来在 PC 浏览器中限制页面内容最大宽度的(类似微信公众号发布的文章),如果网页不需要在 PC 端显示,jQuery 版代码中的 $('#app').width() 可以用 $(window).width() 来代替。
这个 div#app 一般设计有背景色,用于在宽度超过设计稿的设备上显示时区别于 body 的背景。但是当网页内容不超过一屏时,div#app 高度小于窗口,示例中与 appMinHeight 相关的代码就是为了解决这个问题。
示例中 div#app 隐藏/显示相关代码用于解决在页面加载初期由于 font-size 值变化引起的一闪而过的排版错乱。
最后补充一点,如果改变窗口大小时涉及执行耗时的操作,为避免页面卡顿,可以参考这篇文章添加函数防抖:https://xoyozo.net/Blog/Details/js-function-anti-shake
小米电视 5 | 小米电视 5 Pro | |
亮点 | 全面屏、超薄金属机身、小爱同学、远场语音、PatchWall、4K、四单元喇叭、3GB+32GB | 量子点、MEMC运动补偿、4K+HDR10+、全面屏、小爱同学、远场语音、PatchWall、4GB+64GB |
分辨率 | 3840x2160(4K) | |
背光 | 侧入式 | |
可视角度 | 178° | |
刷新率 | 60Hz | |
广色域 | NTSC 85% | NTSC 108% |
CPU | Cortex A55 | |
GPU | Mali-G31 MP2 | |
内存 | 3GB | 4GB |
闪存 | 32GB | 64GB |
解码能力 | 8K 视频解码 | |
无线 | 2.4GHz/5GHz、蓝牙、红外 | |
尺寸 | 55 英寸 长 1227mm 高 717.8mm 含脚架高 773.2mm 65 英寸 长 1445.9mm 高 831.4mm 含脚架高 898mm 75 英寸 长 1676.5mm 宽 973.3mm 含脚架高 1037.7mm | |
首发价格 | 55" ¥2999 65" ¥3999 75" ¥7999 | 55" ¥3699 65" ¥4999 75" ¥9999 |
首发价格(舍入) | 55" ¥3000 65" ¥4000 75" ¥8000 | 55" ¥3700 65" ¥5000 75" ¥10000 |