mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-12-05 21:50:05 +08:00
!3647 feat(#I66VTQ): add AspectRatio/Height parameter on Chart component
* Merge branch 'main' into feat_I66VTQ * Update BootstrapBlazor.Chart.csproj * feat(#I66VTQ): add AspectRatio/Height parameter on Chart component
This commit is contained in:
parent
71a0e845fa
commit
3cecfd4801
@ -3,7 +3,7 @@
|
||||
<Import Project="..\..\..\bundleconfig.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>7.0.0</Version>
|
||||
<Version>7.0.1</Version>
|
||||
<PackageTags>Bootstrap Blazor WebAssembly wasm UI Components Chart</PackageTags>
|
||||
<Description>Bootstrap UI components extensions of Chart.js</Description>
|
||||
</PropertyGroup>
|
||||
|
@ -32,15 +32,77 @@ public partial class Chart : BootstrapComponentBase, IDisposable
|
||||
/// 获得/设置 组件 Style 字符串
|
||||
/// </summary>
|
||||
private string? StyleString => CssBuilder.Default()
|
||||
.AddClass($"height: {Height};", !string.IsNullOrEmpty(Height))
|
||||
.AddClass($"width: {Width};", !string.IsNullOrEmpty(Width))
|
||||
.Build();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件宽度支持单位
|
||||
/// 获得/设置 图表标题
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件高度支持单位<para>如: 30% , 30px , 30em , calc(30%)</para>
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件宽度支持单位<para>如: 30% , 30px , 30em , calc(30%)</para>
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表所在canvas是否随其容器大小变化而变化 默认为 true
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool Responsive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 获取/设置 是否 约束图表比例 默认为 true
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool MaintainAspectRatio { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 设置canvas的宽高比(值为1表示canvas是正方形),如果显示定义了canvas的高度,则此属性无效 默认为 2
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int AspectRatio { get; set; } = 2;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表尺寸延迟变化时间 默认为 0
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int ResizeDelay { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 Bubble 模式下显示角度 180 为 半圆 360 为正圆
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Angle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 正在加载文本
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? LoadingText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表组件渲染类型 默认为 line 图
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ChartType ChartType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表组件组件方法 默认为 Update
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ChartAction ChartAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 组件数据初始化委托方法
|
||||
/// </summary>
|
||||
@ -59,31 +121,6 @@ public partial class Chart : BootstrapComponentBase, IDisposable
|
||||
[Parameter]
|
||||
public Func<ChartAction, Task>? OnAfterUpdateAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 Bubble 模式下显示角度 180 为 半圆 360 为正圆
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int Angle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表组件渲染类型 默认为 line 图
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ChartType ChartType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表组件渲染类型 默认为 Update
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public ChartAction ChartAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 正在加载文本
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
[NotNull]
|
||||
public string? LoadingText { get; set; }
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IStringLocalizer<Chart>? Localizer { get; set; }
|
||||
@ -117,6 +154,16 @@ public partial class Chart : BootstrapComponentBase, IDisposable
|
||||
|
||||
Interop ??= new JSInterop<Chart>(JSRuntime);
|
||||
var ds = await OnInitAsync.Invoke();
|
||||
ds.Options.Title = ds.Options.Title ?? Title;
|
||||
ds.Options.Responsive = ds.Options.Responsive ?? Responsive;
|
||||
ds.Options.MaintainAspectRatio = ds.Options.MaintainAspectRatio ?? MaintainAspectRatio;
|
||||
ds.Options.AspectRatio = ds.Options.AspectRatio ?? AspectRatio;
|
||||
ds.Options.ResizeDelay = ds.Options.ResizeDelay ?? ResizeDelay;
|
||||
if (Height != null && Width != null)
|
||||
{
|
||||
//设置了高度和宽度,会自动禁用约束图表比例,图表充满容器
|
||||
ds.Options.MaintainAspectRatio = false;
|
||||
}
|
||||
await Interop.InvokeVoidAsync(this, ChartElement, "bb_chart", nameof(Completed), ds, "", ChartType.ToDescriptionString(), Angle);
|
||||
}
|
||||
}
|
||||
@ -147,6 +194,24 @@ public partial class Chart : BootstrapComponentBase, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重新加载方法, 强制重新渲染图表
|
||||
/// </summary>
|
||||
public async Task Reload()
|
||||
{
|
||||
if (OnInitAsync != null)
|
||||
{
|
||||
var ds = await OnInitAsync();
|
||||
await Interop.InvokeVoidAsync(this, ChartElement, "bb_chart", nameof(Completed), ds, ChartAction.Reload.ToDescriptionString(), ChartType.ToDescriptionString(), Angle);
|
||||
|
||||
if (OnAfterUpdateAsync != null)
|
||||
{
|
||||
await OnAfterUpdateAsync(ChartAction.Reload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Dispose
|
||||
/// <summary>
|
||||
/// Dispose 方法
|
||||
|
@ -16,29 +16,40 @@ public enum ChartAction
|
||||
/// </summary>
|
||||
[Description("update")]
|
||||
Update,
|
||||
|
||||
/// <summary>
|
||||
/// 增加数据集
|
||||
/// </summary>
|
||||
[Description("addDataset")]
|
||||
AddDataset,
|
||||
|
||||
/// <summary>
|
||||
/// 减少数据集
|
||||
/// </summary>
|
||||
[Description("removeDataset")]
|
||||
RemoveDataset,
|
||||
|
||||
/// <summary>
|
||||
/// 增加数据
|
||||
/// </summary>
|
||||
[Description("addData")]
|
||||
AddData,
|
||||
|
||||
/// <summary>
|
||||
/// 减少数据
|
||||
/// </summary>
|
||||
[Description("removeData")]
|
||||
RemoveData,
|
||||
|
||||
/// <summary>
|
||||
/// 全圆/半圆
|
||||
/// </summary>
|
||||
[Description("setAngle")]
|
||||
SetAngle
|
||||
SetAngle,
|
||||
|
||||
/// <summary>
|
||||
/// 重新渲染图表
|
||||
/// </summary>
|
||||
[Description("reload")]
|
||||
Reload,
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace BootstrapBlazor.Components;
|
||||
|
||||
/// <summary>
|
||||
@ -10,7 +12,7 @@ namespace BootstrapBlazor.Components;
|
||||
public class ChartOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 表格 Title
|
||||
/// 获得/设置 图表 Title
|
||||
/// </summary>
|
||||
public string? Title { get; set; }
|
||||
|
||||
@ -26,14 +28,34 @@ public class ChartOptions
|
||||
public ChartAxes Y { get; } = new ChartAxes();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否 适配移动端 默认为 true
|
||||
/// 获得/设置 图表所在canvas是否随其容器大小变化而变化 默认为 true
|
||||
/// </summary>
|
||||
public bool Responsive { get; set; } = true;
|
||||
public bool? Responsive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取/设置 是否 约束图表比例 默认为 true
|
||||
/// </summary>
|
||||
public bool MaintainAspectRatio { get; set; } = true;
|
||||
public bool? MaintainAspectRatio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 设置canvas的宽高比(值为1表示canvas是正方形),如果显示定义了canvas的高度,则此属性无效 默认为 2
|
||||
/// </summary>
|
||||
public int? AspectRatio { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表尺寸延迟变化时间 默认为 0
|
||||
/// </summary>
|
||||
public int? ResizeDelay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表canvas高度 默认为空,跟随容器高度<para>如: 300px</para>
|
||||
/// </summary>
|
||||
public string? Height { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 图表canvas宽度 默认为空,跟随容器高度<para>如: 300px</para>
|
||||
/// </summary>
|
||||
public string? Width { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 数据显示颜色
|
||||
|
@ -17,6 +17,8 @@
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
aspectRatio: 2,
|
||||
resizeDelay: 0,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
@ -171,6 +173,8 @@
|
||||
options: {
|
||||
responsive: option.options.responsive,
|
||||
maintainAspectRatio: option.options.maintainAspectRatio,
|
||||
aspectRatio: option.options.aspectRatio,
|
||||
resizeDelay: option.options.resizeDelay,
|
||||
plugins: {
|
||||
title: {
|
||||
display: option.options.title != null,
|
||||
@ -193,6 +197,7 @@
|
||||
stacked: option.options.x.stacked
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -236,6 +241,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option.updateMethod === "reload") {
|
||||
config.data = option.data;
|
||||
}
|
||||
else {
|
||||
config.data.datasets.forEach((dataset, index) => {
|
||||
dataset.data = option.data.datasets[index].data;
|
||||
@ -249,6 +257,12 @@
|
||||
if (!chart) {
|
||||
var op = $.getChartOption(option);
|
||||
$el.data('chart', chart = new Chart(el.getElementsByTagName('canvas'), op));
|
||||
if (option.options.height !== null) {
|
||||
chart.canvas.parentNode.style.height = option.options.height;
|
||||
}
|
||||
if (option.options.width !== null) {
|
||||
chart.canvas.parentNode.style.width = option.options.width;
|
||||
}
|
||||
$el.removeClass('is-loading').trigger('chart.afterInit');
|
||||
obj.invokeMethodAsync(method);
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
aspectRatio: 2,
|
||||
resizeDelay: 0,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
@ -157,6 +159,8 @@
|
||||
options: {
|
||||
responsive: option.options.responsive,
|
||||
maintainAspectRatio: option.options.maintainAspectRatio,
|
||||
aspectRatio: option.options.aspectRatio,
|
||||
resizeDelay: option.options.resizeDelay,
|
||||
plugins: {
|
||||
title: {
|
||||
display: option.options.title != null,
|
||||
@ -179,6 +183,7 @@
|
||||
stacked: option.options.x.stacked
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -222,6 +227,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option.updateMethod === "reload") {
|
||||
config.data = option.data;
|
||||
}
|
||||
else {
|
||||
config.data.datasets.forEach((dataset, index) => {
|
||||
dataset.data = option.data.datasets[index].data;
|
||||
@ -235,6 +243,12 @@
|
||||
if (!chart) {
|
||||
var op = $.getChartOption(option);
|
||||
$el.data('chart', chart = new Chart(el.getElementsByTagName('canvas'), op));
|
||||
if (option.options.height !== null) {
|
||||
chart.canvas.parentNode.style.height = option.options.height;
|
||||
}
|
||||
if (option.options.width !== null) {
|
||||
chart.canvas.parentNode.style.width = option.options.width;
|
||||
}
|
||||
$el.removeClass('is-loading').trigger('chart.afterInit');
|
||||
obj.invokeMethodAsync(method);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
(function(n){window.chartOption={options:{responsive:!0,maintainAspectRatio:!0,plugins:{title:{display:!0,text:null}},tooltips:{mode:"index",intersect:!1},hover:{mode:"nearest",intersect:!0},scales:{x:{display:!0,title:{display:!1,text:null}},y:{display:!0,title:{display:!1,text:null}}}}};var t=(n,t)=>n.p0.skip||n.p1.skip?t:undefined,r=(n,t)=>n.p0.parsed.y>n.p1.parsed.y?t:undefined,i={fill:!1,interaction:{intersect:!1},radius:0};n.extend({getChartOption:function(r){var e=[],o,u,f;window.chartColors=r.options.colors;for(o in r.options.colors)e.push(o);return u={},f=null,r.type==="line"?(n.isArray(r.data)&&(n.each(r.data,function(i,u){n.each(u.data,function(n,u){u===null&&(r.data[i].data[n]=NaN,r.data[i].segment={borderColor:n=>t(n,"rgb(0,0,0,0.2)"),borderDash:n=>t(n,[6,6])})})}),r.options=n.extend(!0,r.options,i)),u=n.extend(!0,{},chartOption),f=function(t){var i=chartColors[e.shift()];n.extend(t,{backgroundColor:i,borderColor:i})}):r.type==="bar"?(u=n.extend(!0,{},chartOption),f=function(t){var i=chartColors[e.shift()];n.extend(t,{backgroundColor:Chart.helpers.color(i).alpha(.5).rgbString(),borderColor:i,borderWidth:1})}):r.type==="pie"||r.type==="doughnut"?(u=n.extend(!0,{},chartOption,{options:{scales:{x:{display:!1},y:{display:!1}}}}),f=function(t){n.extend(t,{backgroundColor:e.slice(0,t.data.length).map(function(n){return chartColors[n]})})},r.type==="doughnut"&&n.extend(u.options,{cutoutPercentage:50,animation:{animateScale:!0,animateRotate:!0}})):r.type==="bubble"&&(u=n.extend(!0,{},chartOption,{data:{animation:{duration:1e4}},options:{tooltips:{mode:"point"}}}),f=function(t){var i=chartColors[e.shift()];n.extend(t,{backgroundColor:Chart.helpers.color(i).alpha(.5).rgbString(),borderWidth:1,borderColor:i})}),n.each(r.data,function(){f(this)}),n.extend(!0,u,{type:r.type,data:{labels:r.labels,datasets:r.data},options:{responsive:r.options.responsive,maintainAspectRatio:r.options.maintainAspectRatio,plugins:{title:{display:r.options.title!=null,text:r.options.title}},scales:{x:{title:{display:r.options.x.title!=null,text:r.options.x.title},stacked:r.options.x.stacked},y:{title:{display:r.options.y.title!=null,text:r.options.y.title},stacked:r.options.x.stacked}}}})},updateChart:function(n,t){t.updateMethod==="addDataset"?n.data.datasets.push(t.data.datasets.pop()):t.updateMethod==="removeDataset"?n.data.datasets.pop():t.updateMethod==="addData"?n.data.datasets.length>0&&(n.data.labels.push(t.data.labels.pop()),n.data.datasets.forEach(function(n,i){n.data.push(t.data.datasets[i].data.pop());(t.type==="pie"||t.type==="doughnut")&&n.backgroundColor.push(t.data.datasets[i].backgroundColor.pop())})):t.updateMethod==="removeData"?(n.data.labels.pop(),n.data.datasets.forEach(function(n){n.data.pop();(t.type==="pie"||t.type==="doughnut")&&n.backgroundColor.pop()})):t.updateMethod==="setAngle"?t.type==="doughnut"&&(t.angle===360?(n.options.circumference=360,n.options.rotation=-360):(n.options.circumference=180,n.options.rotation=-90)):n.data.datasets.forEach((n,i)=>{n.data=t.data.datasets[i].data})},bb_chart:function(t,i,r,u,f,e,o){var c=n(t),h,s;u.type=e;h=c.data("chart");h?(s=n.getChartOption(u),s.angle=o,s.updateMethod=f,n.updateChart(h.config,s),h.update()):(s=n.getChartOption(u),c.data("chart",h=new Chart(t.getElementsByTagName("canvas"),s)),c.removeClass("is-loading").trigger("chart.afterInit"),i.invokeMethodAsync(r))}})})(jQuery);
|
||||
(function(n){window.chartOption={options:{responsive:!0,maintainAspectRatio:!0,aspectRatio:2,resizeDelay:0,plugins:{title:{display:!0,text:null}},tooltips:{mode:"index",intersect:!1},hover:{mode:"nearest",intersect:!0},scales:{x:{display:!0,title:{display:!1,text:null}},y:{display:!0,title:{display:!1,text:null}}}}};var t=(n,t)=>n.p0.skip||n.p1.skip?t:undefined,r=(n,t)=>n.p0.parsed.y>n.p1.parsed.y?t:undefined,i={fill:!1,interaction:{intersect:!1},radius:0};n.extend({getChartOption:function(r){var e=[],o,u,f;window.chartColors=r.options.colors;for(o in r.options.colors)e.push(o);return u={},f=null,r.type==="line"?(n.isArray(r.data)&&(n.each(r.data,function(i,u){n.each(u.data,function(n,u){u===null&&(r.data[i].data[n]=NaN,r.data[i].segment={borderColor:n=>t(n,"rgb(0,0,0,0.2)"),borderDash:n=>t(n,[6,6])})})}),r.options=n.extend(!0,r.options,i)),u=n.extend(!0,{},chartOption),f=function(t){var i=chartColors[e.shift()];n.extend(t,{backgroundColor:i,borderColor:i})}):r.type==="bar"?(u=n.extend(!0,{},chartOption),f=function(t){var i=chartColors[e.shift()];n.extend(t,{backgroundColor:Chart.helpers.color(i).alpha(.5).rgbString(),borderColor:i,borderWidth:1})}):r.type==="pie"||r.type==="doughnut"?(u=n.extend(!0,{},chartOption,{options:{scales:{x:{display:!1},y:{display:!1}}}}),f=function(t){n.extend(t,{backgroundColor:e.slice(0,t.data.length).map(function(n){return chartColors[n]})})},r.type==="doughnut"&&n.extend(u.options,{cutoutPercentage:50,animation:{animateScale:!0,animateRotate:!0}})):r.type==="bubble"&&(u=n.extend(!0,{},chartOption,{data:{animation:{duration:1e4}},options:{tooltips:{mode:"point"}}}),f=function(t){var i=chartColors[e.shift()];n.extend(t,{backgroundColor:Chart.helpers.color(i).alpha(.5).rgbString(),borderWidth:1,borderColor:i})}),n.each(r.data,function(){f(this)}),n.extend(!0,u,{type:r.type,data:{labels:r.labels,datasets:r.data},options:{responsive:r.options.responsive,maintainAspectRatio:r.options.maintainAspectRatio,aspectRatio:r.options.aspectRatio,resizeDelay:r.options.resizeDelay,plugins:{title:{display:r.options.title!=null,text:r.options.title}},scales:{x:{title:{display:r.options.x.title!=null,text:r.options.x.title},stacked:r.options.x.stacked},y:{title:{display:r.options.y.title!=null,text:r.options.y.title},stacked:r.options.x.stacked}}}})},updateChart:function(n,t){t.updateMethod==="addDataset"?n.data.datasets.push(t.data.datasets.pop()):t.updateMethod==="removeDataset"?n.data.datasets.pop():t.updateMethod==="addData"?n.data.datasets.length>0&&(n.data.labels.push(t.data.labels.pop()),n.data.datasets.forEach(function(n,i){n.data.push(t.data.datasets[i].data.pop());(t.type==="pie"||t.type==="doughnut")&&n.backgroundColor.push(t.data.datasets[i].backgroundColor.pop())})):t.updateMethod==="removeData"?(n.data.labels.pop(),n.data.datasets.forEach(function(n){n.data.pop();(t.type==="pie"||t.type==="doughnut")&&n.backgroundColor.pop()})):t.updateMethod==="setAngle"?t.type==="doughnut"&&(t.angle===360?(n.options.circumference=360,n.options.rotation=-360):(n.options.circumference=180,n.options.rotation=-90)):t.updateMethod==="reload"?n.data=t.data:n.data.datasets.forEach((n,i)=>{n.data=t.data.datasets[i].data})},bb_chart:function(t,i,r,u,f,e,o){var c=n(t),s,h;u.type=e;s=c.data("chart");s?(h=n.getChartOption(u),h.angle=o,h.updateMethod=f,n.updateChart(s.config,h),s.update()):(h=n.getChartOption(u),c.data("chart",s=new Chart(t.getElementsByTagName("canvas"),h)),u.options.height!==null&&(s.canvas.parentNode.style.height=u.options.height),u.options.width!==null&&(s.canvas.parentNode.style.width=u.options.width),c.removeClass("is-loading").trigger("chart.afterInit"),i.invokeMethodAsync(r))}})})(jQuery);
|
Loading…
Reference in New Issue
Block a user