目 录
- 前言
-
- DeepSeek-V3.1-Terminus
- CherryStudio
- [AI Ping](#AI Ping)
- 蓝耘智算
- 配置方法
- 模型评测
- 总结
前言
当全球目光聚焦于少数几个闭源大模型时,一场由开源力量主导的静默革命正在发生。2025年9月,DeepSeek正式发布V3.1-Terminus版本,不仅在多项基准测试中刷新纪录,更在语言一致性、Agent能力等实际应用层面取得了突破性进展。
但问题是,对于大多数开发者、学生和AI爱好者而言,如何零门槛、低成本地体验到这款"明星模型"的强大能力?高昂的API费用和复杂的本地部署,曾让许多人对顶尖AI技术望而却步。
接下来本文将为您揭开一个"宝藏级"解决方案:通过国内蓝耘元生代MaaS平台,我们竟然可以免费调用DeepSeek-V3.1-Terminus。我将带领您从零开始,一步步通过CherryStudio配置环境,并透过多个生动有趣的实测案例------从烧脑的"谁养鱼"逻辑谜题到高考作文创作,再到严谨的物理解题------全方位验证这款最强开源模型的真实水准。
这不仅仅是一篇技术评测,更是一张通往AI前沿领域的实用地图。无论您是寻求高效开发工具的工程师,还是对AI充满好奇的学习者,相信本文都能为您打开一扇新的大门。现在,就让我们一起开始这段探索之旅。
DeepSeek-V3.1-Terminus
DeepSeek-V3.1-Terminus 是 DeepSeek 于 2025 年 9 月 22 日发布的开源大语言模型更新版,基于用户反馈优化了前代 V3.1。该版本提供思考模型与非思考模型两种模式,上下文窗口均为 128k,支持在线体验。主要改进包括提升语言一致性(减少中英文混杂和异常字符),增强 Code Agent 和 Search Agent 能力,提供更稳定的输出。性能在多领域评估中表现出色,保持 SOTA 水平。访问方式包括官方 App、网页版、小程序、DeepSeek API,以及 Hugging Face 和 ModelScope 开源下载。
DeepSeek-V3.1-Terminus 的主要改进:
- 语言一致性:显著缓解中英文混杂、偶发异常字符等问题,提升输出流畅度和可靠性。 Agent 能力:优化 Code Agent 和
- Search Agent 性能,Search Agent 配备全新工具集,支持更高效的代理式任务。
- 输出更稳定:在不同场景下生成结果更可靠。
DeepSeek-V3.1-Terminus 的输出效果相比前一版本更加稳定,新模型各领域测评结果如下:

CherryStudio
CherryStudio 是一款功能全面的 AI 助手平台,集成了多模型对话、知识库管理、AI 绘画、实时翻译等多种功能。其高度可定制化的设计、强大的扩展能力以及直观友好的用户界面,使其成为专业用户、开发者以及 AI 爱好者的首选工具。无论是零基础用户还是技术专家,都能通过 CherryStudio 轻松调用多样化的 AI 功能,从而提升工作效率与创造力。CherryStudio 支持通过可视化界面或远程 API 接口灵活调用各类模型,大幅降低了本地硬件配置的要求,为个人用户和企业团队提供了一个高效、便捷的 AI 解决方案。
详细配置过程请参考以下这两篇文章:
https://lethehong.blog.csdn.net/article/details/148513147
https://lethehong.blog.csdn.net/article/details/149664410
AI Ping
大型语言模型服务(Large Model as a Service, MaaS)正成为AI应用落地的关键模式。在2025年9月的 GOSIM2025 大会上,清华大学联合中国软件评测中心发布了权威的《2025大模型服务性能排行榜》,对国内20余家大模型服务平台在多项性能指标上进行了评测。据悉,本次评测的数据由清华系企业清程极智打造的 AI Ping 平台提供(官方网站aiping.cn),该平台通过长周期、高频率的测试,实时跟踪大模型服务的延迟、吞吐、可靠性三大核心指标并生成性能榜单。本文将根据这一排行榜的客观数据,对蓝耘元生代 MaaS 平台的大模型服务性能与其他平台进行对比分析,重点关注响应速度、推理吞吐量、稳定性(API 调用成功率)等指标。

蓝耘智算
蓝耘智算平台是一个提供高性能 AI 模型调用服务的国内领先平台,特别以免费支持 DeepSeek-R1 和 V3 等大语言模型而著称 。蓝耘 API 的优势在于稳定快速的网络连接、详尽的中文文档和本地化技术支持,极大降低了使用门槛,特别适合个人开发者、学生及预算有限的团队。无论是语义理解、文本生成还是智能问答,蓝耘 API 都能提供高效、精准的模型调用体验,是国内 AI 开发者的理想选择。
根据官方测试结果,与上一代相比新模型在多项基准测试中表现突出:
- Humanity's Last Exam得分从15.9跃升至21.7,提升幅度达36.5%
- BrowseComp网页理解任务评分提升至38.5
- SimpleQA问答准确率达到96.8%
这些提升使得新模型在复杂任务处理上更加可靠,尤其适合需要高精度输出的专业场景。

1️⃣ 语言一致性提升:中英文混杂与偶发异常字符情况得到缓解。新模型通过动态对齐训练技术,将中英文混杂率降低了68%,异常字符出现频率下降73%。
------在分析文学作品或进行跨语言翻译时,模型不再会出现突然切换语言的问题
2️⃣ Agent能力增强:Code Agent的代码生成准确率提升了12%,现在能够更好地理解复杂工程文件的模块化结构;Search Agent在多轮检索任务中的响应效率提高了40%,可以自动关联实时数据与历史知识库。
------这对于需要频繁进行信息检索的电商数据分析场景尤为实用

配置方法
安装CherryStudio
点击进入官网,根据自己的电脑系统下载安装包

双开打开下载,然后按照相关指引进行安装

获取API密钥
先说个好消息:蓝耘元生代上线 DeepSeek-V3.1-Terminus
限时领取100万tokens体验包
➡体验链接:maas.lanyun.net

验证通过后,直接进入控制台

粘贴蓝耘的API密钥,点击【检查】,提示"连接成功"即表示可以使用。

选择模型
回到主页后,点击顶部的模型进行选择DeepSeek-V3.1-Terminus即可

模型评测
画凹凸图
凹凸图(Bump Chart)作为一种展现排名变化的可视化形式,其核心价值在于通过纵轴表示排名位置、横轴表示时间维度,用连续曲线连接各时间点的排名变化轨迹。这种图表特别适用于电竞战队赛季排名追踪、商品销售波动分析、学术机构年度排名变化等场景。原始数据需包含时间序列、主体标识和排名数值三个核心维度,其中时间字段需统一格式(如YYYY-MM-DD或季度标识),主体标识需唯一且稳定(如球队名称或产品SKU),排名值则需严格为整数且无重复(若出现相同排名需处理为连续整数)。在视觉设计层面,凹凸图需采用高饱和度渐变色系,确保20个主体内可清晰区分;若主体超过20个,建议通过hover交互显示详细信息。辅助元素设计上需添加横向刻度线、排名数字标签及关键节点标记,动态效果则需实现曲线路径动画(持续800毫秒)和节点脉冲效果。通过ECharts的进阶配置,可为线条添加平滑过渡(smooth: 0.6)、调整符号尺寸(symbolSize: 12),并设置阴影效果增强立体感(shadowBlur: 8)。在商业分析场景中,某电商平台曾通过凹凸图发现季节性商品的规律波动(如空调类目在4月排名迅速攀升)、识别出3个月内从87位跃升至TOP10的黑马面膜品牌,并据此优化长尾商品的下架策略。
go
模拟凹凸图

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>开普勒行星轨道模拟</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
font-family: 'Arial', sans-serif;
color: white;
}
canvas {
display: block;
}
.controls {
position: absolute;
bottom: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 10px;
max-width: 250px;
}
.controls h3 {
margin-top: 0;
margin-bottom: 10px;
}
.control-group {
margin-bottom: 10px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="range"] {
width: 100%;
}
</style>
</head>
<body>
<canvas id="planetCanvas"></canvas>
<div class="controls">
<h3>星系控制面板</h3>
<div class="control-group">
<label for="speed">动画速度: <span id="speedValue">1.0</span></label>
<input type="range" id="speed" min="0.1" max="3" step="0.1" value="1">
</div>
<div class="control-group">
<label for="size">星体大小: <span id="sizeValue">1.0</span></label>
<input type="range" id="size" min="0.5" max="2" step="0.1" value="1">
</div>
<div class="control-group">
<label for="trails">轨迹显示: <span id="trailsValue">开启</span></label>
<input type="range" id="trails" min="0" max="1" step="1" value="1">
</div>
</div>
<script>
// 获取Canvas元素和上下文
const canvas = document.getElementById('planetCanvas');
const ctx = canvas.getContext('2d');
// 设置Canvas尺寸为窗口大小
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 设置中心点
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// 控制变量
let animationSpeed = 1.0;
let planetSize = 1.0;
let trailsEnabled = true;
// 更新控制显示
function updateControlsDisplay() {
document.getElementById('speedValue').textContent = animationSpeed.toFixed(1);
document.getElementById('sizeValue').textContent = planetSize.toFixed(1);
document.getElementById('trailsValue').textContent = trailsEnabled ? '开启' : '关闭';
}
// 事件监听
document.getElementById('speed').addEventListener('input', function() {
animationSpeed = parseFloat(this.value);
updateControlsDisplay();
});
document.getElementById('size').addEventListener('input', function() {
planetSize = parseFloat(this.value);
updateControlsDisplay();
});
document.getElementById('trails').addEventListener('input', function() {
trailsEnabled = parseInt(this.value) === 1;
updateControlsDisplay();
});
// 恒星类
class Star {
constructor(x, y, z, size, brightness) {
this.x = x;
this.y = y;
this.z = z;
this.size = size;
this.brightness = brightness;
}
update(speed) {
// 恒星位置相对固定,不需要更新
}
draw() {
ctx.save();
ctx.globalAlpha = this.brightness;
ctx.fillStyle = 'white';
// 计算位置偏移,实现视差效果
const parallaxX = centerX + (this.x - centerX) / this.z;
const parallaxY = centerY + (this.y - centerY) / this.z;
const size = this.size / this.z;
ctx.beginPath();
ctx.arc(parallaxX, parallaxY, size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
}
}
// 行星类
class Planet {
constructor(orbitRadius, orbitSpeed, orbitColor, planetColor, size, eccentricity = 0.2) {
this.orbitRadius = orbitRadius;
this.orbitSpeed = orbitSpeed;
this.orbitColor = orbitColor;
this.planetColor = planetColor;
this.size = size;
this.eccentricity = eccentricity; // 椭圆轨道的离心率
this.angle = Math.random() * Math.PI * 2; // 初始角度随机
this.trail = [];
this.maxTrailLength = 100;
// 计算轨道的长轴和短轴
this.semiMajorAxis = orbitRadius;
this.semiMinorAxis = orbitRadius * Math.sqrt(1 - eccentricity * eccentricity);
// 焦点偏移(太阳位于焦点)
this.focalDistance = Math.sqrt(this.semiMajorAxis * this.semiMajorAxis - this.semiMinorAxis * this.semiMinorAxis);
}
update(speed) {
// 使用开普勒第二定律调整速度(角速度随距离变化)
const distance = this.getCurrentDistance();
// 角速度与距离成反比
const angularSpeed = this.orbitSpeed * Math.sqrt(this.orbitRadius / distance) * speed;
this.angle += angularSpeed * 0.01;
// 记录轨迹点
if (this.trail.length > this.maxTrailLength) {
this.trail.shift();
}
this.trail.push({x: this.x, y: this.y});
}
getCurrentDistance() {
// 计算当前距离(使用极坐标到椭圆坐标转换)
const r = this.semiMajorAxis * (1 - this.eccentricity * this.eccentricity) /
(1 + this.eccentricity * Math.cos(this.angle));
return r;
}
get x() {
const r = this.getCurrentDistance();
return centerX + r * Math.cos(this.angle) - this.focalDistance;
}
get y() {
const r = this.getCurrentDistance();
return centerY + r * Math.sin(this.angle) * (this.semiMinorAxis / this.semiMajorAxis);
}
drawOrbit() {
ctx.save();
ctx.strokeStyle = this.orbitColor;
ctx.globalAlpha = 0.3;
ctx.lineWidth = 1;
ctx.beginPath();
// 绘制椭圆轨道
ctx.ellipse(
centerX - this.focalDistance,
centerY,
this.semiMajorAxis,
this.semiMinorAxis,
0, 0, Math.PI * 2
);
ctx.stroke();
ctx.restore();
}
draw() {
// 绘制轨道
this.drawOrbit();
// 绘制轨迹
if (trailsEnabled && this.trail.length > 1) {
ctx.save();
ctx.strokeStyle = this.planetColor;
ctx.globalAlpha = 0.5;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(this.trail[0].x, this.trail[0].y);
for (let i = 1; i < this.trail.length; i++) {
ctx.lineTo(this.trail[i].x, this.trail[i].y);
}
ctx.stroke();
ctx.restore();
}
// 绘制行星
ctx.save();
ctx.fillStyle = this.planetColor;
// 添加凹凸光照效果
const gradient = ctx.createRadialGradient(
this.x, this.y, 0,
this.x, this.y, this.size * planetSize * 1.2
);
if (this.planetColor === '#ff9900') {
// 太阳的特殊光照
gradient.addColorStop(0, '#fff9c4');
gradient.addColorStop(0.5, '#ffc107');
gradient.addColorStop(1, 'rgba(255, 153, 0, 0)');
} else {
// 行星的光照效果
gradient.addColorStop(0, '#ffffff');
gradient.addColorStop(0.3, this.planetColor);
gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
}
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size * planetSize * 1.2, 0, Math.PI * 2);
ctx.fill();
// 添加高光
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
ctx.beginPath();
ctx.arc(
this.x - this.size * planetSize * 0.3,
this.y - this.size * planetSize * 0.3,
this.size * planetSize * 0.3,
0, Math.PI * 2
);
ctx.fill();
ctx.restore();
}
}
// 创建天体
const stars = [];
for (let i = 0; i < 200; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
const z = Math.random() * 5 + 1; // z值决定视差效果
const size = Math.random() * 2 + 0.5;
const brightness = Math.random() * 0.8 + 0.2;
stars.push(new Star(x, y, z, size, brightness));
}
// 创建行星系统
const planets = [
new Planet(80, 0.8, 'rgba(100, 100, 100, 0.5)', '#ff9900', 25, 0.1), // 太阳
new Planet(150, 2, 'rgba(150, 150, 150, 0.5)', '#888888', 8, 0.2), // 水星
new Planet(220, 1.5, 'rgba(200, 180, 100, 0.5)', '#dd9955', 12, 0.15), // 金星
new Planet(300, 1, 'rgba(100, 150, 220, 0.5)', '#4488ff', 15, 0.1), // 地球
new Planet(380, 0.7, 'rgba(220, 100, 80, 0.5)', '#ff5555', 13, 0.05), // 火星
new Planet(500, 0.4, 'rgba(220, 200, 100, 0.5)', '#ddcc77', 20, 0.3), // 木星
new Planet(620, 0.3, 'rgba(200, 220, 150, 0.5)', '#aadd99', 18, 0.2), // 土星
new Planet(740, 0.2, 'rgba(150, 200, 220, 0.5)', '#77aadd', 16, 0.15), // 天王星
new Planet(850, 0.15, 'rgba(100, 150, 220, 0.5)', '#5577bb', 16, 0.1) // 海王星
];
// 动画循环
function animate() {
// 清除画布(使用半透明填充实现拖尾效果)
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制恒星
stars.forEach(star => star.draw());
// 更新并绘制行星
planets.forEach(planet => {
planet.update(animationSpeed);
planet.draw();
});
// 继续动画循环
requestAnimationFrame(animate);
}
// 开始动画
animate();
// 窗口大小调整
window.addEventListener('resize', function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
</script>
</body>
</html>

画未来一周气温变化
气温变化趋势图需整合多维数据,包括小时级温度采集、晴雨雪天气图标、风速风向矢量信息及空气质量指数(AQI)。视觉编码策略上,主趋势线采用平滑曲线(spline)连接日均温度,带状区域使用浅色渐变填充展示昼夜温差,极端天气事件则通过闪电图标加红色描边突出显示。交互设计需支持十字线数据实时显示(trigger: 'axis')、区域缩放(dataZoom: {type: 'inside'})以及多视图联动(点击温度图同步更新湿度趋势)。为提升性能,可采用数据分片加载技术(按周请求数据并滚动加载)、启用WebGL渲染处理万级数据点,并通过离屏Canvas预渲染静态元素以提高帧率。预警系统集成方面,通过visualMap组件设置分段颜色:35℃以上触发红色高温预警(#c23531),30-35℃为橙色预警(#fcb045),0℃以下启动低温预警(#2f4554)。某气象中心应用此方案后,实现城市热岛效应可视化分析,精准定位高温热点区域,为城市规划提供数据支持。
go
模拟未来一周气温变化

bash
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>未来一周气温变化模拟</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2980, #26d0ce);
color: white;
min-height: 100vh;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
max-width: 1000px;
width: 100%;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background: rgba(0, 0, 0, 0.2);
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.date-range {
font-size: 1.2rem;
opacity: 0.9;
}
.dashboard {
display: grid;
grid-template-columns: 1fr 300px;
gap: 20px;
margin-bottom: 30px;
}
.chart-container {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
height: 400px;
position: relative;
}
.info-panel {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
}
.info-panel h2 {
margin-bottom: 15px;
border-bottom: 2px solid rgba(255, 255, 255, 0.3);
padding-bottom: 10px;
}
.weather-cards {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 15px;
margin-top: 30px;
}
.weather-card {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 15px;
text-align: center;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease, background 0.3s ease;
cursor: pointer;
backdrop-filter: blur(10px);
}
.weather-card:hover {
transform: translateY(-5px);
background: rgba(255, 255, 255, 0.2);
}
.weather-card.active {
background: rgba(255, 255, 255, 0.25);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
}
.day {
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 10px;
}
.date {
font-size: 0.9rem;
opacity: 0.8;
margin-bottom: 15px;
}
.temp {
font-size: 2rem;
font-weight: bold;
margin: 10px 0;
}
.high-low {
display: flex;
justify-content: space-around;
margin-top: 10px;
}
.high, .low {
font-size: 0.9rem;
}
.high::before {
content: "↑";
margin-right: 5px;
}
.low::before {
content: "↓";
margin-right: 5px;
}
.weather-icon {
font-size: 2.5rem;
margin: 10px 0;
}
.temp-color-0 { color: #6bc5f8; } /* 寒冷 */
.temp-color-1 { color: #8de2c0; } /* 凉爽 */
.temp-color-2 { color: #b6e86f; } /* 舒适 */
.temp-color-3 { color: #f6d365; } /* 温暖 */
.temp-color-4 { color: #ff9966; } /* 炎热 */
.temp-bar {
height: 8px;
border-radius: 4px;
margin-top: 10px;
background: linear-gradient(to right, #6bc5f8, #8de2c0, #b6e86f, #f6d365, #ff9966);
position: relative;
}
.temp-marker {
width: 16px;
height: 16px;
border-radius: 50%;
background: white;
position: absolute;
top: -4px;
transform: translateX(-50%);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
transition: left 1s ease;
}
.legend {
display: flex;
justify-content: space-between;
margin-top: 5px;
font-size: 0.8rem;
opacity: 0.8;
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin: 20px 0;
}
button {
background: rgba(255, 255, 255, 0.2);
border: none;
border-radius: 30px;
color: white;
padding: 10px 20px;
cursor: pointer;
font-size: 1rem;
transition: background 0.3s ease;
}
button:hover {
background: rgba(255, 255, 255, 0.3);
}
.statistics {
display: flex;
justify-content: space-between;
margin-top: 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 15px;
}
.stat-item {
text-align: center;
flex: 1;
}
.stat-value {
font-size: 1.8rem;
font-weight: bold;
}
.stat-label {
font-size: 0.9rem;
opacity: 0.8;
}
canvas {
width: 100%;
height: 100%;
}
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
}
.weather-cards {
grid-template-columns: repeat(4, 1fr);
}
.weather-card:nth-child(n+5) {
grid-column: span 2;
}
h1 {
font-size: 2rem;
}
}
@media (max-width: 480px) {
.weather-cards {
grid-template-columns: 1fr;
}
.weather-card:nth-child(n+5) {
grid-column: 1;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>未来一周气温变化</h1>
<div class="date-range" id="dateRange">加载中...</div>
</header>
<div class="dashboard">
<div class="chart-container">
<canvas id="temperatureChart"></canvas>
</div>
<div class="info-panel">
<h2>今日详情</h2>
<div class="current-day" id="currentDay">-</div>
<div class="current-date" id="currentDate">-</div>
<div class="weather-icon" id="weatherIcon">☀️</div>
<div class="temp" id="currentTemp">-°C</div>
<div class="high-low">
<div class="high" id="currentHigh">最高: -°C</div>
<div class="low" id="currentLow">最低: -°C</div>
</div>
<div class="description" id="weatherDesc">-</div>
<div class="temp-bar">
<div class="temp-marker" id="tempMarker"></div>
</div>
<div class="legend">
<span>寒冷</span>
<span>凉爽</span>
<span>舒适</span>
<span>温暖</span>
<span>炎热</span>
</div>
</div>
</div>
<div class="controls">
<button id="btnWeek">本周趋势</button>
<button id="btnAvg">与平均温度对比</button>
<button id="btnDetail">详细数据</button>
</div>
<div class="weather-cards" id="weatherCards">
<!-- 天气卡片将通过JavaScript动态生成 -->
</div>
<div class="statistics">
<div class="stat-item">
<div class="stat-value" id="avgTemp">-°C</div>
<div class="stat-label">平均温度</div>
</div>
<div class="stat-item">
<div class="stat-value" id="maxTemp">-°C</div>
<div class="stat-label">最高温度</div>
</div>
<div class="stat-item">
<div class="stat-value" id="minTemp">-°C</div>
<div class="stat-label">最低温度</div>
</div>
<div class="stat-item">
<div class="stat-value" id="tempRange">-°C</div>
<div class="stat-label">温度范围</div>
</div>
</div>
</div>
<script>
// 模拟未来一周的气温数据
const weatherData = [
{ day: "周一", date: "6月10日", high: 22, low: 15, condition: "sunny", desc: "晴朗" },
{ day: "周二", date: "6月11日", high: 25, low: 17, condition: "partly-cloudy", desc: "局部多云" },
{ day: "周三", date: "6月12日", high: 28, low: 19, condition: "cloudy", desc: "多云" },
{ day: "周四", date: "6月13日", high: 30, low: 21, condition: "sunny", desc: "晴朗" },
{ day: "周五", date: "6月14日", high: 32, low: 23, condition: "sunny", desc: "晴朗" },
{ day: "周六", date: "6月15日", high: 29, low: 20, condition: "rainy", desc: "阵雨" },
{ day: "周日", date: "6月16日", high: 26, low: 18, condition: "partly-cloudy", desc: "局部多云" }
];
// 天气图标映射
const conditionIcons = {
sunny: "☀️",
"partly-cloudy": "⛅",
cloudy: "☁️",
rainy: "🌧️",
stormy: "⛈️",
snowy: "❄️"
};
// 根据温度获取颜色类别
function getTempColor(temp) {
if (temp < 10) return 0; // 寒冷
if (temp < 18) return 1; // 凉爽
if (temp < 25) return 2; // 舒适
if (temp < 30) return 3; // 温暖
return 4; // 炎热
}
// 初始化
document.addEventListener('DOMContentLoaded', function() {
// 设置日期范围
document.getElementById('dateRange').textContent =
`${weatherData[0].date} - ${weatherData[weatherData.length-1].date}`;
// 生成天气卡片
const weatherCards = document.getElementById('weatherCards');
weatherData.forEach((dayData, index) => {
const card = document.createElement('div');
card.className = 'weather-card';
card.dataset.index = index;
const tempClass = `temp-color-${getTempColor(dayData.high)}`;
card.innerHTML = `
<div class="day">${dayData.day}</div>
<div class="date">${dayData.date}</div>
<div class="weather-icon">${conditionIcons[dayData.condition]}</div>
<div class="temp ${tempClass}">${dayData.high}°C</div>
<div class="high-low">
<div class="high">${dayData.high}°C</div>
<div class="low">${dayData.low}°C</div>
</div>
`;
card.addEventListener('click', function() {
// 移除所有卡片的active类
document.querySelectorAll('.weather-card').forEach(c => c.classList.remove('active'));
// 添加active类到当前卡片
this.classList.add('active');
// 更新详情面板
updateDetailPanel(index);
});
weatherCards.appendChild(card);
});
// 默认选择第一天
document.querySelector('.weather-card').classList.add('active');
updateDetailPanel(0);
// 绘制温度图表
drawTemperatureChart();
// 更新统计数据
updateStatistics();
// 设置按钮事件
document.getElementById('btnWeek').addEventListener('click', function() {
drawTemperatureChart();
});
document.getElementById('btnAvg').addEventListener('click', function() {
drawComparisonChart();
});
document.getElementById('btnDetail').addEventListener('click', function() {
drawDetailedChart();
});
});
// 更新详情面板
function updateDetailPanel(index) {
const dayData = weatherData[index];
document.getElementById('currentDay').textContent = dayData.day;
document.getElementById('currentDate').textContent = dayData.date;
document.getElementById('weatherIcon').textContent = conditionIcons[dayData.condition];
document.getElementById('currentTemp').textContent = `${dayData.high}°C`;
document.getElementById('currentHigh').textContent = `最高: ${dayData.high}°C`;
document.getElementById('currentLow').textContent = `最低: ${dayData.low}°C`;
document.getElementById('weatherDesc').textContent = dayData.desc;
// 更新温度指示器位置
const tempMarker = document.getElementById('tempMarker');
const tempPos = ((dayData.high - 10) / 25) * 100; // 假设温度范围10-35°C
tempMarker.style.left = `${Math.min(100, Math.max(0, tempPos))}%`;
}
// 绘制温度图表
function drawTemperatureChart() {
const canvas = document.getElementById('temperatureChart');
const ctx = canvas.getContext('2d');
// 设置canvas尺寸
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
// 清除画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 图表参数
const margin = { top: 40, right: 40, bottom: 60, left: 60 };
const width = canvas.width - margin.left - margin.right;
const height = canvas.height - margin.top - margin.bottom;
// 温度范围(稍微扩展以留出空间)
const minTemp = Math.min(...weatherData.map(d => d.low)) - 2;
const maxTemp = Math.max(...weatherData.map(d => d.high)) + 2;
// 比例尺
const xScale = (index) => margin.left + (index / (weatherData.length - 1)) * width;
const yScale = (temp) => margin.top + height - ((temp - minTemp) / (maxTemp - minTemp)) * height;
// 绘制网格线
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
ctx.lineWidth = 1;
// 水平网格线(温度)
for (let temp = Math.ceil(minTemp); temp <= maxTemp; temp += 5) {
const y = yScale(temp);
ctx.beginPath();
ctx.moveTo(margin.left, y);
ctx.lineTo(canvas.width - margin.right, y);
ctx.stroke();
// 温度标签
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
ctx.textAlign = 'right';
ctx.fillText(`${temp}°C`, margin.left - 10, y + 4);
}
// 垂直网格线(日期)
for (let i = 0; i < weatherData.length; i++) {
const x = xScale(i);
ctx.beginPath();
ctx.moveTo(x, margin.top);
ctx.lineTo(x, canvas.height - margin.bottom);
ctx.stroke();
// 日期标签
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
ctx.textAlign = 'center';
ctx.fillText(weatherData[i].day, x, canvas.height - margin.bottom + 30);
ctx.fillText(weatherData[i].date, x, canvas.height - margin.bottom + 50);
}
// 绘制高温折线
ctx.beginPath();
ctx.strokeStyle = '#ff9966';
ctx.lineWidth = 3;
for (let i = 0; i < weatherData.length; i++) {
const x = xScale(i);
const y = yScale(weatherData[i].high);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
// 绘制低温折线
ctx.beginPath();
ctx.strokeStyle = '#6bc5f8';
ctx.lineWidth = 3;
for (let i = 0; i < weatherData.length; i++) {
const x = xScale(i);
const y = yScale(weatherData[i].low);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
// 绘制高温点
ctx.fillStyle = '#ff9966';
for (let i = 0; i < weatherData.length; i++) {
const x = xScale(i);
const y = yScale(weatherData[i].high);
ctx.beginPath();
ctx.arc(x, y, 6, 0, Math.PI * 2);
ctx.fill();
// 高温标签
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
ctx.textAlign = 'center';
ctx.fillText(`${weatherData[i].high}°C`, x, y - 15);
ctx.fillStyle = '#ff9966';
}
// 绘制低温点
ctx.fillStyle = '#6bc5f8';
for (let i = 0; i < weatherData.length; i++) {
const x = xScale(i);
const y = yScale(weatherData[i].low);
ctx.beginPath();
ctx.arc(x, y, 6, 0, Math.PI * 2);
ctx.fill();
// 低温标签
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
ctx.textAlign = 'center';
ctx.fillText(`${weatherData[i].low}°C`, x, y + 20);
ctx.fillStyle = '#6bc5f8';
}
// 添加图例
ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
ctx.textAlign = 'left';
ctx.fillText('最高温度', canvas.width - margin.right - 100, margin.top - 20);
ctx.fillText('最低温度', canvas.width - margin.right - 100, margin.top - 5);
ctx.fillStyle = '#ff9966';
ctx.fillRect(canvas.width - margin.right - 120, margin.top - 25, 15, 10);
ctx.fillStyle = '#6bc5f8';
ctx.fillRect(canvas.width - margin.right - 120, margin.top - 10, 15, 10);
}
// 绘制对比图表(与平均温度对比)
function drawComparisonChart() {
// 简化的实现 - 在实际应用中,这里应该绘制更复杂的图表
alert("切换到与平均温度对比视图");
// 在实际实现中,这里会绘制包含历史平均温度的图表
}
// 绘制详细数据图表
function drawDetailedChart() {
// 简化的实现 - 在实际应用中,这里应该绘制更详细的图表
alert("切换到详细数据视图");
// 在实际实现中,这里会绘制包含更多数据点(如每小时温度)的图表
}
// 更新统计数据
function updateStatistics() {
const highs = weatherData.map(d => d.high);
const lows = weatherData.map(d => d.low);
const avgTemp = (highs.reduce((a, b) => a + b, 0) + lows.reduce((a, b) => a + b, 0)) / (highs.length + lows.length);
const maxTemp = Math.max(...highs);
const minTemp = Math.min(...lows);
const tempRange = maxTemp - minTemp;
document.getElementById('avgTemp').textContent = `${avgTemp.toFixed(1)}°C`;
document.getElementById('maxTemp').textContent = `${maxTemp}°C`;
document.getElementById('minTemp').textContent = `${minTemp}°C`;
document.getElementById('tempRange').textContent = `${tempRange}°C`;
}
</script>
</body>
</html>

画折线图区域高亮
区域高亮折线图通过颜色心理学原理,采用黄-红渐变标识异常区间,背景区域透明度降至15%以强化对比,并加入0.8秒间隔的动态呼吸效果。数据标注算法基于标准差检测异常点:计算数据平均值与标准差,标记超出2倍标准差范围的值。Canvas混合模式(globalCompositeOperation: 'multiply')实现高亮区域叠加,rgba(255,204,0,0.15)的填充色确保视觉柔和性。在工业检测场景中,某半导体工厂通过此技术实时监控生产良率,自动标注低于95%的区间,并触发连续3个异常点的设备报警。工艺优化环节,工程师可对比不同参数组的异常区域分布,快速定位最佳生产配置。实际部署中,系统成功将缺陷检测效率提升40%,误报率降低至3%以下。
bash
模拟折线图区域高亮

bash
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>折线图区域高亮模拟</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
color: white;
min-height: 100vh;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto;
}
header {
text-align: center;
margin-bottom: 30px;
padding: 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
}
h1 {
font-size: 2.5rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
background: linear-gradient(to right, #6dd5ed, #2193b0);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
}
.dashboard {
display: grid;
grid-template-columns: 1fr 300px;
gap: 25px;
margin-bottom: 30px;
}
.chart-container {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
height: 500px;
position: relative;
overflow: hidden;
}
.info-panel {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
display: flex;
flex-direction: column;
justify-content: center;
}
.info-panel h2 {
margin-bottom: 15px;
border-bottom: 2px solid rgba(255, 255, 255, 0.3);
padding-bottom: 10px;
color: #6dd5ed;
}
.data-point {
margin-bottom: 20px;
padding: 15px;
background: rgba(255, 255, 255, 0.05);
border-radius: 10px;
transition: all 0.3s ease;
}
.data-point.active {
background: rgba(109, 213, 237, 0.2);
box-shadow: 0 0 15px rgba(109, 213, 237, 0.5);
}
.data-point h3 {
font-size: 1.2rem;
margin-bottom: 5px;
display: flex;
align-items: center;
}
.data-point h3::before {
content: '';
width: 12px;
height: 12px;
border-radius: 50%;
margin-right: 10px;
background: #6dd5ed;
}
.data-value {
font-size: 1.8rem;
font-weight: bold;
margin: 10px 0;
color: #6dd5ed;
}
.data-desc {
font-size: 0.9rem;
opacity: 0.8;
}
.controls {
display: flex;
justify-content: center;
gap: 15px;
margin: 20px 0;
flex-wrap: wrap;
}
button {
background: rgba(109, 213, 237, 0.2);
border: 2px solid rgba(109, 213, 237, 0.5);
border-radius: 30px;
color: white;
padding: 10px 20px;
cursor: pointer;
font-size: 1rem;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
}
button:hover {
background: rgba(109, 213, 237, 0.3);
transform: translateY(-2px);
}
button.active {
background: rgba(109, 213, 237, 0.5);
box-shadow: 0 0 15px rgba(109, 213, 237, 0.5);
}
.statistics {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
margin-top: 30px;
}
.stat-item {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 20px;
text-align: center;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
transition: transform 0.3s ease;
backdrop-filter: blur(10px);
}
.stat-item:hover {
transform: translateY(-5px);
}
.stat-value {
font-size: 2rem;
font-weight: bold;
margin-bottom: 5px;
color: #6dd5ed;
}
.stat-label {
font-size: 0.9rem;
opacity: 0.8;
}
canvas {
width: 100%;
height: 100%;
}
.highlight-hint {
position: absolute;
bottom: 20px;
left: 20px;
font-size: 0.9rem;
opacity: 0.7;
background: rgba(0, 0, 0, 0.3);
padding: 5px 10px;
border-radius: 5px;
}
@media (max-width: 768px) {
.dashboard {
grid-template-columns: 1fr;
}
.statistics {
grid-template-columns: repeat(2, 1fr);
}
h1 {
font-size: 2rem;
}
}
@media (max-width: 480px) {
.statistics {
grid-template-columns: 1fr;
}
.controls {
flex-direction: column;
align-items: center;
}
button {
width: 100%;
justify-content: center;
}
}
/* 动画效果 */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
animation: fadeIn 0.5s ease forwards;
}
/* 标记点样式 */
.marker {
position: absolute;
width: 16px;
height: 16px;
border-radius: 50%;
background: #6dd5ed;
border: 3px solid white;
box-shadow: 0 0 10px rgba(109, 213, 237, 0.8);
transform: translate(-50%, -50%);
pointer-events: none;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 10;
}
.marker.active {
opacity: 1;
}
.tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 15px;
border-radius: 8px;
font-size: 0.9rem;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s ease;
z-index: 20;
transform: translate(-50%, -100%);
white-space: nowrap;
}
.tooltip.active {
opacity: 1;
}
.highlight-area {
position: absolute;
background: rgba(109, 213, 237, 0.2);
pointer-events: none;
border-radius: 5px;
opacity: 0;
transition: opacity 0.3s ease;
}
.highlight-area.active {
opacity: 1;
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>交互式折线图区域高亮</h1>
<div class="subtitle">悬停或点击数据点以高亮相关区域</div>
</header>
<div class="dashboard">
<div class="chart-container">
<canvas id="lineChart"></canvas>
<div class="highlight-hint">← 将鼠标悬停在折线上查看高亮效果</div>
<!-- 标记点和工具提示将通过JS动态创建 -->
</div>
<div class="info-panel">
<h2>数据点详情</h2>
<div class="data-point active">
<h3>一月</h3>
<div class="data-value">42.5</div>
<div class="data-desc">本月数据显示增长趋势</div>
</div>
<div class="data-point">
<h3>二月</h3>
<div class="data-value">38.2</div>
<div class="data-desc">数据较上月有所下降</div>
</div>
<div class="data-point">
<h3>三月</h3>
<div class="data-value">45.7</div>
<div class="data-desc">数据呈现稳定上升</div>
</div>
<div class="data-point">
<h3>四月</h3>
<div class="data-value">51.3</div>
<div class="data-desc">达到季度最高点</div>
</div>
</div>
</div>
<div class="controls">
<button id="btnHover" class="active">
<span>🔍</span> 悬停高亮模式
</button>
<button id="btnClick">
<span>👆</span> 点击高亮模式
</button>
<button id="btnAuto">
<span>🔄</span> 自动高亮演示
</button>
<button id="btnReset">
<span>↺</span> 重置视图
</button>
</div>
<div class="statistics">
<div class="stat-item fade-in">
<div class="stat-value">44.4</div>
<div class="stat-label">平均值</div>
</div>
<div class="stat-item fade-in" style="animation-delay: 0.1s;">
<div class="stat-value">51.3</div>
<div class="stat-label">最大值</div>
</div>
<div class="stat-item fade-in" style="animation-delay: 0.2s;">
<div class="stat-value">38.2</div>
<div class="stat-label">最小值</div>
</div>
<div class="stat-item fade-in" style="animation-delay: 0.3s;">
<div class="stat-value">13.1</div>
<div class="stat-label">数据范围</div>
</div>
</div>
</div>
<script>
// 样本数据
const sampleData = [
{ month: "一月", value: 42.5, desc: "本月数据显示增长趋势" },
{ month: "二月", value: 38.2, desc: "数据较上月有所下降" },
{ month: "三月", value: 45.7, desc: "数据呈现稳定上升" },
{ month: "四月", value: 51.3, desc: "达到季度最高点" },
{ month: "五月", value: 48.6, desc: "数据略有回落" },
{ month: "六月", value: 46.2, desc: "保持稳定水平" },
{ month: "七月", value: 49.8, desc: "夏季回升趋势" },
{ month: "八月", value: 53.1, desc: "创下年度新高" },
{ month: "九月", value: 50.4, desc: "数据小幅调整" },
{ month: "十月", value: 47.9, desc: "进入平稳期" },
{ month: "十一月", value: 45.3, desc: "年终数据整理" },
{ month: "十二月", value: 42.8, desc: "年度数据总结" }
];
// 图表状态变量
let hoverMode = true;
let activePointIndex = -1;
let animationId = null;
let isAutoAnimating = false;
// 初始化图表
document.addEventListener('DOMContentLoaded', function() {
const canvas = document.getElementById('lineChart');
const ctx = canvas.getContext('2d');
// 设置canvas尺寸
function resizeCanvas() {
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
drawChart();
}
// 初始调整尺寸
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// 绘制图表
function drawChart(highlightIndex = -1) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 图表参数
const margin = { top: 50, right: 50, bottom: 70, left: 70 };
const width = canvas.width - margin.left - margin.right;
const height = canvas.height - margin.top - margin.bottom;
// 数据范围
const values = sampleData.map(d => d.value);
const minValue = Math.min(...values) - 5;
const maxValue = Math.max(...values) + 5;
// 比例尺
const xScale = (index) => margin.left + (index / (sampleData.length - 1)) * width;
const yScale = (value) => margin.top + height - ((value - minValue) / (maxValue - minValue)) * height;
// 绘制网格
drawGrid(ctx, margin, width, height, minValue, maxValue, xScale, yScale);
// 绘制区域高亮
if (highlightIndex >= 0) {
drawHighlightArea(ctx, highlightIndex, xScale, yScale, margin, height, minValue);
}
// 绘制折线
drawLine(ctx, sampleData, xScale, yScale);
// 绘制数据点
drawDataPoints(ctx, sampleData, xScale, yScale, highlightIndex);
// 绘制坐标轴标签
drawAxisLabels(ctx, margin, width, height, sampleData, minValue, maxValue);
}
// 绘制网格
function drawGrid(ctx, margin, width, height, minValue, maxValue, xScale, yScale) {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
ctx.lineWidth = 1;
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
ctx.font = '12px Arial';
ctx.textAlign = 'center';
// 水平网格线
const ySteps = 5;
for (let i = 0; i <= ySteps; i++) {
const value = minValue + (i / ySteps) * (maxValue - minValue);
const y = yScale(value);
ctx.beginPath();
ctx.moveTo(margin.left, y);
ctx.lineTo(margin.left + width, y);
ctx.stroke();
// Y轴标签
ctx.textAlign = 'right';
ctx.fillText(value.toFixed(1), margin.left - 10, y + 4);
}
// 垂直网格线
ctx.textAlign = 'center';
for (let i = 0; i < sampleData.length; i++) {
const x = xScale(i);
ctx.beginPath();
ctx.moveTo(x, margin.top);
ctx.lineTo(x, margin.top + height);
ctx.stroke();
// X轴标签
ctx.fillText(sampleData[i].month, x, margin.top + height + 20);
}
}
// 绘制高亮区域
function drawHighlightArea(ctx, highlightIndex, xScale, yScale, margin, height, minValue) {
const x = xScale(highlightIndex);
const y = yScale(sampleData[highlightIndex].value);
// 创建高亮区域渐变
const gradient = ctx.createLinearGradient(0, margin.top, 0, margin.top + height);
gradient.addColorStop(0, 'rgba(109, 213, 237, 0.3)');
gradient.addColorStop(1, 'rgba(109, 213, 237, 0.1)');
ctx.fillStyle = gradient;
ctx.beginPath();
// 绘制高亮区域
ctx.moveTo(x, margin.top);
ctx.lineTo(x, margin.top + height);
// 绘制到基线的区域
ctx.lineTo(x, yScale(minValue));
ctx.lineTo(x, margin.top + height);
ctx.fill();
// 高亮线
ctx.strokeStyle = 'rgba(109, 213, 237, 0.8)';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(x, margin.top);
ctx.lineTo(x, margin.top + height);
ctx.stroke();
}
// 绘制折线
function drawLine(ctx, data, xScale, yScale) {
ctx.strokeStyle = '#6dd5ed';
ctx.lineWidth = 3;
ctx.lineJoin = 'round';
ctx.beginPath();
for (let i = 0; i < data.length; i++) {
const x = xScale(i);
const y = yScale(data[i].value);
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
}
ctx.stroke();
// 添加渐变填充
const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, 'rgba(109, 213, 237, 0.3)');
gradient.addColorStop(1, 'rgba(109, 213, 237, 0)');
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.moveTo(xScale(0), yScale(data[0].value));
for (let i = 1; i < data.length; i++) {
ctx.lineTo(xScale(i), yScale(data[i].value));
}
ctx.lineTo(xScale(data.length - 1), canvas.height);
ctx.lineTo(xScale(0), canvas.height);
ctx.closePath();
ctx.fill();
}
// 绘制数据点
function drawDataPoints(ctx, data, xScale, yScale, highlightIndex = -1) {
for (let i = 0; i < data.length; i++) {
const x = xScale(i);
const y = yScale(data[i].value);
// 数据点
ctx.beginPath();
ctx.arc(x, y, 6, 0, Math.PI * 2);
if (i === highlightIndex) {
ctx.fillStyle = '#fff';
ctx.strokeStyle = '#6dd5ed';
ctx.lineWidth = 3;
} else {
ctx.fillStyle = '#6dd5ed';
ctx.strokeStyle = 'transparent';
}
ctx.fill();
ctx.stroke();
// 数据标签
ctx.fillStyle = 'white';
ctx.font = 'bold 14px Arial';
ctx.textAlign = 'center';
ctx.fillText(data[i].value, x, y - 15);
}
}
// 绘制坐标轴标签
function drawAxisLabels(ctx, margin, width, height, data, minValue, maxValue) {
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
ctx.font = 'bold 16px Arial';
ctx.textAlign = 'center';
// X轴标题
ctx.fillText('月份', margin.left + width / 2, margin.top + height + 50);
// Y轴标题
ctx.save();
ctx.translate(20, margin.top + height / 2);
ctx.rotate(-Math.PI / 2);
ctx.fillText('数值', 0, 0);
ctx.restore();
// 图表标题
ctx.font = 'bold 20px Arial';
ctx.fillText('年度数据趋势图', margin.left + width / 2, 30);
}
// 设置交互事件
function setupInteractions() {
canvas.addEventListener('mousemove', function(e) {
if (!hoverMode || isAutoAnimating) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 检查鼠标是否接近数据点
const margin = { left: 70, top: 50 };
const width = canvas.width - margin.left - 50;
const index = Math.round(((x - margin.left) / width) * (sampleData.length - 1));
if (index >= 0 && index < sampleData.length) {
const pointX = margin.left + (index / (sampleData.length - 1)) * width;
const pointY = 50 + (canvas.height - 120) -
((sampleData[index].value - (Math.min(...sampleData.map(d => d.value)) - 5)) /
((Math.max(...sampleData.map(d => d.value)) + 5) - (Math.min(...sampleData.map(d => d.value)) - 5))) *
(canvas.height - 120);
const distance = Math.sqrt(Math.pow(x - pointX, 2) + Math.pow(y - pointY, 2));
if (distance < 30) {
activePointIndex = index;
drawChart(index);
updateInfoPanel(index);
} else if (activePointIndex !== -1) {
activePointIndex = -1;
drawChart();
resetInfoPanel();
}
}
});
canvas.addEventListener('click', function(e) {
if (hoverMode || isAutoAnimating) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
// 检查鼠标是否接近数据点
const margin = { left: 70, top: 50 };
const width = canvas.width - margin.left - 50;
const index = Math.round(((x - margin.left) / width) * (sampleData.length - 1));
if (index >= 0 && index < sampleData.length) {
const pointX = margin.left + (index / (sampleData.length - 1)) * width;
const pointY = 50 + (canvas.height - 120) -
((sampleData[index].value - (Math.min(...sampleData.map(d => d.value)) - 5)) /
((Math.max(...sampleData.map(d => d.value)) + 5) - (Math.min(...sampleData.map(d => d.value)) - 5))) *
(canvas.height - 120);
const distance = Math.sqrt(Math.pow(x - pointX, 2) + Math.pow(y - pointY, 2));
if (distance < 30) {
activePointIndex = index;
drawChart(index);
updateInfoPanel(index);
}
}
});
canvas.addEventListener('mouseleave', function() {
if (hoverMode && !isAutoAnimating) {
activePointIndex = -1;
drawChart();
resetInfoPanel();
}
});
}
// 更新信息面板
function updateInfoPanel(index) {
// 移除所有活动类
document.querySelectorAll('.data-point').forEach(item => {
item.classList.remove('active');
});
// 添加活动类到对应数据点
if (index < document.querySelectorAll('.data-point').length) {
document.querySelectorAll('.data-point')[index].classList.add('active');
}
}
// 重置信息面板
function resetInfoPanel() {
document.querySelectorAll('.data-point').forEach(item => {
item.classList.remove('active');
});
}
// 设置控制按钮事件
document.getElementById('btnHover').addEventListener('click', function() {
hoverMode = true;
isAutoAnimating = false;
activePointIndex = -1;
drawChart();
resetInfoPanel();
// 更新按钮状态
document.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
// 取消自动动画
if (animationId) {
cancelAnimationFrame(animationId);
animationId = null;
}
});
document.getElementById('btnClick').addEventListener('click', function() {
hoverMode = false;
isAutoAnimating = false;
activePointIndex = -1;
drawChart();
resetInfoPanel();
// 更新按钮状态
document.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
// 取消自动动画
if (animationId) {
cancelAnimationFrame(animationId);
animationId = null;
}
});
document.getElementById('btnAuto').addEventListener('click', function() {
isAutoAnimating = true;
activePointIndex = -1;
drawChart();
resetInfoPanel();
// 更新按钮状态
document.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
this.classList.add('active');
// 开始自动动画
startAutoHighlight();
});
document.getElementById('btnReset').addEventListener('click', function() {
hoverMode = true;
isAutoAnimating = false;
activePointIndex = -1;
drawChart();
resetInfoPanel();
// 更新按钮状态
document.querySelectorAll('button').forEach(btn => btn.classList.remove('active'));
document.getElementById('btnHover').classList.add('active');
// 取消自动动画
if (animationId) {
cancelAnimationFrame(animationId);
animationId = null;
}
});
// 自动高亮演示
function startAutoHighlight() {
let index = 0;
function animate() {
drawChart(index);
updateInfoPanel(index);
index = (index + 1) % sampleData.length;
animationId = requestAnimationFrame(animate);
}
// 每1.5秒切换一次高亮点
animationId = requestAnimationFrame(animate);
}
// 初始化交互
setupInteractions();
});
</script>
</body>
</html>

谁养鱼?
提示词
在一条街上,有 5 座房子,喷了 5 种颜色;
每座房子里住着不同国籍的人;每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物。
问题:谁养鱼?
提示:英国人住红色房子、瑞典人养狗、丹麦人喝茶、绿色房子在白色房子左面、绿色房子的主人喝咖啡、抽 Pall Mall 香烟的人养鸟、黄色房子的主人抽 Dunhill 香烟、住在中间房子的人喝牛奶、 挪威人住第一间房、抽 Blends 香烟的人住在养猫人的隔壁、养马的人住抽 Dunhill 香烟的人隔壁、抽 Blue Master 的人喝啤酒、德国人抽 Prince 香烟、挪威人住蓝色房子隔壁、抽 Blends 香烟的人有一个喝水的邻居。
看着一步一步的分析下来,有条有理且速度很快(虽然分析下来很长,但是期间的速度非常快),这个结果让我挺意外的,之前接触到了太多思考一半停顿一会儿的大模型,但是面前的这位DeepSeek-V3.1-Terminus真是让人感到意外!
写作能力
提示词:
写一篇关于夏天的高考满分作文,要求字数在800字以上。

解理综物理真题
提示词
一高压舱内气体的压强为 1.2 个大气压,温度为 17℃,密度为 1.46 kg/m³。
(i)升高气体温度并释放出舱内部分气体以保持压强不变,求气体温度升至 27℃ 时舱内气体的密度;
(ii)保持温度 27℃ 不变,再释放出舱内部分气体使舱内压强降至 1.0 个大气压,求舱内气体的密度。
提供解题过程,并给出答案。
此处过程简单明了,显而易见,不啰嗦,并且结果精确到了小数点后三位,在解题方面很不错
总结
在本次深度体验中,通过蓝耘元生代MaaS平台调用DeepSeek-V3.1-Terminus模型,展现了这款大语言模型在复杂问题解决方面的强大能力。无论是需要严谨逻辑推理的"谁养鱼"经典谜题,还是要求创造力的高考作文写作,亦或是需要精确计算的物理题目,模型都表现出了令人印象深刻的综合素养。
特别值得注意的是,模型在解决逻辑推理问题时展现出的系统性思维------它能够将复杂条件逐步拆解,建立完整的逻辑链条,并且在整个推理过程中保持稳定的输出节奏,没有出现常见的思考中断现象。这种流畅的问题解决体验,在实际应用中尤为重要。
从技术实现角度来看,通过CherryStudio这样的AI助手平台接入蓝耘API的方式,为普通用户提供了低门槛的使用体验。平台简洁的界面设计和直观的操作流程,使得即使没有技术背景的用户也能快速上手。而蓝耘平台提供的免费额度,更是降低了AI技术的使用门槛,让更多开发者和小型团队能够体验到大模型的能力。
综合来看,DeepSeek-V3.1-Terminus在语言一致性、推理能力和专业问题解决方面都有显著提升,配合蓝耘平台稳定的服务支持,为国内AI应用落地提供了可靠的技术基础。这种"模型+平台"的组合模式,正在让高端AI技术从实验室走向实际应用,为各行各业的智能化转型注入新的动力。
蓝耘元生代MaaS平台已上线KIMI K2、千问系列、DeepSeek、MiniMax、百川系列的量化及蒸馏版本等多种模态,且全部支持直接调用 API、私有化部署等多种使用方式,满足不同用户对于数据安全、应用场景的个性化需求。