Blazor Working with Charts
Infragistics Blazor Excel Engine의 WorksheetChart
기능을 사용하면 워크시트의 셀 영역에 걸쳐 데이터 추세를 시각적 차트로 표현할 수 있습니다. 예를 들어, 셀 영역에 있는 Excel 데이터를 열, 선 또는 70개 이상의 다른 차트 유형으로 시각화하려는 경우 이 기능을 사용하면 이를 달성하는 데 도움이 될 수 있습니다.
Blazor WebAssembly および Blazor Server 向けに最適化された 60 以上の高性能チャートを使用 とグラフを使用して、生データを魅力的な視覚化に変換し、最高の UX を実現します。
Blazor Working with Charts Example
using System.Runtime.InteropServices.JavaScript;
namespace Infragistics.Samples
{
public partial class BlazorFastDownload
{
[JSImport("BlazorDownloadFileFast", "BlazorFastDownload")]
internal static partial void DownloadFile(string name, string contentType, byte[] content);
}
}
csusing System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using IgniteUI.Blazor.Controls;
namespace Infragistics.Samples
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// registering Ignite UI modules
builder.Services.AddIgniteUIBlazor(
typeof(IgbDataGridModule),
typeof(IgbCategoryChartModule)
);
await builder.Build().RunAsync();
}
}
}
cs
@using Microsoft.AspNetCore.Components
@using Microsoft.JSInterop
@using Microsoft.JSInterop.WebAssembly
@using Infragistics.Documents.Excel
@using IgniteUI.Blazor.Controls
@using System.Runtime.InteropServices.JavaScript
@implements IDisposable
<div class="container vertical">
<div class="options vertical">
<button @onclick="ExportData">Save to Excel</button>
</div>
<div class="container vertical">
<IgbCategoryChart Height="50%" Width="100%"
DataSource="@ChartData"
YAxisMinimumValue="0"
XAxisInterval="1"
ChartType="@CategoryChartType.Column"
Brushes="#4f81bd, #c0504d, #9bbb59, #8064a2"
Outlines="#4f81bd, #c0504d, #9bbb59, #8064a2"
Thickness="0" />
<IgbDataGrid Height="50%" Width="100%" DataSource="GridData">
<IgbTextColumn Field="Expense" Width="@("*>100")" />
<IgbNumericColumn Field="Jan" Width="@("*>75")" />
<IgbNumericColumn Field="Feb" Width="@("*>75")" />
<IgbNumericColumn Field="Mar" Width="@("*>75")" />
<IgbNumericColumn Field="Apr" Width="@("*>75")" />
<IgbNumericColumn Field="May" Width="@("*>75")" />
<IgbNumericColumn Field="Jun" Width="@("*>75")" />
<IgbNumericColumn Field="Jul" Width="@("*>75")" />
<IgbNumericColumn Field="Aug" Width="@("*>75")" />
<IgbNumericColumn Field="Sep" Width="@("*>75")" />
<IgbNumericColumn Field="Oct" Width="@("*>75")" />
<IgbNumericColumn Field="Nov" Width="@("*>75")" />
<IgbNumericColumn Field="Dec" Width="@("*>75")" />
</IgbDataGrid>
</div>
</div>
@code {
[Inject]
public IJSRuntime Runtime { get; set; }
public List<ExpenseGridInfo> GridData { get; set; }
public List<ExpenseChartInfo> ChartData { get; set; }
Random r = new Random();
protected override void OnInitialized()
{
Workbook.InProcessRuntime = (IJSInProcessRuntime)this.Runtime;
InitData();
}
public void InitData()
{
var months = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
var groups = new string[] { "Heating", "Electricity", "Water", "Taxes" };
var expenseKey = "Expense";
var monthKey = "Month";
List<ExpenseGridInfo> _gridData = new List<ExpenseGridInfo>();
List<ExpenseChartInfo> _chartData = new List<ExpenseChartInfo>();
for (int i = 0; i < groups.Length; i++)
{
string group = groups[i];
ExpenseGridInfo info = new ExpenseGridInfo() { Expense = group };
foreach(string month in months)
{
double x = i * 15 * Math.PI / 180;
double rand = r.Next(50, 100);
double heat = Math.Abs(Math.Cos(x)) * 300 + rand;
double ac = Math.Abs(Math.Sin(x)) * 500 + rand;
switch (group)
{
case "Heating": {
typeof(ExpenseGridInfo).GetProperty(month).SetValue(info, Math.Round(heat));
break;
}
case "Electricity":
{
typeof(ExpenseGridInfo).GetProperty(month).SetValue(info, Math.Round(ac));
break;
}
case "Water":
{
typeof(ExpenseGridInfo).GetProperty(month).SetValue(info, r.Next(100, 150));
break;
}
case "Taxes":
{
typeof(ExpenseGridInfo).GetProperty(month).SetValue(info, r.Next(700, 800));
break;
}
}
}
_gridData.Add(info);
}
foreach(string month in months)
{
ExpenseChartInfo data = new ExpenseChartInfo() { Month = month };
foreach(ExpenseGridInfo info in _gridData)
{
switch (info.Expense)
{
case "Heating":
{
data.Heat = (double)typeof(ExpenseGridInfo).GetProperty(month).GetValue(info);
break;
}
case "Electricity":
{
data.Electricity = (double)typeof(ExpenseGridInfo).GetProperty(month).GetValue(info);
break;
}
case "Water":
{
data.Water = (double)typeof(ExpenseGridInfo).GetProperty(month).GetValue(info);
break;
}
case "Taxes":
{
data.Taxes = (double)typeof(ExpenseGridInfo).GetProperty(month).GetValue(info);
break;
}
}
}
_chartData.Add(data);
}
this.GridData = _gridData;
this.ChartData = _chartData;
}
public void ExportData()
{
var workbook = new Workbook(WorkbookFormat.Excel2007);
var sheet = workbook.Worksheets.Add("Sheet1");
sheet.DefaultColumnWidth = 200 * 20;
int firstDataRow = 2;
var headerRow = sheet.Rows[firstDataRow - 1];
var props = typeof(ExpenseGridInfo).GetProperties();
for (int i = 0; i < props.Count(); i++)
{
System.Reflection.PropertyInfo prop = props[i];
headerRow.SetCellValue(i, prop.Name);
}
for (int i = 0; i < this.GridData.Count; i++)
{
var worksheetRow = sheet.Rows[i + firstDataRow];
ExpenseGridInfo item = this.GridData[i];
for (int j = 0; j < props.Length; j++)
{
System.Reflection.PropertyInfo info = props[j];
worksheetRow.SetCellValue(j, info.GetValue(item));
}
}
int indexRow = firstDataRow - 1;
int indexData = firstDataRow + this.GridData.Count - 1;
int indexHeader = props.Length - 1;
var tableRegion = new WorksheetRegion(sheet, indexRow, 0, indexData, indexHeader);
var table = sheet.Tables.Add(tableRegion.ToString(), true);
sheet.Rows[0].Height = 5000;
var chart = sheet.Shapes.AddChart(Documents.Excel.Charts.ChartType.ColumnClustered,
sheet.Rows[0].Cells[0], new Infragistics.Core.Point(0, 0),
sheet.Rows[0].Cells[props.Length - 1], new Infragistics.Core.Point(100, 100));
chart.SetSourceData(table.WholeTableRegion.ToString(), true);
chart.AxisCollection[Infragistics.Documents.Excel.Charts.AxisType.Category].AxisBetweenCategories = true;
var memStream = new System.IO.MemoryStream();
workbook.Save(memStream);
memStream.Position = 0;
var bytes = memStream.ToArray();
this.SaveFile(bytes, "ExelWorkbook.xlsx", string.Empty);
}
JSObject module;
bool moduleDownloaded = false;
public async void SaveFile(byte[] bytes, string fileName, string mime)
{
if (Runtime is WebAssemblyJSRuntime wasmRuntime)
{
if (!moduleDownloaded)
{
module = await JSHost.ImportAsync("BlazorFastDownload", "../BlazorFastDownloadFile.js");
moduleDownloaded = true;
}
BlazorFastDownload.DownloadFile(fileName, mime, bytes);
}
else if (Runtime is IJSInProcessRuntime inProc)
inProc.InvokeVoid("BlazorDownloadFile", fileName, mime, bytes);
}
public void Dispose()
{
if (moduleDownloaded && module != null)
{
module.Dispose();
}
}
public class ExpenseGridInfo
{
public string Expense { get; set; }
public double Jan { get; set; }
public double Feb { get; set; }
public double Mar { get; set; }
public double Apr { get; set; }
public double May { get; set; }
public double Jun { get; set; }
public double Jul { get; set; }
public double Aug { get; set; }
public double Sep { get; set; }
public double Oct { get; set; }
public double Nov { get; set; }
public double Dec { get; set; }
}
public class ExpenseChartInfo
{
public string Month { get; set; }
public double Heat { get; set; }
public double Electricity { get; set; }
public double Water { get; set; }
public double Taxes { get; set; }
}
}
razor// these methods are from:
// https://www.meziantou.net/generating-and-downloading-a-file-in-a-blazor-webassembly-application.htm
function BlazorDownloadFile(filename, contentType, content) {
// Blazor marshall byte[] to a base64 string, so we first need to convert the string (content) to a Uint8Array to create the File
var data = base64DecToArr(content);
// Create the URL
var file = new File([data], filename, { type: contentType });
var exportUrl = URL.createObjectURL(file);
// Create the <a> element and click on it
var a = document.createElement("a");
document.body.appendChild(a);
a.href = exportUrl;
a.download = filename;
a.target = "_self";
a.click();
// We don't need to keep the url, let's release the memory
URL.revokeObjectURL(exportUrl);
}
// Convert a base64 string to a Uint8Array. This is needed to create a blob object from the base64 string.
// The code comes from: https://developer.mozilla.org/fr/docs/Web/API/WindowBase64/D%C3%A9coder_encoder_en_base64
function b64ToUint6(nChr) {
return nChr > 64 && nChr < 91 ? nChr - 65 : nChr > 96 && nChr < 123 ? nChr - 71 : nChr > 47 && nChr < 58 ? nChr + 4 : nChr === 43 ? 62 : nChr === 47 ? 63 : 0;
}
function base64DecToArr(sBase64, nBlocksSize) {
var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length, nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, taBytes = new Uint8Array(nOutLen);
for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
nMod4 = nInIdx & 3;
nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
if (nMod4 === 3 || nInLen - nInIdx === 1) {
for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
}
nUint24 = 0;
}
}
return taBytes;
}
//# sourceMappingURL=BlazorDownloadFile.js.map
js/*
CSS styles are loaded from the shared CSS file located at:
https://static.infragistics.com/xplatform/css/samples/
*/
css
Like this sample? Get access to our complete Ignite UI for Blazor toolkit and start building your own apps in minutes. Download it for free.
Usage
워크시트에 차트를 추가하려면 워크시트 도형 컬렉션의 AddChart
메서드를 사용해야 합니다. 이 방법에서는 사용하려는 차트 유형, 왼쪽 상단 셀, 오른쪽 하단 셀 및 차트가 차지할 셀의 비율을 지정할 수 있습니다.
AddChart
메서드는 워크시트에 추가할 워크시트 차트 요소를 반환합니다. 이 정보가 있으면 차트의 SetSourceData
메서드를 사용하여 데이터 소스로 사용하려는 워크시트 셀 영역의 셀 주소를 설정할 수 있을 뿐만 아니라 열 매핑을 전환할지 여부도 설정할 수 있습니다. X 및 Y축에 행을 추가합니다.
Line
, Area
, IgbColumn
및 Pie
포함하여 70개 이상의 차트 유형이 지원됩니다.
다음 코드는 Excel 차트 기능을 사용하는 방법을 보여줍니다. 아래 코드 조각은 워크시트 첫 번째 행의 첫 번째 셀과 13번째 셀 사이에 세로 막대형 차트를 추가합니다. 그런 다음 A2:M6 영역의 데이터에 대한 소스 데이터가 설정되어 기둥형 차트의 X 및 Y축에 대한 열과 행의 매핑이 전환됩니다.
var chart = sheet.Shapes.AddChart(Documents.Excel.Charts.ChartType.ColumnClustered,
sheet.Rows[0].Cells[0], new Core.Point(0, 0),
sheet.Rows[0].Cells[props.Length - 1], new Core.Point(100, 100));
chart.SetSourceData("A2:M6", true);
razor
API References
AddChart
Area
IgbColumn
Line
Pie
WorksheetChart