mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-12-02 03:59:14 +08:00
feat(Chart): add AppendData parameter (#4047)
* chore: bump version 8.1.7 * chore: 更新依赖 * Feat(Chart): use custom ChartDataSource (#4041) Co-authored-by: Argo Zhang <argo@live.ca> * chore: bump version 8.1.8 * refactor: 重构代码 * feat: 增加 AppendData 扩展数据 * feat: 增加 AppendData 参数 * refactor: 增加 deepMerge 方法 * doc: 增加 AppendData 示例 * chore: 更新项目依赖 * refactor: 更新命名空间 --------- Co-authored-by: AiZhen <53560110+AiYuZhen@users.noreply.github.com>
This commit is contained in:
parent
4792fe6ebc
commit
f85b22791c
@ -35,6 +35,7 @@
|
||||
<PackageReference Include="BootstrapBlazor.Bluetooth" Version="8.0.2" />
|
||||
<PackageReference Include="BootstrapBlazor.BootstrapIcon" Version="8.0.3" />
|
||||
<PackageReference Include="BootstrapBlazor.BootstrapIcon.Extensions" Version="8.0.6" />
|
||||
<PackageReference Include="BootstrapBlazor.Chart" Version="8.1.8" />
|
||||
<PackageReference Include="BootstrapBlazor.CherryMarkdown" Version="8.0.0" />
|
||||
<PackageReference Include="BootstrapBlazor.CodeEditor" Version="8.0.2" />
|
||||
<PackageReference Include="BootstrapBlazor.Dock" Version="8.1.7" />
|
||||
|
@ -63,14 +63,8 @@
|
||||
<Pre ShowToolbar="true">@_code</Pre>
|
||||
</DemoBlock>
|
||||
|
||||
<DemoBlock Title="添加未封装属性"
|
||||
Introduction="通过继承<code>ChartDataset</code>类型,添加未封装的属性"
|
||||
Name="BarAddProperty">
|
||||
<Row ItemsPerRow="ItemsPerRow.Six" RowType="RowType.Inline">
|
||||
<BootstrapInputGroup>
|
||||
<BootstrapInputGroupLabel DisplayText="是否通过继承添加属性"/>
|
||||
<Switch @bind-Value=IsChartDataset2 OnValueChanged="@(v=>BarAdd!.Reload())" ShowLabel="false" />
|
||||
</BootstrapInputGroup>
|
||||
</Row>
|
||||
<Chart @ref=BarAdd ChartType="ChartType.Line" OnInitAsync="() => OnInitAddProperty(true)" Title="BarColorSeparately Demo" Height="500px" Width="500px" />
|
||||
<DemoBlock Title="@Localizer["AppendDataTitle"]"
|
||||
Introduction="@Localizer["AppendDataIntro"]"
|
||||
Name="AppendData">
|
||||
<Chart OnInitAsync="GetData" AppendData="GetAppendData()" />
|
||||
</DemoBlock>
|
||||
|
@ -295,6 +295,38 @@ public partial class Line : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private Task<ChartDataSource> GetData()
|
||||
{
|
||||
var BarDataCount = 6;
|
||||
var BarDatasetCount = 3;
|
||||
var Randomer = new Random();
|
||||
var ds = new ChartDataSource();
|
||||
ds.Options.Title = "Bar Histogram";
|
||||
ds.Options.X.Title = "Days";
|
||||
ds.Options.Y.Title = "Numerical value";
|
||||
ds.Labels = Enumerable.Range(1, BarDataCount).Select(i => i.ToString());
|
||||
for (var index = 0; index < BarDatasetCount; index++)
|
||||
{
|
||||
ds.Data.Add(new ChartDataset()
|
||||
{
|
||||
Label = $"Set {index}",
|
||||
Data = Enumerable.Range(1, BarDataCount).Select(i => Randomer.Next(20, 37)).Cast<object>()
|
||||
});
|
||||
}
|
||||
return Task.FromResult(ds);
|
||||
}
|
||||
|
||||
private static object GetAppendData()
|
||||
{
|
||||
var steps = new List<object>();
|
||||
for (var index = 0; index < 3; index++)
|
||||
{
|
||||
// 添加 ChartDataset 未提供的 Stepped 参数
|
||||
steps.Add(new { Stepped = true });
|
||||
}
|
||||
return new { Data = steps };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
|
@ -560,7 +560,9 @@
|
||||
"LineBarAspectRatioTitle": "Chart ratio",
|
||||
"LineBarAspectRatioIntro": "Setting the height and width will automatically disable the constraint chart ratio, and the chart will fill the container",
|
||||
"LineChartJSTitle": "Generate Chart through JS",
|
||||
"LineChartJSIntro": "Due to the underlying reference of<code>BootstrapBlazor.Chart</code>to<code>Chart.JS</code>, we can call and generate charts through JS."
|
||||
"LineChartJSIntro": "Due to the underlying reference of<code>BootstrapBlazor.Chart</code>to<code>Chart.JS</code>, we can call and generate charts through JS.",
|
||||
"AppendDataTitle": "Append Data",
|
||||
"AppendDataIntro": "Since <code>ChartDataSource</code> does not fully encapsulate all parameters in <code>Chart.JS</code>, when we need to set some unprovided parameters, we can use <code>AppendData</code> to complete it."
|
||||
},
|
||||
"BootstrapBlazor.Server.Components.Samples.Charts.Bar": {
|
||||
"BarTypeTitle": "Bar graph",
|
||||
|
@ -560,7 +560,9 @@
|
||||
"LineBarAspectRatioTitle": "图表比例",
|
||||
"LineBarAspectRatioIntro": "设置了高度和宽度,会自动禁用约束图表比例, 图表充满容器",
|
||||
"LineChartJSTitle": "通过JS生成Chart",
|
||||
"LineChartJSIntro": "由于 <code>BootstrapBlazor.Chart</code> 底层引用了 <code>Chart.JS</code> 所以我们可以通过JS方式来调用并生成图表。"
|
||||
"LineChartJSIntro": "由于 <code>BootstrapBlazor.Chart</code> 底层引用了 <code>Chart.JS</code> 所以我们可以通过JS方式来调用并生成图表。",
|
||||
"AppendDataTitle": "数据参数扩展",
|
||||
"AppendDataIntro": "由于 <code>ChartDataSource</code> 没有完全封装 <code>Chart.JS</code> 中所有参数,当我们需要设置一些未提供的参数时,可以通过 <code>AppendData</code> 来完成"
|
||||
},
|
||||
"BootstrapBlazor.Server.Components.Samples.Charts.Bar": {
|
||||
"BarTypeTitle": "Bar 图",
|
||||
|
@ -775,6 +775,20 @@ export function switchTheme(theme, x = 0, y = 0, sync = true) {
|
||||
}
|
||||
}
|
||||
|
||||
const deepMerge = (obj1, obj2) => {
|
||||
for (let key in obj2) {
|
||||
if (obj2.hasOwnProperty(key)) {
|
||||
if (obj2[key] instanceof Object && obj1[key] instanceof Object) {
|
||||
obj1[key] = deepMerge(obj1[key], obj2[key]);
|
||||
}
|
||||
else {
|
||||
obj1[key] = obj2[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj1;
|
||||
}
|
||||
|
||||
export {
|
||||
autoAdd,
|
||||
autoRemove,
|
||||
@ -785,10 +799,11 @@ export {
|
||||
addLink,
|
||||
addScript,
|
||||
copy,
|
||||
getTextFromClipboard,
|
||||
getAllClipboardContents,
|
||||
deepMerge,
|
||||
debounce,
|
||||
drag,
|
||||
getTextFromClipboard,
|
||||
getAllClipboardContents,
|
||||
insertBefore,
|
||||
insertAfter,
|
||||
isDisabled,
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>8.1.6</Version>
|
||||
<Version>8.1.8</Version>
|
||||
<PackageTags>Bootstrap Blazor WebAssembly wasm UI Components Chart</PackageTags>
|
||||
<Description>Bootstrap UI components extensions of Chart.js</Description>
|
||||
</PropertyGroup>
|
||||
|
@ -101,13 +101,16 @@ public partial class Chart
|
||||
[Parameter]
|
||||
public bool IsAnimation { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 扩展数据 默认为空 序列化到浏览器与数据集合 <see cref="ChartDataSource "/> 合并,方便把组件未提供的参数传递到浏览器
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public object? AppendData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件数据初始化委托方法
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
#if NET6_0_OR_GREATER
|
||||
[EditorRequired]
|
||||
#endif
|
||||
public Func<Task<ChartDataSource>>? OnInitAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@ -154,21 +157,25 @@ public partial class Chart
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
if (OnInitAsync == null)
|
||||
if (OnInitAsync == null && AppendData == null)
|
||||
{
|
||||
throw new InvalidOperationException("OnInit parameter must be set");
|
||||
throw new InvalidOperationException($"{nameof(OnInitAsync)} parameter or {nameof(AppendData)} must one be set. {nameof(OnInitAsync)} 回调方法或者 {nameof(AppendData)} 参数必须设置一个");
|
||||
}
|
||||
|
||||
var ds = await OnInitAsync();
|
||||
UpdateOptions(ds);
|
||||
|
||||
if (Height != null && Width != null)
|
||||
ChartDataSource? ds = null;
|
||||
if (OnInitAsync != null)
|
||||
{
|
||||
//设置了高度和宽度,会自动禁用约束图表比例,图表充满容器
|
||||
ds.Options.MaintainAspectRatio = false;
|
||||
ds = await OnInitAsync();
|
||||
UpdateOptions(ds);
|
||||
|
||||
if (Height != null && Width != null)
|
||||
{
|
||||
//设置了高度和宽度,会自动禁用约束图表比例,图表充满容器
|
||||
ds.Options.MaintainAspectRatio = false;
|
||||
}
|
||||
}
|
||||
|
||||
await InvokeVoidAsync("init", Id, Interop, nameof(Completed), ds);
|
||||
await InvokeVoidAsync("init", Id, Interop, nameof(Completed), ds, AppendData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,9 +183,12 @@ public partial class Chart
|
||||
/// 图表绘制完成后回调此方法
|
||||
/// </summary>
|
||||
[JSInvokable]
|
||||
public void Completed()
|
||||
public async Task Completed()
|
||||
{
|
||||
OnAfterInitAsync?.Invoke();
|
||||
if (OnAfterInitAsync != null)
|
||||
{
|
||||
await OnAfterInitAsync();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,7 +70,23 @@ const genericOptions = {
|
||||
radius: 0
|
||||
}
|
||||
|
||||
const getChartOption = function (option) {
|
||||
const deepMerge = (obj1, obj2) => {
|
||||
for (let key in obj2) {
|
||||
if (obj2.hasOwnProperty(key)) {
|
||||
if (obj2[key] instanceof Object && obj1[key] instanceof Object) {
|
||||
obj1[key] = deepMerge(obj1[key], obj2[key]);
|
||||
}
|
||||
else {
|
||||
obj1[key] = obj2[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj1;
|
||||
}
|
||||
|
||||
const getChartOption = function (option, appendData) {
|
||||
option = deepMerge(option, appendData);
|
||||
|
||||
const colors = []
|
||||
const chartColors = option.options.colors
|
||||
for (const name in option.options.colors) colors.push(name)
|
||||
@ -409,8 +425,8 @@ const updateChart = function (config, option) {
|
||||
}
|
||||
}
|
||||
|
||||
export function init(id, invoke, method, option) {
|
||||
const op = getChartOption(option);
|
||||
export function init(id, invoke, method, option, appendData) {
|
||||
const op = getChartOption(option, appendData);
|
||||
op.options.onClick = (event, elements, chart) => {
|
||||
if (elements.length > 0) {
|
||||
if (option.options.onClickDataMethod) {
|
||||
|
Loading…
Reference in New Issue
Block a user