這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)如何用Blazor技術(shù)封裝G2Plot實(shí)現(xiàn)Charts組件,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、做網(wǎng)站、平江網(wǎng)絡(luò)推廣、微信小程序、平江網(wǎng)絡(luò)營(yíng)銷、平江企業(yè)策劃、平江品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供平江建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:chinadenli.net
Blazor是一個(gè)使用 .NET 生成交互式客戶端 Web UI 的框架。目前社區(qū)剛起步,相關(guān)的組件并不多,有幸有一群愛(ài)好者正在努力建設(shè)社區(qū),我作為社區(qū)一員也來(lái)貢獻(xiàn)一些內(nèi)容。這里我就分享分享我封裝G2Plot后的Blazor組件ant-design-charts-blazor。
ant-design-charts-blazor屬于Ant Design of Blazor的一個(gè)開(kāi)源項(xiàng)目,我們的目標(biāo)是做Ant Design在Blazor生態(tài)圈最優(yōu)秀的實(shí)現(xiàn),廢話不多說(shuō),先來(lái)看一下目前實(shí)現(xiàn)的圖表。

項(xiàng)目地址:
ant-design-blazor/ant-design-charts-blazor github.com
安裝 Nuget 包引用
$ dotnet add package AntDesign.Charts
在wwwroot/index.html(WebAssembly) 或Pages/_Host.razor(Server) 中引入靜態(tài)文件:
<script src="https://unpkg.com/@antv/g2plot@latest/dist/g2plot.js"></script>
<script src="_content/AntDesign.Charts/ant-design-charts-blazor.js"></script>在_Imports.razor中加入命名空間
@using AntDesign.Charts
最后就可以在.razor組件中引用啦!
<Line Data="data" Config="config" />
@code{
object[] data = new object[] {
new { year= "1991", value= 3 },
new { year= "1992", value= 4 },
new { year= "1993", value= 3.5 },
new { year= "1994", value= 5 },
new { year= "1995", value= 4.9 },
new { year= "1996", value= 6 },
new { year= "1997", value= 7 },
new { year= "1998", value= 9 },
new { year= "1999", value= 13 },
};
LineConfig config = new LineConfig()
{
title = new Title()
{
visible = true,
text = "曲線折線圖",
},
description = new Description()
{
visible = true,
text = "用平滑的曲線代替折線。",
},
padding = "auto",
forceFit = true,
xField = "year",
yField = "value",
smooth = true,
};
}
組件的使用相對(duì)于原先的G2Plot并沒(méi)有太多變化,主要針對(duì)C#語(yǔ)法的特點(diǎn)增加了強(qiáng)類型支持,屬性命名規(guī)則符合C#語(yǔ)法習(xí)慣等。
所以這篇文章不想多聊如何使用的問(wèn)題,我想談?wù)勗趯?duì)G2Plot封裝的過(guò)程中遇到的一些困難和實(shí)現(xiàn)方式,希望能為Blazor社區(qū)做出一些綿薄的貢獻(xiàn),如大佬看了有更好的實(shí)現(xiàn)方式希望告知在下。
G2Plot是通過(guò)傳入一個(gè)Config對(duì)象來(lái)配置圖表的呈現(xiàn)內(nèi)容,而且只需要給出必要的參數(shù)即可,這一切設(shè)計(jì)的都非常合理。
但是用C#實(shí)現(xiàn)的時(shí)候就遇上了問(wèn)題,當(dāng)Config對(duì)象通過(guò)InvokeVoidAsync傳到JS后,對(duì)象會(huì)包含所有屬性,這對(duì)于G2Plot來(lái)說(shuō)就畫(huà)蛇添足了,有些默認(rèn)屬性會(huì)被帶進(jìn)來(lái)的空屬性給覆蓋了,圖表顯示就出現(xiàn)了問(wèn)題。
當(dāng)然最簡(jiǎn)單的就是把值為Null的屬性從Config剔除,嘿嘿,我就是這么干的。通過(guò)一個(gè)遞歸遍歷對(duì)象中的所有屬性,移除沒(méi)有值的屬性。
function isEmptyObj(o) {
for (let attr in o) return !1;
return !0
}
function processArray(arr) {
for (let i = arr.length - 1; i >= 0; i--) {
if (arr[i] === null || arr[i] === undefined) arr.splice(i, 1);
else if (typeof arr[i] == 'object') removeNullItem(arr[i], arr, i);
}
return arr.length == 0
}
function proccessObject(o) {
for (let attr in o) {
if (o[attr] === null || o[attr] === undefined) delete o[attr];
else if (typeof o[attr] == 'object') {
removeNullItem(o[attr]);
if (isEmptyObj(o[attr])) delete o[attr];
}
}
}
//清除沒(méi)有值的項(xiàng)
function removeNullItem(o, arr, i) {
let s = ({}).toString.call(o);
if (s == '[object Array]') {
if (processArray(o) === true) {
if (arr) arr.splice(i, 1);
}
} else if (s == '[object Object]') {
proccessObject(o);
if (arr && isEmptyObj(o)) arr.splice(i, 1);
}
}
一個(gè)問(wèn)題解決了,有一個(gè)問(wèn)題來(lái)了,JS/TS是弱類型語(yǔ)言,他對(duì)象中的屬性可以在實(shí)例化時(shí)任意添加,C#可不行,他被定義約束的死死的,這就遇到下面兩個(gè)問(wèn)題:
有些配置屬性不可能窮舉所有的屬性定義。
而且作為組件的封裝者不可能無(wú)時(shí)差的跟進(jìn)G2Plot對(duì)Config定義的變化。
針對(duì)這兩個(gè)問(wèn)題,我們需要C#中有一個(gè)類似的弱類型的對(duì)象,這時(shí)候我看上了object,它可以定義成任何類型,如果用它做Config參數(shù),可謂是一勞永逸,豈不美哉。
理想是美好的,現(xiàn)實(shí)是殘酷的。如果用object,那么C#的強(qiáng)類型就徹底喪失,編寫(xiě)圖表配置時(shí)完全沒(méi)有提示,基本就是盲寫(xiě),太恐怖了,C#的優(yōu)雅蕩然無(wú)存。
這時(shí)突然腦子冒出個(gè)念頭,為啥不能使用兩個(gè)配置,一個(gè)是強(qiáng)類型的,一個(gè)是object,然后將他們合并成最終的配置給到G2Plot,完美。
基本原理就是通過(guò)一個(gè)遞歸將傳入JS的配置對(duì)象挨個(gè)對(duì)比,并將它們合并,JS實(shí)現(xiàn)代碼如下
function deepObjectMerge(source, target) {
for (var key in target) {
if (source[key] && source[key].toString() === "[object Object]") {
deepObjectMerge(source[key], target[key])
} else {
source[key] = target[key]
}
}
return source;
}
Blazor中使用方法如下(部分代碼)
<Tabs>
<TabPane Key="1">
<Tab>示例1</Tab>
<ChildContent>
<Line Data=data1 Config="config1" OtherConfig="otherConfig1" />
</ChildContent>
</TabPane>
</Tabs>
@code{
LineConfig config1 = new LineConfig()
{
XField = "date",
YField = "value",
};
object otherConfig1 = new
{
= new object[]
{
new{
Visible = true,
data =new object []{new { date = "2019-05-01", value = 4.9 },new { date = "2019-10-01" } },
Label = new
{
Visible = true,
Field = "festival",
},
},
},
};
}
通過(guò)Config生成的圖表是靜態(tài)的,沒(méi)有生命的死物,我們需要通過(guò)調(diào)用它的一些函數(shù)給予他生命,比如更新配置,更新數(shù)據(jù),設(shè)置高亮等等。
那么問(wèn)題就來(lái)了,IJSRuntime提供的InvokeAsync方法只能返回可以序列化成json的對(duì)象,通過(guò)new G2Plot得到的對(duì)象不屬于此列,我們?nèi)绾卧贑#代碼中得到G2Plot對(duì)象就是個(gè)難題了。
好在Blazor提供了一個(gè)ElementReference對(duì)象給我們,它只能作為Html對(duì)象的引用,沒(méi)法作為JS對(duì)象引用,有點(diǎn)可惜,不過(guò)它給我們分配了唯一的Id,既然如此,我們就曲線救國(guó)。
第一步,得到div的ElementReference
<div @ref="Ref"></div>
@code{
protected ElementReference Ref;
}第二步,構(gòu)造的G2Plot對(duì)象,并放到一個(gè)叫“chartsContainer”的JS對(duì)象中,以Ref.Id作為索引
const plot = new G2Plot[type](domRef, config);
plot.render();
window.AntDesignCharts.chartsContainer[domId] = plot;
第三步,如果需要調(diào)用G2Plot對(duì)象的方法,那么直接拿著Ref.Id去“chartsContainer”中找到對(duì)象后調(diào)用,下面是“changeData”方法的實(shí)現(xiàn)
changeData(domId, data, all) {
if (window.AntDesignCharts.chartsContainer[domId] == undefined) return;
window.AntDesignCharts.chartsContainer[domId].changeData(data, all);
},
第四步,組件銷毀時(shí)及時(shí)清理“chartsContainer”中不用的對(duì)象
public async void Dispose()
await JS.InvokeVoidAsync(InteropDestroy, Ref.Id);
}
到目前已經(jīng)完成絕大部分功能,還有一些功能需要進(jìn)一步技術(shù)攻關(guān)。
上述就是小編為大家分享的如何用Blazor技術(shù)封裝G2Plot實(shí)現(xiàn)Charts組件了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
文章名稱:如何用Blazor技術(shù)封裝G2Plot實(shí)現(xiàn)Charts組件
標(biāo)題路徑:http://chinadenli.net/article12/ppdhdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、App設(shè)計(jì)、云服務(wù)器、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)