Blazor入门-简单svg绘制+导出图像

参考:
SVG 教程 | 菜鸟教程
https://www.runoob.com/svg/svg-tutorial.html

本地环境:win10, visual studio 2022 community


注意:本文只给出思路和框架,对于具体的计算细节,考虑到日后会写入软件著作权和专利文书,因此不会展示。(虽然大概率要经过修改后才会放进文书,但是考虑到隐私保护,还是不写了。不过基本都是三角函数)

目录

  • 效果
  • 实现
    • 思路
    • 前端
    • 下载svg图像的js代码
    • 报错
      • Error: Microsoft.JSInterop.JSException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
      • 下载svg图像时,只显示一部分
  • 改进

效果

在这里插入图片描述
导出效果:
在这里插入图片描述

实现

思路

<svg>标签内,首先绘制两个圆,形成圆环;然后再使用循环,每次绘制一组<path><line><text>。需要着重考虑的是:

  • <path>的数据属性(d)、<line>中起终点坐标和<text>坐标的计算(这部分是三角函数,不展开)
  • 导出按钮的onclick函数编写
  • 实际的导出函数(js)

前端

    <div>
        <svg id="mySvg" width="100%" xmlns="http://www.w3.org/2000/svg" style="display:none">
            <rect  width="100%" height="100%" fill="white" />
            <circle cx="@cx" cy="@cy" r="@outerRadius" fill="#ccc" stroke="#ccc" stroke-width="1" />
            <circle cx="@cx" cy="@cy" r="@innerRadius" fill="#fff" stroke="#ccc" stroke-width="1" />
            @foreach (DisplayPart p in v.Parts)
            {
                <g>
                    <path d="@p.PathData" opacity="0.5" fill="@p.Color" stroke="black" stroke-width="2" data-toggle="tooltip" title="@p.Name" />
                    <line x1="@p.Lcx" y1="@p.Lcy" x2="@p.Tcx" y2="@p.Tcy" stroke="black" stroke-width="1" />
                    <text x="@p.Tcx" y="@p.Tcy" fill="black">@p.Name</text>
                </g>
                
            }
        </svg>
    </div>

    <div id="exportBtnDiv" style="display:none">
        <button value="" class="btn btn-primary" id="ExportSvgBtn" @onclick="ExportSvg">
            导出图谱
        </button>
    </div>

注意:

  • <rect width="100%" height="100%" fill="white" />是为svg增加白色背景
  • 其中@开头的变量都是在code中定义的
  • v.PartsList<DisplayPart>DisplayPart是自定义的一个类型

随后,在@code{}块中,实现ExportSvgBtn

    private async Task ExportSvg()
    {
        var svgElement = await JsRuntime.InvokeAsync<IJSObjectReference>("document.getElementById", "mySvg");
        await module.InvokeVoidAsync("exportSvgToImage", svgElement, "png");
    }

其中JsRuntime是:

@inject IJSRuntime JsRuntime

而module在前面定义过,这里用它可以调用在别处定义的js函数。
参考:
Blazor入门-调用js+例子-CSDN博客
https://blog.csdn.net/pxy7896/article/details/138670348

跟这篇文章里一样设置即可。

下载svg图像的js代码

export function exportSvgToImage(svgElement, format) {
    if (format == null)
        return;
    var svgXml = new XMLSerializer().serializeToString(svgElement);
    var imageUrl = "data:image/svg+xml;base64," + btoa(svgXml);
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    var img = new Image();
    img.onload = function () {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0);
        var a = document.createElement("a");
        a.download = "exported_image." + format;
        a.href = canvas.toDataURL("image/" + format);
        a.click();
    };
    img.src = imageUrl;
}

注意:函数前面写export的原因已在上一节的参考文章里解释。

报错

Error: Microsoft.JSInterop.JSException: Failed to execute ‘btoa’ on ‘Window’: The string to be encoded contains characters outside of the Latin1 range.

这个错误通常发生是因为要编码的字符串中包含了Latin1范围之外的字符。解决方案是修改 exportSvgToImage 函数的这句:

var imageUrl = "data:image/svg+xml;base64," + btoa(svgXml);

改为:

var utf8 = unescape(encodeURIComponent(svgXml));
var imageUrl = "data:image/svg+xml;base64," + btoa(utf8);

下载svg图像时,只显示一部分

使用上面下载图像的js代码时,输出的图像可能只有一部分,如下图所示:
在这里插入图片描述
解决方案是将canvas的宽高设置为跟svg元素一致:

    canvas.width = svgElement.clientWidth;
    canvas.height = svgElement.clientHeight;

改进

未来会通过算法调整label的位置和line的线形,以避免label重叠。如果可以的话,会再写:)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

visio生成pdf文件有黑边(边框),插入latex输出有边框

解决办法&#xff1a; 1 文件-导出pdf-点击“选项” 2 选择取消勾选

HTML静态网页成品作业(HTML+CSS)——利物浦足球俱乐部介绍网页设计制作(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;共有5个页面。 二、作品演示 三、代码目录 四、网站代码 HTML部分代…

TikTok矩阵管理系统:品牌增长的新引擎

随着社交媒体的快速发展&#xff0c;TikTok已成为全球最受欢迎的短视频平台之一。品牌和企业纷纷涌入这个平台&#xff0c;寻求新的增长机会。然而&#xff0c;随着内容的激增和用户群体的多样化&#xff0c;管理TikTok账号变得越来越复杂。这时&#xff0c;TikTok矩阵管理系统…

LLaMa系列模型详解(原理介绍、代码解读):LLaMA 3

LLaMA 3 2024年4月18日&#xff0c;Meta 重磅推出了Meta Llama 3&#xff0c;Llama 3是Meta最先进开源大型语言模型的下一代&#xff0c;包括具有80亿和700亿参数的预训练和指令微调的语言模型&#xff0c;能够支持广泛的应用场景。这一代Llama在一系列行业标准基准测试中展示…

数据仓库实验四:聚类分析实验

目录 一、实验目的二、实验内容和要求三、实验步骤1、建立数据表2、建立数据源视图3、建立挖掘结构Student.dmm4、部署项目并浏览结果5、挖掘模型预测 四、实验结果分析五、实验总结体会 一、实验目的 通过本实验&#xff0c;进一步理解基于划分的、基于层次的、基于密度的聚类…

Python 渗透测试:GhostScript 沙箱绕过.(CVE-2018-16509)

什么是 GhostScript 沙箱绕过 GhostScript 沙箱是一种安全机制,用于在受控环境中运行 GhostScript 解释器,以防止恶意代码的执行。GhostScript 是一个广泛使用的 PDF 和 PostScript 解释器,通常用于在服务器上处理和渲染这些文件格式。Tavis Ormandy 通过公开邮件列表&#xf…

[Algorithm][动态规划][路径问题][不同路径][不同路径Ⅱ][珠宝的最高价值]详细讲解

目录 1.不同路径1.题目链接2.算法原理详解3.代码实现 2.不同路径 II1.题目链接2.算法原理详解3.代码实现 3.珠宝的最高价值1.题目链接2.算法原理详解3.代码实现 1.不同路径 1.题目链接 不同路径 2.算法原理详解 思路&#xff1a; 确定状态表示 -> dp[i][j]的含义 走到dp[…

docker和containerd的区别

docker和containerd的区别 1、容器运行时 1.1 容器运行时概念 容器运行时&#xff08;Container Runtime&#xff09;是一种负责在操作系统层面创建和管理容器的软件工具或组件。它是容器化技术的核心组件之一&#xff0c;用于在容器内部运行应用程序&#xff0c;并提供隔离…

pdf加水印怎么加?3种添加水印方法分享

pdf加水印怎么加&#xff1f;PDF加水印不仅是为了保护文档内容&#xff0c;确保信息的安全性和完整性&#xff0c;更是一种有效的版权保护措施。通过添加水印&#xff0c;您可以在文档中嵌入公司名称、日期、编号等信息&#xff0c;以明确文档的归属权和使用限制。此外&#xf…

Anti Desgin Vue 实现 表格可编辑、新增、删除功能

1、效果图 新增&#xff1a; 删除&#xff1a; 修改&#xff1a; 代码&#xff1a; <template><div><button click"add">添加</button><span style"margin-left: 8px"><template v-if"hasSelected">{…

浏览器的下载行为基本原理

浏览器解析 在使用浏览器访问某些资源时&#xff0c;有些资源是直接下载有些资源是直接打开。例如前端的html&#xff0c;xml&#xff0c;css&#xff0c;图片等资源都是直接打开&#xff0c;而txt&#xff0c;excel等文件是直接下载。那么如何控制访问一个资源时是下载文件还…

stm32学习-光敏传感器控制蜂鸣器

接线 GPIO配置 初始化GPIO 1.使用RCC开启GPIO时钟 void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState); 作用&#xff1a;外设时钟控制(根据外设连接的总线选择要开启的时钟&#xff09; RCC_AHBPeriph/RCC_APB2Periph/RCC_APB1Periph&#x…

.NET Core Web Api Swagger运行异常

遇到的问题 因为新增了一个控制器方法&#xff0c;从而导致在运行Swagger的时候直接报错&#xff0c;异常如下&#xff1a; SwaggerGeneratorException: Conflicting method/path combination "POST api/UserOperationExample" for actions - WebApi.Controllers.Us…

GMSL图像采集卡,适用于无人车、自动驾驶、自主机器、数据采集等场景,支持定制

基于各种 系列二代 G MS L 图像采集卡&#xff08;以下简称 二代图像采集卡&#xff09;是一款自主研发的一款基于 F P G A 的高速图像产品&#xff0c;二代图像采集卡相比一代卡&#xff0c;由于采用PCIe G en 3 技术&#xff0c;速度和带宽都相应的有了成 倍的提高。该图像…

开源与闭源AI模型的对决:数据隐私、商业应用与社区参与

引言 在人工智能&#xff08;AI&#xff09;领域&#xff0c;模型的发展路径主要分为“开源”和“闭源”两条。这两种模型在数据隐私保护、商业应用以及社区参与与合作方面各有优劣&#xff0c;是创业公司、技术巨头和开发者们必须仔细权衡的重要选择。那么&#xff0c;面对这些…

【经验技巧】谷歌高级搜索语法

谷歌高级搜索语法是一些特殊的搜索指令&#xff0c;可以在谷歌搜索框中使用以帮助您更准确地找到您需要的信息。以下是一些常用的谷歌高级搜索语法&#xff1a; 搜索特定词组&#xff1a;用引号将词组括起来&#xff0c;例如&#xff1a;“人工智能” 排除特定词语&#xff1a…

前端 基础 综合案例 二 注册页面( 简单版)A

案例示例 &#xff1a; 案例 分析 &#xff1a; 我们将 上示网页&#xff0c;拆成两个部分进行分析&#xff1a; 很显然&#xff0c;网页 第一行&#xff0c;是标题&#xff08;青春不常在&#xff0c;抓紧谈恋爱&#xff09;&#xff0c; 我们就用 h4 去完成&#xff1b…

若依nodejs版本过高问题解决方案

由于nodejs版本过高,可能会导致vue-cli项目运行报错。 目录 方法1:每次启动项目前,输入配置命令 方法2:修改package.js

Study--Oracle-03-Oracle19C--RAC集群部署

一、硬件信息及配套软件 1、硬件设置 RAC集群虚拟机&#xff1a;CPU:2C、内存&#xff1a;9G、操作系统&#xff1a;30G、数据库安装目录&#xff1a;100G 数据存储&#xff1a;50G &#xff08;10G*5&#xff09; 共享存储&#xff1a;2G &#xff08;1G*2&#xff09; 2…