Blazor Working with Charts
Infragistics Blazor Excel Engine의 WorksheetChart
기능을 사용하면 워크시트의 셀 영역에 걸쳐 데이터 추세를 시각적 차트로 표현할 수 있습니다. 예를 들어, 셀 영역에 있는 Excel 데이터를 열, 선 또는 70개 이상의 다른 차트 유형으로 시각화하려는 경우 이 기능을 사용하면 이를 달성하는 데 도움이 될 수 있습니다.
Blazor WebAssembly および Blazor Server 向けに最適化された 60 以上の高性能チャートを使用 とグラフを使用して、生データを魅力的な視覚化に変換し、最高の UX を実現します。
Blazor 차트 작업 예제
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
이 샘플이 마음에 드시나요? Ignite UI for Blazor에 액세스하고 몇 분 만에 나만의 앱을 빌드하기 시작하세요. 무료로 다운로드하세요.
용법
워크시트에 차트를 추가하려면 워크시트 도형 컬렉션의 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 참조
AddChart
Area
IgbColumn
Line
Pie
WorksheetChart