A number column usually makes a bar for each value it holds — an age chart with a bar for 23, another for 24 and so on. Grouped in ranges, it makes a bar for each span of the column instead: 20 – 24, 25 – 29, 30 – 34. Set GroupByRangeSize (groupByRangeSize in React) for the bars, or SeriesRangeSize (seriesRangeSize) to split each bar into a dataset for each range. It is the same grouping a grid's rows get from RangeSize, so a chart and a grid beside it group a column alike.
Dataverse groups an aggregate by a value, never by a range of values, so the chart asks for a row for each value — or each pair of values, when a series splits them — and the server adds the rows up into their ranges before the chart draws them. A range starts at a multiple of its size: with a size of 5, 23 falls in 20 – 24.
20 – 24. A column with decimals, or a size with them, reads from the start to under the end, 1.0 to under 1.5, with as many decimal places as the column keeps. Set GroupByFormat or SeriesFormat to show the ends in a format of your own, such as N1.Set GroupByRangeSize on an AggregateDataverseChartDataSource to the size of each range. The bars come back in the order of their ranges, lowest first, with the bar of the records that have no value leading them.
import {
AggregateDataverseChartDataSource,
AggregateType,
ChartType,
} from '@powerportalspro/react-charts';
import { DataverseChart } from '@powerportalspro/react-fluent';
import { useMemo } from 'react';
export function MyChart() {
const source = useMemo(
() =>
new AggregateDataverseChartDataSource({
tableName: 'contact',
groupByColumn: 'ppp_age',
groupByRangeSize: 5, // 0 – 4, 5 – 9, 10 – 14 …
aggregateColumn: 'contactid',
aggregate: AggregateType.Count,
}),
[],
);
return (
<DataverseChart
dataSource={source}
type={ChartType.Bar}
title="Contacts by Age"
/>
);
}<DataverseChart Source="_source"
Type="ChartType.Bar"
Title="Contacts by Age" />
@code {
private readonly AggregateDataverseChartDataSource _source = new()
{
TableName = "contact",
GroupByColumn = "ppp_age",
GroupByRangeSize = 5, // 0 – 4, 5 – 9, 10 – 14 …
AggregateColumn = "contactid",
Aggregate = AggregateType.Count,
};
}The contacts counted by age. Pick how many years each bar covers, or a bar for each age. Each pick builds a new data source, and the chart loads again because its source asks for something else.
Set SeriesRangeSize when the column in ranges is the series rather than the bars: the chart groups its bars by GroupByColumn and splits each one into a dataset for each range of SeriesColumn. Stacked, each bar shows how its total divides across the ranges. Both can be in ranges at once — age along the axis, salary ranges stacked in each bar.
const source = useMemo(
() =>
new AggregateDataverseChartDataSource({
tableName: 'contact',
groupByColumn: 'gendercode',
seriesColumn: 'ppp_age',
seriesRangeSize: 20, // a dataset for 0 – 19, 20 – 39, 40 – 59 …
aggregateColumn: 'contactid',
aggregate: AggregateType.Count,
}),
[],
);
return <DataverseChart dataSource={source} type={ChartType.Bar} stacked />;<DataverseChart Source="_source"
Type="ChartType.Bar"
Stacked="true" />
@code {
private readonly AggregateDataverseChartDataSource _source = new()
{
TableName = "contact",
GroupByColumn = "gendercode",
SeriesColumn = "ppp_age",
SeriesRangeSize = 20, // a dataset for 0 – 19, 20 – 39, 40 – 59 …
AggregateColumn = "contactid",
Aggregate = AggregateType.Count,
};
}The contacts counted by gender, each bar stacked by age range. Pick how many years each range covers; the legend lists the ranges, lowest first.
Records with no value in the column are a bar of their own, labelled (Blank) — or in a series, a (Blank) dataset. That holds for any grouping, not only ranges. Set GroupByIncludeBlank or SeriesIncludeBlank to false to leave them out of the chart.
new AggregateDataverseChartDataSource({
tableName: 'contact',
groupByColumn: 'ppp_age',
groupByRangeSize: 10,
groupByIncludeBlank: false, // no (Blank) bar
aggregateColumn: 'contactid',
aggregate: AggregateType.Count,
});_source = new AggregateDataverseChartDataSource
{
TableName = "contact",
GroupByColumn = "ppp_age",
GroupByRangeSize = 10,
GroupByIncludeBlank = false, // no (Blank) bar
AggregateColumn = "contactid",
Aggregate = AggregateType.Count,
};A chart that shares a ViewDataSource with a grid groups in ranges the same way: set RangeSize on its aggregation's GroupBy (or Series). Clicking a bar then highlights every row of the grid whose value falls in that bar's range, and clicking the (Blank) bar highlights the rows with no value.
const dataSource = useViewDataSource({
viewId,
aggregations: [
{
groupBy: { column: 'ppp_age', rangeSize: 10 },
aggregateColumn: 'contactid',
aggregate: AggregateType.Count,
},
],
});_dataSource = new ViewDataSource(GridService, new ViewDataSourceOptions
{
ViewId = _viewId,
Aggregations =
[
new ChartAggregation
{
GroupBy = new ChartGrouping { Column = "ppp_age", RangeSize = 10 },
AggregateColumn = "contactid",
Aggregate = AggregateType.Count,
},
],
});A chart in ranges reads up to 10,000 rows of values — distinct values, or pairs of values when a series splits them. One with more shows an error saying so rather than an incomplete chart. Set RangeGroupingOptions.MaximumRangedValues in the host's startup to change that limit for every grid and chart in the portal. A chart can ask for a lower limit of its own with MaximumRangedValues (maximumRangedValues); one that asks for more than the portal's is held to the portal's.
// this chart reads fewer
new AggregateDataverseChartDataSource({
tableName: 'contact',
groupByColumn: 'ppp_age',
groupByRangeSize: 5,
aggregateColumn: 'contactid',
aggregate: AggregateType.Count,
maximumRangedValues: 2000,
});// Program.cs — every grid and chart in the portal
builder.Services.Configure<RangeGroupingOptions>(o => o.MaximumRangedValues = 20_000);
// this chart reads fewer
_source = new AggregateDataverseChartDataSource
{
TableName = "contact",
GroupByColumn = "ppp_age",
GroupByRangeSize = 5,
AggregateColumn = "contactid",
Aggregate = AggregateType.Count,
MaximumRangedValues = 2_000,
};Dataverse returns at most 5,000 rows to a query, so past 4,999 the values are read 5,000 at a time. Raising the limit has these costs for every grid or chart whose column has that many values:
SplitOverRecordLimit, which multiplies the requests again.A column with that many values is often better grouped in larger ranges, which reads the same rows but draws fewer bars, or filtered first, which reads fewer rows.
See Also