InputDatasource.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Types
  2. import {
  3. DataQueryRequest,
  4. DataQueryResponse,
  5. DataSourceApi,
  6. DataSourceInstanceSettings,
  7. MetricFindValue,
  8. } from '@grafana/ui';
  9. import { DataFrame, DataFrameDTO, toDataFrame } from '@grafana/data';
  10. import { InputQuery, InputOptions } from './types';
  11. export class InputDatasource extends DataSourceApi<InputQuery, InputOptions> {
  12. data: DataFrame[] = [];
  13. constructor(instanceSettings: DataSourceInstanceSettings<InputOptions>) {
  14. super(instanceSettings);
  15. if (instanceSettings.jsonData.data) {
  16. this.data = instanceSettings.jsonData.data.map(v => toDataFrame(v));
  17. }
  18. }
  19. /**
  20. * Convert a query to a simple text string
  21. */
  22. getQueryDisplayText(query: InputQuery): string {
  23. if (query.data) {
  24. return 'Panel Data: ' + describeDataFrame(query.data);
  25. }
  26. return `Shared Data From: ${this.name} (${describeDataFrame(this.data)})`;
  27. }
  28. metricFindQuery(query: string, options?: any): Promise<MetricFindValue[]> {
  29. return new Promise((resolve, reject) => {
  30. const names = [];
  31. for (const series of this.data) {
  32. for (const field of series.fields) {
  33. // TODO, match query/options?
  34. names.push({
  35. text: field.name,
  36. });
  37. }
  38. }
  39. resolve(names);
  40. });
  41. }
  42. query(options: DataQueryRequest<InputQuery>): Promise<DataQueryResponse> {
  43. const results: DataFrame[] = [];
  44. for (const query of options.targets) {
  45. let data = this.data;
  46. if (query.data) {
  47. data = query.data.map(v => toDataFrame(v));
  48. }
  49. for (let i = 0; i < data.length; i++) {
  50. results.push({
  51. ...data[i],
  52. refId: query.refId,
  53. });
  54. }
  55. }
  56. return Promise.resolve({ data: results });
  57. }
  58. testDatasource() {
  59. return new Promise((resolve, reject) => {
  60. let rowCount = 0;
  61. let info = `${this.data.length} Series:`;
  62. for (const series of this.data) {
  63. const length = series.length;
  64. info += ` [${series.fields.length} Fields, ${length} Rows]`;
  65. rowCount += length;
  66. }
  67. if (rowCount > 0) {
  68. resolve({
  69. status: 'success',
  70. message: info,
  71. });
  72. }
  73. reject({
  74. status: 'error',
  75. message: 'No Data Entered',
  76. });
  77. });
  78. }
  79. }
  80. function getLength(data?: DataFrameDTO | DataFrame) {
  81. if (!data || !data.fields || !data.fields.length) {
  82. return 0;
  83. }
  84. if (data.hasOwnProperty('length')) {
  85. return (data as DataFrame).length;
  86. }
  87. return data.fields[0].values.length;
  88. }
  89. export function describeDataFrame(data: Array<DataFrameDTO | DataFrame>): string {
  90. if (!data || !data.length) {
  91. return '';
  92. }
  93. if (data.length > 1) {
  94. const count = data.reduce((acc, series) => {
  95. return acc + getLength(series);
  96. }, 0);
  97. return `${data.length} Series, ${count} Rows`;
  98. }
  99. const series = data[0];
  100. if (!series.fields) {
  101. return 'Missing Fields';
  102. }
  103. const length = getLength(series);
  104. return `${series.fields.length} Fields, ${length} Rows`;
  105. }
  106. export default InputDatasource;