Draw charts from Azure Data Explorer queries
npm install adx-query-chartsnpm i lodash
npm i css-element-queries
npm i highcharts
typescript
import * as Charts from 'adx-query-charts';
const highchartsVisualizer = new Charts.HighchartsVisualizer();
const chartHelper = chartHelper = new Charts.KustoChartHelper('chart-elem-id', highchartsVisualizer);
const chartOptions: Charts.IChartOptions = {
chartType: Charts.ChartType.UnstackedColumn,
columnsSelection: {
xAxis: { name: 'timestamp', type: Charts.DraftColumnType.DateTime },
yAxes: [{ name: 'requestCount', type: Charts.DraftColumnType.Int }]
}
};
// Draw the chart - the chart will be drawn inside an element with 'chart-elem-id' id
chartHelper.draw(queryResultData, chartOptions);
`
API
$3
| Method: | Description: | Input: | Return value: |
| ------------------------ |-------------------------- | ----------------------------------------------------------------------------- | ---------------- |
| draw | Draw the chart | IQueryResultData - The original query result data
IChartOptions - The information required to draw the chart | Promise<IChartInfo> |
| changeTheme | Change the theme of an existing chart | ChartTheme - The theme to apply | Promise<void> |
| getSupportedColumnTypes | Get the supported column types for the axes and the split-by
for a specific chart type | ChartType - The type of the chart | ISupportedColumnTypes |
| getSupportedColumnsInResult | Get the supported columns from the query result data for the axes and the split-by for a specific chart type | IQueryResultData - The original query result data
ChartType - The type of the chart | ISupportedColumns |
| getDefaultSelection | Get the default columns selection from the query result data.
Select the default columns for the axes and the split-by for drawing a default chart of a specific chart type. | IQueryResultData - The original query result data
ChartType - The type of the chart
ISupportedColumns - (Optional) The list of the supported column types for the axes and the split-by | ColumnsSelection |
| downloadChartJPGImage | Download the chart as JPG image | (error: Error) => void - [Optional] A callback that will be called if the module failed to export the chart image | void |
$3
| Option name: | Type: | Details: | Default value: |
| ------------------- |-------------------- | --------------------------------------------- | ----------------|
| chartType | ChartType | Mandatory.
The type of the chart to draw | |
| columnsSelection | ColumnsSelection| The columns selection for the Axes and the split-by of the chart | If not provided, default columns will be selected.
See: getDefaultSelection method|
| maxUniqueXValues | number | The maximum number of the unique X-axis values.
The chart will show the biggest values, and the rest will be aggregated to a separate data point.| 100 |
| exceedMaxDataPointLabel| string | The label of the data point that contains the aggregated value of all the X-axis values that exceed the 'maxUniqueXValues'| 'OTHER' |
| aggregationType | AggregationType | Multiple rows with the same values for the X-axis and the split-by will be aggregated using a function of this type.
For example, assume we get the following query result data:
['2016-08-02T10:00:00Z', 'Chrome 51.0', 15],
['2016-08-02T10:00:00Z', 'Internet Explorer 9.0', 4]
When drawing a chart with columnsSelection = { xAxis: timestamp, yAxes: count_ }, and aggregationType = AggregationType.Sum we need to aggregate the values of the same timestamp value and return one row with ["2016-08-02T10:00:00Z", 19] | AggregationType.Sum |
| title | string | The title of the chart | |
| legendOptions | ILegendOptions | The legend configuration options | |
| yMinimumValue | number | The minimum value to be displayed on the y-axis.
If not provided, the minimum value is automatically calculated. | |
| yMaximumValue | number | The maximum value to be displayed on the y-axis.
If not provided, the maximum value is automatically calculated. | |
| animationDurationMS | number | The duration of the animation for chart rendering.
The animation can be disabled by setting it to 0. | 1000 |
| fontFamily | string | Chart labels font family | 'az_ea_font, wf_segoe-ui_normal, \"Segoe UI\", \"Segoe WP\", Tahoma, Arial, sans-serif' |
| chartTheme | ChartTheme | The theme of the chart | ChartTheme.Light |
| getUtcOffset | Function
(dateValue: number): number | Callback that is used to get the desired offset from UTC in minutes for date value. Used to handle timezone.
The offset will be added to the original UTC date from the query results data.
For example:
For 'South Africa Standard Time' timezone return -120 and the displayed date will be:
'11/25/2019, 02:00 PM' instead of '11/25/2019, 04:00 PM'
See time zone info
If dateFormatter wasn't provided, the callback will be also used for the X axis labels and the tooltip header. Otherwise - it will only be used for positioning the x-axis.
Callback inputs:
dateValue - The time value in milliseconds since midnight, January 1, 1970 UTC of the date from the query result.
For example: 1574666160000 represents '2019-11-25T07:16:00.000Z'
Callback return value:
The desired offset from UTC in hours | If not provided, the utcOffset will be 0 |
| dateFormatter | Function
(dateValue: number, defaultFormat: DateFormat): string | Callback that is used to format the date values both in the axis and the tooltip
Callback inputs:
dateValue - The original date value in milliseconds since midnight, January 1, 1970 UTC
DateFormat - The default format of the label
Callback return value:
The string represents the display value of the dateValue| If not provided - the default formatting will apply |
| numberFormatter | Function
(numberValue: number): string | Callback that is used to format number values both in the axis and the tooltip
Callback inputs:
numberValue - The original number
Callback return value:
The string represents the display value of the numberValue |If not provided - the default formatting will apply |
| xAxisTitleFormatter | Function
(xAxisColumn: IColumn): string | Callback that is used to get the xAxis title
Callback inputs:
IColumn - The x-axis column
Callback return value:
The desired x-axis title | If not provided - the xAxis title will be the xAxis column name |
| yAxisTitleFormatter | Function
(yAxisColumns: IColumn[]): string | Callback that is used to get the yAxis title
Callback inputs:
[IColumn[]](#IColumn) - The y-axis columns
Callback return value:
The desired y-axis title | If not provided - the yAxis title will be the first yAxis column name |
| updateCustomOptions | Function
(originalOptions: any): void | Callback that is called to allow altering the options of the external charting library before rendering the chart.
Used to allow flexibility and control of the external charting library.
USE WITH CAUTION changing the original options might break the functionality / backward compatibility when using a different IVisualizer or upgrading the charting library.
Validating the updated options is the user's responsibility.
For official chart options - please make contribution to the base code.
Callback inputs:
originalOptions - The custom charting options that are given to the external charting library
| |
| onFinishDataTransformation | Function(dataTransformationInfo: IDataTransformationInfo) : Promise<boolean> | Callback that is called when all the data transformations required to draw the chart are finished
Callback inputs:
IDataTransformationInfo - The information regarding the applied transformations on the original query results
Callback return value:
The promise that is used to continue/stop drawing the chart
When provided, the drawing of the chart will be suspended until this promise will be resolved
When resolved with true - the chart will continue the drawing
When resolved with false - the chart drawing will be canceled | |
| onFinishDrawing | Function(chartInfo: IChartInfo) : void | Callback that is called when the chart drawing is finished
Callback inputs:
IChartInfo - The information regarding the chart | | |
| onFinishChartAnimation | Function(chartInfo: IChartInfo) : void | Callback that is called when the chart animation is finished
Callback inputs:
IChartInfo - The information regarding the chart | | |
| onDataPointClicked | Function(dataPoint: IDataPoint) : void | When this callback is provided, the chart data points will be clickable.
The callback will be called when chart's data point will be clicked, providing the clicked data point information.
Callback inputs:
IDataPoint - The information regarding the columns and values of the clicked data point.
Note that the value of a date-time column in the dataPoint object will be its numeric value - Date.valueOf(). | | |
$3
| Option name: | Type: | Details: |
| -------------------------- |------------------------------------- | -------------------------------------------------------------------------------------------------- |
| numberOfDataPoints | number | The amount of the data points that will be drawn for the chart |
| isPartialData | boolean | True if the chart presents partial data from the original query results
The chart data will be partial when the maximum number of the unique X-axis values exceed the
'maxUniqueXValues' in IChartOptions |
| isAggregationApplied | boolean | True if aggregation was applied on the original query results in order to draw the chart
See 'aggregationType' in IChartOptions for more details |
$3
| Option name: | Type: | Details: |
| -------------------------- |----------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| dataTransformationInfo | IDataTransformationInfo | The information regarding the applied transformations on the original query results |
| status | DrawChartStatus | The status of the draw action |
| error | ChartError | [Optional] The error information in case that the draw action failed |
$3
| Option name: | Type: | Details: |
| ------------ | ----------------------------------- | -------------------------------------------------------------------------------------------------- |
| isEnabled | boolean | [Optional] Set to false if you want to hide the legend.
[Default value: true (show legend)] |
| position | LegendPosition | [Optional] The position of the legend (relative to the chart).
[Default value: Bottom] |
$3
`typescript
enum ChartType {
Line,
Scatter,
UnstackedArea,
StackedArea,
PercentageArea,
UnstackedColumn,
StackedColumn,
PercentageColumn,
UnstackedBar,
StackedBar,
PercentageBar,
Pie,
Donut,
}
`
$3
| Chart type: | X-axis: | Y-axis: | Split-by: |
| ------------------------------------------------------------------------------------------------------------------------ | ------------------ | --------------- | ------------------ |
| Line / Scatter UnstackedArea / StackedArea / PercentageArea UnstackedColumn / StackedColumn / PercentageColumn UnstackedBar / StackedBar / PercentageBar | [Single selection]
DateTime / Int / Long Decimal / Real / String | [If split-by column is selected: y-axis restricted to single selection]
[If split-by column is not selected: y-axis can be single/multi selection]
Int / Long / Decimal / Real | [Single selection]
String |
| Pie / Donut | [Single selection]
String | [Single selection]
Int / Long / Decimal / Real | [Single / Multi selection]
String / DateTime / Bool |
$3
`typescript
interface IColumn {
name: string;
type: DraftColumnType;
}
class ColumnsSelection {
xAxis: IColumn;
yAxes: IColumn[];
splitBy?: IColumn[];
}
`
See Columns selection per chart type
$3
`typescript
enum AggregationType {
Sum,
Average,
Min,
Max
}
`
$3
`typescript
enum ChartTheme {
Dark,
Light
}
`
$3
`typescript
enum ErrorCode {
InvalidQueryResultData,
InvalidColumnsSelection,
UnsupportedTypeInColumnsSelection,
InvalidChartContainerElementId,
InvalidDate,
FailedToCreateVisualization,
EmptyPie
}
`
$3
`typescript
class ChartError extends Error {
errorCode: ErrorCode;
}
`
See ErrorCode
$3
`typescript
export enum DateFormat {
FullDate // The full date and time. For example: 12/7/2019, 2:30:00.600
Time // The full time, without the milliseconds. For example: 2:30:00
FullTime // The full time, including the milliseconds. For example: 2:30:00.600
HourAndMinute // The hours and minutes. For example: 2:30
MonthAndDay // The month and day. For example: July 12th
MonthAndYear // The month and day. For example: July 2019
Year // The year. For example: 2019
}
`
$3
`typescript
export enum DrawChartStatus {
Success = 'Success', // Successfully drawn the chart
Failed = 'Failed', // There was an error while trying to draw the chart
Canceled = 'Canceled' // The chart drawing was canceled
}
`
See 'onFinishDataTransformation' return value in IChartOptions for more information regarding drawing cancellation
$3
`typescript
type IRowValue = string | number;
type ISeriesRowValue = IRowValue | string[] | number[];
type IRow = IRowValue[];
type ISeriesRow = ISeriesRowValue[];
interface IColumn {
name: string;
type: DraftColumnType;
}
`
$3
`typescript
interface IQueryResultData {
rows: IRow[] | ISeriesRow[];
columns: IColumn[];
}
`
See IColumn
$3
`typescript
interface ISupportedColumns {
xAxis: IColumn[];
yAxis: IColumn[];
splitBy: IColumn[];
}
`
See IColumn
$3
See: https://kusto.azurewebsites.net/docs/query/scalar-data-types/index.html
`typescript
enum DraftColumnType {
Bool,
DateTime,
Decimal,
Dynamic,
Guid,
Int,
Long,
Real,
String,
TimeSpan
}
`
$3
`typescript
interface ISupportedColumnTypes {
xAxis: DraftColumnType[];
yAxis: DraftColumnType[];
splitBy: DraftColumnType[];
}
`
See DraftColumnType
$3
`typescript
export interface IDataPointInfo {
column: IColumn;
value: IRowValue;
}
export interface IDataPoint {
x: IDataPointInfo;
y: IDataPointInfo;
splitBy?: IDataPointInfo;
}
`
$3
`typescript
export enum LegendPosition {
Bottom,
Right
}
`
Test
Unit tests are written using Jest.
`sh
Run tests: npm run test
``