Skip to content

Commit

Permalink
Line Chart Fill (#828)
Browse files Browse the repository at this point in the history
* Add LineChartDataset Fill options

* Updated documentation

* LineChartDataset.cs  - code cleanup

* Code cleanup

* #828 Formating updated

* #828: LineChartDataset - formating updates

* Charts demos - updated

---------

Co-authored-by: Mischa Spelt <[email protected]>
Co-authored-by: Vikram Reddy <[email protected]>
  • Loading branch information
3 people authored Sep 7, 2024
1 parent 2cc30bc commit 73191ff
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PageTitle>@title</PageTitle>

<MetaTags PageUrl="@pageUrl" Title="@title" Description="@description" ImageUrl="@imageUrl"/>
<MetaTags PageUrl="@pageUrl" Title="@title" Description="@description" ImageUrl="@imageUrl" />

<h1>Blazor Line Chart</h1>
<div class="lead mb-3">
Expand All @@ -17,26 +17,26 @@
Refer to the <a href="/getting-started/blazor-webassembly">getting started guide</a> for setting up charts.
</div>

<SectionHeading Size="HeadingSize.H4" Text="How it works" PageUrl="@pageUrl" HashTagName="how-it-works"/>
<SectionHeading Size="HeadingSize.H4" Text="How it works" PageUrl="@pageUrl" HashTagName="how-it-works" />
<div class="mb-3">
In the following example, a <a href="/utils/color-utility#categorical-12-color">categorical 12-color</a> palette is used.
</div>
<Callout Heading="TIP" Color="CalloutColor.Success">
For data visualization, you can use the predefined palettes <code>ColorUtility.CategoricalTwelveColors</code> for a 12-color palette and <code>ColorUtility.CategoricalSixColors</code> for a 6-color palette.
These palettes offer a range of distinct and visually appealing colors that can be applied to represent different categories or data elements in your visualizations.
</Callout>
<Demo Type="typeof(LineChart_Demo_01_A_Examples)" Tabs="true"/>
<Demo Type="typeof(LineChart_Demo_01_A_Examples)" Tabs="true" />
<div class="my-3"></div>
<Demo Type="typeof(LineChart_Demo_01_B_Examples)" Tabs="true" />

<SectionHeading Size="HeadingSize.H4" Text="Locale" PageUrl="@pageUrl" HashTagName="locale"/>
<SectionHeading Size="HeadingSize.H4" Text="Locale" PageUrl="@pageUrl" HashTagName="locale" />
<div class="my-3">
By default, the chart is using the default locale of the platform on which it is running.
In the following example, you will see the chart in the <b>German</b> locale (<b>de_DE</b>).
</div>
<Demo Type="typeof(LineChart_Demo_02_Locale)" Tabs="true"/>
<Demo Type="typeof(LineChart_Demo_02_Locale)" Tabs="true" />

<SectionHeading Size="HeadingSize.H4" Text="Add data dynamically for a specific dataset" PageUrl="@pageUrl" HashTagName="add-data-dynamically-for-a-specific-dataset"/>
<SectionHeading Size="HeadingSize.H4" Text="Add data dynamically for a specific dataset" PageUrl="@pageUrl" HashTagName="add-data-dynamically-for-a-specific-dataset" />
<Demo Type="typeof(LineChart_Demo_03_Dynamically_add_data)" Tabs="true" />

<SectionHeading Size="HeadingSize.H4" Text="Data labels" PageUrl="@pageUrl" HashTagName="data-labels" />
Expand All @@ -45,6 +45,9 @@
<SectionHeading Size="HeadingSize.H4" Text="Tick Configuration" PageUrl="@pageUrl" HashTagName="tick-configuration" />
<Demo Type="typeof(LineChart_Demo_05_Tick_Configuration)" Tabs="true" />

<SectionHeading Size="HeadingSize.H4" Text="Fill between datasets" PageUrl="@pageUrl" HashTagName="dataset-fill" />
<Demo Type="typeof(LineChart_Demo_06_Dataset_Fill)" Tabs="true" />

@code {
private readonly string pageUrl = "/charts/line-chart";
private readonly string title = "Blazor Line Chart";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
</div>

<div class="mt-5">
<Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await RandomizeAsync()"> Randomize </Button>
<Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await AddDatasetAsync()" Disabled="@(datasetsCount >= 12)"> Add Dataset </Button>
<Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await AddDataAsync()"> Add Data </Button>
<Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await ShowHorizontalLineChartAsync()"> Horizontal Line Chart </Button>
<Button Type="ButtonType.Button" Class="mb-2" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await ShowVerticalLineChartAsync()"> Vertical Line Chart </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await RandomizeAsync()"> Randomize </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await AddDatasetAsync()"> Add Dataset </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await AddDataAsync()"> Add Data </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await ShowHorizontalLineChartAsync()"> Horizontal Line Chart </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await ShowVerticalLineChartAsync()"> Vertical Line Chart </Button>
</div>

@code {
Expand All @@ -23,8 +23,12 @@
protected override void OnInitialized()
{
chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(3) };
lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } };
lineChartOptions.Scales.Y!.Max = 250;
lineChartOptions = new()
{
IndexAxis = "x",
Interaction = new Interaction { Mode = InteractionMode.Index, Intersect = false },
Responsive = true,
};
}

protected override async Task OnAfterRenderAsync(bool firstRender)
Expand Down Expand Up @@ -125,13 +129,10 @@
{
Label = $"Team {datasetsCount}",
Data = GetRandomData(),
BackgroundColor = c.ToRgbString(),
BackgroundColor = c.ToRgbaString(),
BorderColor = c.ToRgbString(),
BorderWidth = 2,
HoverBorderWidth = 4,
// PointBackgroundColor = c.ToRgbString(),
// PointRadius = 0, // hide points
// PointHoverRadius = 4,
PointRadius = new List<double> { 5 },
PointHoverRadius = new List<double> { 8 },
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
</div>

<div class="mt-5">
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await ChangeTicksAlignmentToStart()"> Alignment: start </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await ChangeTicksAlignmentToCenter()"> Alignment: center (default) </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" @onclick="async () => await ChangeTicksAlignmentToEnd()"> Alignment: end </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await ChangeTicksAlignmentToStart()"> Alignment: start </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await ChangeTicksAlignmentToCenter()"> Alignment: center (default) </Button>
<Button Type="ButtonType.Button" Color="ButtonColor.Primary" Size="ButtonSize.Small" Class="my-1 mr-1" @onclick="async () => await ChangeTicksAlignmentToEnd()"> Alignment: end </Button>
</div>

@code {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<LineChart Height="200" @ref="lineChart" Width="500" />

<div class="mt-5">
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await NoFillAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> No fill</Button>
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await FillToNextAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> Fill to next (relative index +1)</Button>
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await FillToZeroAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> Fill to specific (absolute index 0) </Button>
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await FillToReferenceAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> Fill to specific (by object reference)</Button>
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await FillToStartAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> Fill to start </Button>
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await FillToEndAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> Fill to end</Button>
<Button Color="ButtonColor.Primary" Class="my-1 mr-1" @onclick="async () => await FillToValueAsync()" Size="ButtonSize.Small" Type="ButtonType.Button"> Fill to value 50</Button>
</div>

@code {
private LineChart lineChart = default!;
private LineChartOptions lineChartOptions = default!;
private ChartData chartData = default!;

private int datasetsCount;
private int labelsCount;

private Random random = new();

protected override void OnInitialized()
{
chartData = new ChartData { Labels = GetDefaultDataLabels(6), Datasets = GetDefaultDataSets(4) };
lineChartOptions = new() { Responsive = true, Interaction = new Interaction { Mode = InteractionMode.Index } };
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await lineChart.InitializeAsync(chartData, lineChartOptions);
}
await base.OnAfterRenderAsync(firstRender);
}

public async Task NoFillAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
middle!.Fill = null;
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

public async Task FillToNextAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
middle!.FillToDataset(1, true);
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

public async Task FillToZeroAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
middle!.FillToDataset(0, false);
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

public async Task FillToReferenceAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
var fillTo = chartData.Datasets[3] as LineChartDataset;

middle!.FillToDataset(chartData, fillTo!);
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

public async Task FillToStartAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
middle!.FillToStart();
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

public async Task FillToEndAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
middle!.FillToEnd();
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

public async Task FillToValueAsync()
{
var middle = chartData.Datasets[1] as LineChartDataset;
middle!.FillToValue(50.0);
await lineChart.UpdateAsync(chartData, lineChartOptions);
}

#region Data Preparation

private List<IChartDataset> GetDefaultDataSets(int numberOfDatasets)
{
var datasets = new List<IChartDataset>();

for (var index = 0; index < numberOfDatasets; index++)
{
datasets.Add(GetRandomLineChartDataset());
}

return datasets;
}

private LineChartDataset GetRandomLineChartDataset()
{
var c = ColorUtility.CategoricalTwelveColors[datasetsCount].ToColor();

datasetsCount += 1;

return new LineChartDataset
{
Label = $"Team {datasetsCount}",
Data = GetRandomData(),
BackgroundColor = c.ToRgbaString(),
BorderCapStyle = "round",
BorderColor = c.ToRgbString(),
BorderWidth = 2,
HoverBorderWidth = 4,
PointBackgroundColor = new List<string>() { c.ToRgbString() },
// PointRadius = 0, // hide points
PointHoverRadius = new List<double>() { 4 },
};
}

private List<double?> GetRandomData()
{
var data = new List<double?>();
for (var index = 0; index < labelsCount; index++)
{
data.Add(random.Next(200));
}

return data;
}

private List<string> GetDefaultDataLabels(int numberOfLabels)
{
var labels = new List<string>();
for (var index = 0; index < numberOfLabels; index++)
{
labels.Add(GetNextDataLabel());
}

return labels;
}

private string GetNextDataLabel()
{
labelsCount += 1;
return $"Day {labelsCount}";
}

#endregion Data Preparation
}
Loading

0 comments on commit 73191ff

Please sign in to comment.