@grafana/data#AnnotationEvent TypeScript Examples

The following examples show how to use @grafana/data#AnnotationEvent. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: annotations_srv.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getAnnotations(options: { dashboard: DashboardModel; panel: PanelModel; range: TimeRange }) {
    return Promise.all([this.getGlobalAnnotations(options), this.getAlertStates(options)])
      .then(results => {
        // combine the annotations and flatten results
        let annotations: AnnotationEvent[] = flattenDeep(results[0]);

        // filter out annotations that do not belong to requesting panel
        annotations = annotations.filter(item => {
          // if event has panel id and query is of type dashboard then panel and requesting panel id must match
          if (item.panelId && item.source.type === 'dashboard') {
            return item.panelId === options.panel.id;
          }
          return true;
        });

        annotations = dedupAnnotations(annotations);

        // look for alert state for this panel
        const alertState: any = results[1].find((res: any) => res.panelId === options.panel.id);

        return {
          annotations: annotations,
          alertState: alertState,
        };
      })
      .catch(err => {
        if (!err.message && err.data && err.data.message) {
          err.message = err.data.message;
        }
        console.log('AnnotationSrv.query error', err);
        appEvents.emit(AppEvents.alertError, ['Annotation Query Failed', err.message || err]);
        return [];
      });
  }
Example #2
Source File: response_parser.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
transformToAnnotations(options: any) {
    const queryResult = this.parseQueryResult();

    const list: AnnotationEvent[] = [];

    _.forEach(queryResult, result => {
      let timeIndex = -1;
      let textIndex = -1;
      let tagsIndex = -1;

      for (let i = 0; i < result.columns.length; i++) {
        if (timeIndex === -1 && result.columns[i].type === 'datetime') {
          timeIndex = i;
        }

        if (textIndex === -1 && result.columns[i].text.toLowerCase() === 'text') {
          textIndex = i;
        }

        if (tagsIndex === -1 && result.columns[i].text.toLowerCase() === 'tags') {
          tagsIndex = i;
        }
      }

      _.forEach(result.rows, row => {
        list.push({
          annotation: options.annotation,
          time: Math.floor(ResponseParser.dateTimeToEpoch(row[timeIndex])),
          text: row[textIndex] ? row[textIndex].toString() : '',
          tags: row[tagsIndex] ? row[tagsIndex].trim().split(/\s*,\s*/) : [],
        });
      });
    });

    return list;
  }
Example #3
Source File: datasource.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
async annotationQuery(options: AnnotationQueryRequest<LokiQuery>): Promise<AnnotationEvent[]> {
    if (!options.annotation.expr) {
      return [];
    }

    const interpolatedExpr = this.templateSrv.replace(options.annotation.expr, {}, this.interpolateQueryExpr);
    const query = { refId: `annotation-${options.annotation.name}`, expr: interpolatedExpr };
    const { data } = await this.runRangeQueryWithFallback(query, options).toPromise();
    const annotations: AnnotationEvent[] = [];

    for (const frame of data) {
      const tags: string[] = [];
      for (const field of frame.fields) {
        if (field.labels) {
          tags.push.apply(tags, Object.values(field.labels));
        }
      }
      const view = new DataFrameView<{ ts: string; line: string }>(frame);

      view.forEachRow(row => {
        annotations.push({
          time: new Date(row.ts).valueOf(),
          text: row.line,
          tags,
        });
      });
    }

    return annotations;
  }
Example #4
Source File: AnnoListPanel.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
onUserClick = (e: React.SyntheticEvent, anno: AnnotationEvent) => {
    e.stopPropagation();
    this.setState({
      queryUser: {
        id: anno.userId,
        login: anno.login,
        email: anno.email,
      },
    });
  };
Example #5
Source File: annotations_srv.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
saveAnnotationEvent(annotation: AnnotationEvent) {
    this.globalAnnotationsPromise = null;
    return getBackendSrv().post('/api/annotations', annotation);
  }
Example #6
Source File: annotations_srv.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
updateAnnotationEvent(annotation: AnnotationEvent) {
    this.globalAnnotationsPromise = null;
    return getBackendSrv().put(`/api/annotations/${annotation.id}`, annotation);
  }
Example #7
Source File: annotations_srv.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
deleteAnnotationEvent(annotation: AnnotationEvent) {
    this.globalAnnotationsPromise = null;
    const deleteUrl = `/api/annotations/${annotation.id}`;

    return getBackendSrv().delete(deleteUrl);
  }
Example #8
Source File: event_editor.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
event: AnnotationEvent;
Example #9
Source File: event_manager.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
editEvent(event: AnnotationEvent, elem?: any) {
    this.event = event;
    this.panelCtrl.render();
  }
Example #10
Source File: event_manager.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
event: AnnotationEvent;
Example #11
Source File: event_manager.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
function getRegions(events: AnnotationEvent[]) {
  return _.filter(events, 'isRegion');
}
Example #12
Source File: AnnoListPanel.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
onAnnoClick = (e: React.SyntheticEvent, anno: AnnotationEvent) => {
    e.stopPropagation();
    const { options } = this.props;
    const dashboardSrv = getDashboardSrv();
    const current = dashboardSrv.getCurrent();

    const params: any = {
      from: this._timeOffset(anno.time, options.navigateBefore, true),
      to: this._timeOffset(anno.time, options.navigateAfter, false),
    };

    if (options.navigateToPanel) {
      params.panelId = anno.panelId;
      params.fullscreen = true;
    }

    if (current.id === anno.dashboardId) {
      store.dispatch(
        updateLocation({
          query: params,
          partial: true,
        })
      );
      return;
    }

    getBackendSrv()
      .get('/api/search', { dashboardIds: anno.dashboardId })
      .then((res: any[]) => {
        if (res && res.length && res[0].id === anno.dashboardId) {
          const dash = res[0];
          store.dispatch(
            updateLocation({
              query: params,
              path: dash.url,
            })
          );
          return;
        }
        appEvents.emit(AppEvents.alertWarning, ['Unknown Dashboard: ' + anno.dashboardId]);
      });
  };
Example #13
Source File: AnnoListPanel.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
renderItem = (anno: AnnotationEvent, index: number): JSX.Element => {
    const { options } = this.props;
    const { showUser, showTags, showTime } = options;
    const dashboard = getDashboardSrv().getCurrent();

    return (
      <div className="dashlist-item">
        <span
          className="dashlist-link pointer"
          onClick={e => {
            this.onAnnoClick(e, anno);
          }}
        >
          <span
            className={cx([
              'dashlist-title',
              css`
                margin-right: 8px;
              `,
            ])}
          >
            {anno.text}
          </span>

          <span className="pluginlist-message">
            {anno.login && showUser && (
              <span className="graph-annotation">
                <Tooltip
                  content={
                    <span>
                      Created by:
                      <br /> {anno.email}
                    </span>
                  }
                  theme="info"
                  placement="top"
                >
                  <span onClick={e => this.onUserClick(e, anno)} className="graph-annotation__user">
                    <img src={anno.avatarUrl} />
                  </span>
                </Tooltip>
              </span>
            )}
            {showTags && this.renderTags(anno.tags, false)}
          </span>

          <span className="pluginlist-version">{showTime && <span>{dashboard.formatDate(anno.time)}</span>}</span>
        </span>
      </div>
    );
  };
Example #14
Source File: Graph2.tsx    From loudml-grafana-app with MIT License 5 votes vote down vote up
annotations: AnnotationEvent[];
Example #15
Source File: Graph2.tsx    From loudml-grafana-app with MIT License 5 votes vote down vote up
function getRegions(events: AnnotationEvent[]) {
  return _.filter(events, 'isRegion');
}
Example #16
Source File: datasource.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
async annotationQuery(options: any): Promise<AnnotationEvent[]> {
    const annotation = options.annotation;
    const { expr = '', tagKeys = '', titleFormat = '', textFormat = '' } = annotation;

    if (!expr) {
      return Promise.resolve([]);
    }

    const start = this.getPrometheusTime(options.range.from, false);
    const end = this.getPrometheusTime(options.range.to, true);
    const queryOptions = this.createAnnotationQueryOptions(options);

    // Unsetting min interval for accurate event resolution
    const minStep = '1s';
    const queryModel = {
      expr,
      interval: minStep,
      refId: 'X',
      requestId: `prom-query-${annotation.name}`,
    };

    const query = this.createQuery(queryModel, queryOptions, start, end);

    const self = this;
    const response: PromDataQueryResponse = await this.performTimeSeriesQuery(query, query.start, query.end);
    const eventList: AnnotationEvent[] = [];
    const splitKeys = tagKeys.split(',');

    if (response.cancelled) {
      return [];
    }

    const step = Math.floor(query.step) * 1000;

    response?.data?.data?.result?.forEach(series => {
      const tags = Object.entries(series.metric)
        .filter(([k]) => splitKeys.includes(k))
        .map(([_k, v]: [string, string]) => v);

      series.values.forEach((value: any[]) => {
        let timestampValue;
        // rewrite timeseries to a common format
        if (annotation.useValueForTime) {
          timestampValue = Math.floor(parseFloat(value[1]));
          value[1] = 1;
        } else {
          timestampValue = Math.floor(parseFloat(value[0])) * 1000;
        }
        value[0] = timestampValue;
      });

      const activeValues = series.values.filter((value: Record<number, string>) => parseFloat(value[1]) >= 1);
      const activeValuesTimestamps = activeValues.map((value: number[]) => value[0]);

      // Instead of creating singular annotation for each active event we group events into region if they are less
      // then `step` apart.
      let latestEvent: AnnotationEvent = null;
      activeValuesTimestamps.forEach((timestamp: number) => {
        // We already have event `open` and we have new event that is inside the `step` so we just update the end.
        if (latestEvent && latestEvent.timeEnd + step >= timestamp) {
          latestEvent.timeEnd = timestamp;
          return;
        }

        // Event exists but new one is outside of the `step` so we "finish" the current region.
        if (latestEvent) {
          eventList.push(latestEvent);
        }

        // We start a new region.
        latestEvent = {
          time: timestamp,
          timeEnd: timestamp,
          annotation,
          title: self.resultTransformer.renderTemplate(titleFormat, series.metric),
          tags,
          text: self.resultTransformer.renderTemplate(textFormat, series.metric),
        };
      });
      if (latestEvent) {
        // finish up last point if we have one
        latestEvent.timeEnd = activeValuesTimestamps[activeValuesTimestamps.length - 1];
        eventList.push(latestEvent);
      }
    });

    return eventList;
  }