前端(razor)
放在项目根目录下的Pages文件夹中。
@page "/ab1"
@using BlazorApp1.Data
@inject Ab1Service aService
@inject IJSRuntime JsRuntime
@inject IWebHostEnvironment Environ
@using System.Text.RegularExpressions;
<PageTitle>Ab1</PageTitle>
<div class="container-fluid p-5">
<div class="row" style="margin-top:1%;">
<div>
<label>
提示信息:@Message
</label>
</div>
<br/>
<div>
输入中心点:<input class="input-group-text" type="text" @bind-value="@targetPos" />
</div>
<br />
<div>
<label>
选择上传文件:<InputFile OnChange="@LoadFiles" multiple />
</label>
@if (isLoading)
{
<p>文件上传中......</p>
}
else
{
<ul>
@foreach (var file in loadedFiles)
{
<li>
<ul>
<li class="full-width">文件名:@file.Name</li>
<li>最后修改时间:@file.LastModified.ToString()</li>
<li>文件大小(byte):@file.Size</li>
<li>文件类型:@file.ContentType</li>
</ul>
</li>
}
</ul>
}
</div>
</div>
<div id="exportBtnDiv" style="display:none">
<button value="" class="btn btn-primary" id="ExportSvgBtn" @onclick="ExportSvg" data-toggle="tooltip" title="导出图像">
导出图像
</button>
</div>
<div class="row" style="display:flex; justify-content:center; align-items:center; width:100%; height:100%;">
@if (ab1 != null)
{
<svg id="mySvg" height="160" width="@ab1.max_width" xmlns="http://www.w3.org/2000/svg" style="display:none;padding:0;margin:0">
<rect id="myRect" width="@ab1.max_width" height="160" fill="white" style="margin:0" />
@if (ab1.ya != null && ab1.ya.Length > 0)
{
<path d="@ab1.ya" stroke="green" fill="none" stroke-width="@ab1.line_width" />
<path d="@ab1.yc" stroke="blue" fill="none" stroke-width="@ab1.line_width" />
<path d="@ab1.yg" stroke="black" fill="none" stroke-width="@ab1.line_width" />
<path d="@ab1.yt" stroke="red" fill="none" stroke-width="@ab1.line_width" />
}
@if (ab1.Ab1Chars.Count > 0)
{
@foreach (Ab1Char a in ab1.Ab1Chars)
{
@if (a.ch == "A")
{
color = "green";
}
else if (a.ch == "C")
{
color = "blue";
}
else if (a.ch == "G")
{
color = "black";
}
else
{
color = "red";
}
<g>
<!-- y是底端 -->
<text x="@a.x" y="30" fill="@color" font-family="Courier New" font-size="20" font-weight="bold">@a.ch</text>
</g>
}
}
<path d="@ab1.ArrowPathData" stroke="red" fill="red" stroke-width="0.5"></path>
</svg>
}
</div>
</div>
<style>
.full-width {
white-space: nowrap; /* 禁止换行 */
overflow: hidden; /* 隐藏溢出部分 */
text-overflow: clip; /* 显示完整内容,不显示省略号 */
}
</style>
<script>
window.interop = {
}
function showSvg() {
document.getElementById('mySvg').style.display = 'block';
}
function hideSvg() {
document.getElementById('mySvg').style.display = 'none';
}
function showExportBtn() {
document.getElementById('exportBtnDiv').style.display = 'block';
}
</script>
@code {
private Data.Ab1? ab1;
private string targetPos = "";
private IJSObjectReference module;
private List<IBrowserFile> loadedFiles = new();
private int maxFileSize = 5 * 1024 * 1024;
private int maxAllowedFiles = 1;
private bool isLoading;
private string Message = string.Empty;
private string color = "black";
private async Task LoadFiles(InputFileChangeEventArgs e)
{
await JsRuntime.InvokeAsync<object>("hideSvg");
isLoading = true;
loadedFiles.Clear();
foreach (var file in e.GetMultipleFiles(maxAllowedFiles))
{
try
{
//ModelStateDictionary modelState = new ModelStateDictionary();
loadedFiles.Add(file);
//string result = await FileHelpers.ProcessFormFile(file, modelState, Environ, maxFileSize);
// 存储到本地
Ab1Obj ab1Obj = await Ab1Service.ProcessFormFile(file, Environ, maxFileSize, int.Parse(targetPos));
if (ab1Obj != null)
{
Message = "成功";
// 更新svg
ab1 = await aService.GetAb1Async(ab1Obj);
await JsRuntime.InvokeAsync<object>("showSvg");
await JsRuntime.InvokeAsync<object>("showExportBtn");
}
else
{
Message = "失败";
}
}
catch (Exception ex)
{
Message = ex.Message;
}
}
isLoading = false;
}
protected override async Task OnInitializedAsync()
{
ab1 = await aService.GetAb1Async();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
//await UpdateRadius();
module = await JsRuntime.InvokeAsync<IJSObjectReference>("import", "./exportSvg.js");
}
}
private async Task ExportSvg()
{
var svgElement = await JsRuntime.InvokeAsync<IJSObjectReference>("document.getElementById", "mySvg");
await module.InvokeVoidAsync("exportSvgToImage2", svgElement, "png", ab1.max_width);
}
}
Ab1Service
放在项目根目录下的Data文件夹中。
using Microsoft.AspNetCore.Components.Forms;
namespace BlazorApp1.Data
{
public class Ab1Service
{
public Task<Ab1> GetAb1Async()
{
Ab1 ab1 = new Ab1();
return Task.FromResult(ab1);
}
public Task<Ab1> GetAb1Async(Ab1Obj ab1Obj) {
Ab1 ab1 = new Ab1();
double max_width = 0.0;
List<string> ans = ab1Obj.GetPathData(out max_width);
ab1.ya = ans[0];
ab1.yc = ans[1];
ab1.yg = ans[2];
ab1.yt = ans[3];
ab1.max_width = max_width;
List<Ab1Char> ab1Chars = ab1Obj.GetXPosData();
ab1.Ab1Chars.AddRange(ab1Chars);
// 固定值
ab1.ArrowPathData = ab1Obj.GetArrowData(20);
return Task.FromResult(ab1);
}
/// <summary>
/// 上传的文件存储到:C:\项目根目录\Development\unsafeUploads
/// </summary>
/// <param name="formFile"></param>
/// <param name="envir"></param>
/// <param name="maxFileSize">前端的文件大小限制,目前是5MB</param>
/// <returns></returns>
public static async Task<Ab1Obj> ProcessFormFile(IBrowserFile formFile, IWebHostEnvironment envir, int maxFileSize, int target)
{
var path = Path.Combine(envir.ContentRootPath, envir.EnvironmentName, "unsafeUploads", formFile.Name);
using (
var reader =
new FileStream(
path,
FileMode.Create))
{
await formFile.OpenReadStream(maxFileSize).CopyToAsync(reader);
}
// 读取
Ab1Obj ab1Obj = new Ab1Obj(path, target);
return ab1Obj;
}
}
}
Ab1Obj和Ab1类
Ab1Obj是解析ab1文件的类,里面包含一些变量和解析相关的函数。这部分受版权保护,恕不公开。
Ab1类的实现是:
namespace BlazorApp1.Data
{
public class Ab1Char {
public string ch = "";
public double x = 0.0;
public Ab1Char() { }
public Ab1Char(string ch, double x) {
this.ch = ch;
this.x = x;
}
}
public class Ab1
{
// 记录y值
public string ya { set; get; } = "";
public string yc { set; get; } = "";
public string yg { set; get; } = "";
public string yt { set; get; } = "";
public double max_width { set; get; } = 0.0;
public int line_width { set; get; } = 3;
public int target { set; get; } = 0;
// 记录字母的位置
public List<Ab1Char> Ab1Chars = new List<Ab1Char>();
// 记录箭头的path数据
public string ArrowPathData = "";
}
}