Skip to content

Commit

Permalink
Add frame utils to grafana-utils (#47)
Browse files Browse the repository at this point in the history
* Add frame utils to grafana-utils

* Prepare grafana-utils release 1.4.0

* Remove unused code

* Add build for server and client environments to reduce bundle size

* Prepare grafana-utils release 1.4.1

* Change output for client build and update package exports

* Prepare grafana-utils release 1.4.2

* Fix tests

* Add several esm output for client

* Prepare grafana-utils release 1.4.3
  • Loading branch information
asimonok authored Jun 20, 2024
1 parent a09fdd7 commit 0e2eeaa
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 12 deletions.
6 changes: 6 additions & 0 deletions packages/grafana-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 1.4.3 (2024-06-20)

### Features / Enhancements

- Add frame utils (#47)

## 1.3.0 (2024-02-15)

### Features / Enhancements
Expand Down
1 change: 1 addition & 0 deletions packages/grafana-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- Includes Transformations from `@grafana/grafana`
- Query utils
- Includes Template service
- Frame utils

## License

Expand Down
11 changes: 6 additions & 5 deletions packages/grafana-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@
],
"keywords": [],
"license": "Apache-2.0",
"main": "dist/index.js",
"main": "dist/client.js",
"module": "dist/esm/client.js",
"name": "@volkovlabs/grafana-utils",
"publishConfig": {
"access": "public",
"main": "dist/index.js",
"types": "dist/index.d.ts"
"main": "dist/client.js",
"types": "dist/client.d.ts"
},
"scripts": {
"build": "rollup -c",
Expand All @@ -50,6 +51,6 @@
"test:ci": "jest --maxWorkers 4 --coverage",
"typecheck": "tsc --emitDeclarationOnly false --noEmit"
},
"types": "dist/index.d.ts",
"version": "1.3.0"
"types": "dist/client.d.ts",
"version": "1.4.3"
}
48 changes: 42 additions & 6 deletions packages/grafana-utils/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import terser from '@rollup/plugin-terser';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import inject from '@rollup/plugin-inject';
import packageJson from './package.json' assert { type: 'json' };

const name = packageJson.main.replace(/\.js$/, '');
const getOutputPath = (file) => `dist/${file}`;

export default [
{
input: `src/index.ts`,
input: `src/server.ts`,
plugins: [
commonjs(),
nodeResolve({
Expand All @@ -36,17 +35,54 @@ export default [
],
output: [
{
file: `${name}.js`,
file: getOutputPath('server.js'),
format: 'cjs',
sourcemap: true,
},
],
},
{
input: `src/index.ts`,
input: 'src/client.ts',
plugins: [esbuild(), terser()],
output: [
{
file: getOutputPath('client.js'),
format: 'cjs',
sourcemap: true,
},
{
file: getOutputPath('esm/client.js'),
format: 'esm',
sourcemap: true,
},
],
external: [
'@grafana/data',
'@grafana/schema',
'd3',
'd3-color',
'd3-force',
'd3-interpolate',
'd3-scale-chromatic',
'ol',
'react-colorful',
'rxjs',
'uuid',
],
},
{
input: 'src/client.ts',
plugins: [dts()],
output: {
file: getOutputPath('client.d.ts'),
format: 'es',
},
},
{
input: 'src/server.ts',
plugins: [dts()],
output: {
file: `${name}.d.ts`,
file: getOutputPath('server.d.ts'),
format: 'es',
},
},
Expand Down
7 changes: 7 additions & 0 deletions packages/grafana-utils/src/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './constants';
export * from './grafana/types';
export * from './privateTransformers';
export * from './query';
export * from './types';
export * from './utils';
export * from './variables';
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as module from './index';
import * as module from './server';

describe('Export module', () => {
it('Should not throw window not defined error', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export * from './grafana/types';
export * from './privateTransformers';
export * from './query';
export * from './types';
export * from './utils';
export * from './variables';
export * from '@grafana/data';
130 changes: 130 additions & 0 deletions packages/grafana-utils/src/utils/frame.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { FieldType, toDataFrame } from '@grafana/data';

import { findField, getFieldValues, getLastFieldValue } from './frame';

describe('Frame utils', () => {
describe('findField', () => {
it('Should find first suitable field', () => {
const frame1 = toDataFrame({
fields: [
{
name: 'field',
type: FieldType.number,
},
],
});
const frame2 = toDataFrame({
fields: [
{
name: 'field',
type: FieldType.string,
},
],
});

const result = findField([frame1, frame2], (field) => field.name === 'field');

expect(result).toBeDefined();
expect(result?.name).toEqual('field');
expect(result?.type).toEqual(FieldType.number);
});

it('Should return nothing if no field found', () => {
const frame1 = toDataFrame({
fields: [
{
name: 'field',
type: FieldType.number,
},
],
});

const result = findField([frame1], (field) => field.name === '123');

expect(result).not.toBeDefined();
});
});

describe('getFieldValues', () => {
it('Should return field values', () => {
const series = [
toDataFrame({
fields: [
{ name: 'name', type: FieldType.string, values: ['file1.png', 'file1.png', ''] },
{
name: 'media',
type: FieldType.string,
values: ['1', '2', ''],
},
],
}),
];

const mediaData = getFieldValues(series, 'media');
expect(mediaData).toHaveLength(3);
expect(mediaData[0]).toEqual(series[0].fields[1].values[0]);
expect(mediaData[1]).toEqual(series[0].fields[1].values[1]);
});

it('Should take field with specified type or name', () => {
const dataFrames = [
toDataFrame({
fields: [
{ name: 'name', type: FieldType.string, values: ['file1.png', 'file1.png', ''] },
{
name: 'media',
type: FieldType.number,
values: [1, 2, 0],
},
],
}),
];

const mediaData = getFieldValues(dataFrames, 'media', FieldType.string);

expect(mediaData).toHaveLength(0);
expect(mediaData).toEqual([]);
});
});

describe('getLastFieldValue', () => {
it('Should return last field value', () => {
const frame = toDataFrame({
fields: [
{
name: 'value',
values: [1, 2, 3],
},
],
});

expect(getLastFieldValue([frame], 'value')).toEqual(3);
});

it('Should return nothing if no values', () => {
const frame = toDataFrame({
fields: [
{
name: 'value',
values: [],
},
],
});

expect(getLastFieldValue([frame], 'value')).not.toBeDefined();
});

it('Should return nothing if no field', () => {
const frame = toDataFrame({
fields: [
{
name: 'value',
values: [1, 2],
},
],
});

expect(getLastFieldValue([frame], '')).not.toBeDefined();
});
});
});
54 changes: 54 additions & 0 deletions packages/grafana-utils/src/utils/frame.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { DataFrame, Field, FieldType } from '@grafana/data';

/**
* Find field
*/
export const findField = <TValue = unknown>(
series: DataFrame[],
predicateFn: (field: Field) => boolean
): Field<TValue> | undefined => {
for (let i = 0; i < series.length; i += 1) {
const frame = series[i];

const field = frame.fields.find((field) => predicateFn(field));

/**
* Field found
*/
if (field) {
return field;
}
}
};

/**
* Get field values
* @param series
* @param fieldName
* @param fieldType
*/
export const getFieldValues = <TValue>(series: DataFrame[], fieldName: string, fieldType?: FieldType): TValue[] => {
const field = findField<TValue>(series, (field) => {
const isTypeEqual = fieldType ? field.type === fieldType : true;

return isTypeEqual && field.name === fieldName;
});

if (!field) {
return [];
}

return field.values;
};

/**
* Get last field value
* @param series
* @param fieldName
* @param fieldType
*/
export const getLastFieldValue = <TValue>(series: DataFrame[], fieldName: string, fieldType?: FieldType): TValue => {
const values = getFieldValues<TValue>(series, fieldName, fieldType);

return values[values.length - 1];
};
1 change: 1 addition & 0 deletions packages/grafana-utils/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './frame';

0 comments on commit 0e2eeaa

Please sign in to comment.