@grafana/data#LinkModel TypeScript Examples

The following examples show how to use @grafana/data#LinkModel. 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: linkSuppliers.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getLinksFromLogsField = (field: Field, rowIndex: number): Array<LinkModel<Field>> => {
  const scopedVars: any = {};
  scopedVars['__value'] = {
    value: {
      raw: field.values.get(rowIndex),
    },
    text: 'Raw value',
  };

  return field.config.links
    ? field.config.links.map(link => getLinkSrv().getDataLinkUIModel(link, scopedVars, field))
    : [];
}
Example #2
Source File: link_srv.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
/**
   * Returns LinkModel which is basically a DataLink with all values interpolated through the templateSrv.
   */
  getDataLinkUIModel = <T>(link: DataLink, scopedVars: ScopedVars, origin: T): LinkModel<T> => {
    const params: KeyValue = {};
    const timeRangeUrl = toUrlParams(this.timeSrv.timeRangeForUrl());

    let href = link.url;

    if (link.onBuildUrl) {
      href = link.onBuildUrl({
        origin,
        scopedVars,
      });
    }

    let onClick: (e: any) => void = undefined;

    if (link.onClick) {
      onClick = (e: any) => {
        link.onClick({
          origin,
          scopedVars,
          e,
        });
      };
    }

    const info: LinkModel<T> = {
      href: locationUtil.assureBaseUrl(href.replace(/\n/g, '')),
      title: this.templateSrv.replace(link.title || '', scopedVars),
      target: link.targetBlank ? '_blank' : '_self',
      origin,
      onClick,
    };

    this.templateSrv.fillVariableValuesForUrl(params, scopedVars);

    const variablesQuery = toUrlParams(params);

    info.href = this.templateSrv.replace(info.href, {
      ...scopedVars,
      [DataLinkBuiltInVars.keepTime]: {
        text: timeRangeUrl,
        value: timeRangeUrl,
      },
      [DataLinkBuiltInVars.includeVars]: {
        text: variablesQuery,
        value: variablesQuery,
      },
    });

    info.href = getConfig().disableSanitizeHtml ? info.href : sanitizeUrl(info.href);

    return info;
  };
Example #3
Source File: module.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
link(scope: any, elem: JQuery, attrs: any, ctrl: any) {
    const $location = this.$location;
    const linkSrv = this.linkSrv;
    const $timeout = this.$timeout;
    const $sanitize = this.$sanitize;
    const panel = ctrl.panel;
    const templateSrv = this.templateSrv;
    let linkInfo: LinkModel<any> | null = null;
    elem = elem.find('.singlestat-panel');

    function getPanelContainer() {
      return elem.closest('.panel-container');
    }

    function applyColoringThresholds(valueString: string) {
      const data = ctrl.data;
      const color = getColorForValue(data, data.value);
      if (color) {
        return '<span style="color:' + color + '">' + valueString + '</span>';
      }

      return valueString;
    }

    function getSpan(className: string, fontSizePercent: string, applyColoring: any, value: string) {
      value = $sanitize(templateSrv.replace(value, ctrl.data.scopedVars));
      value = applyColoring ? applyColoringThresholds(value) : value;
      const pixelSize = (parseInt(fontSizePercent, 10) / 100) * BASE_FONT_SIZE;
      return '<span class="' + className + '" style="font-size:' + pixelSize + 'px">' + value + '</span>';
    }

    function getBigValueHtml() {
      const data: ShowData = ctrl.data;
      let body = '<div class="singlestat-panel-value-container">';

      if (panel.prefix) {
        body += getSpan('singlestat-panel-prefix', panel.prefixFontSize, panel.colorPrefix, panel.prefix);
      }

      body += getSpan(
        'singlestat-panel-value',
        panel.valueFontSize,
        panel.colorValue,
        formattedValueToString(data.display)
      );

      if (panel.postfix) {
        body += getSpan('singlestat-panel-postfix', panel.postfixFontSize, panel.colorPostfix, panel.postfix);
      }

      body += '</div>';

      return body;
    }

    function getValueText() {
      const data: ShowData = ctrl.data;
      let result = panel.prefix ? templateSrv.replace(panel.prefix, data.scopedVars) : '';
      result += formattedValueToString(data.display);
      result += panel.postfix ? templateSrv.replace(panel.postfix, data.scopedVars) : '';

      return result;
    }

    function addGauge() {
      const data: ShowData = ctrl.data;
      const width = elem.width();
      const height = elem.height();
      // Allow to use a bit more space for wide gauges
      const dimension = Math.min(width, height * 1.3);

      ctrl.invalidGaugeRange = false;
      if (panel.gauge.minValue > panel.gauge.maxValue) {
        ctrl.invalidGaugeRange = true;
        return;
      }

      const plotCanvas = $('<div></div>');
      const plotCss = {
        top: '5px',
        margin: 'auto',
        position: 'relative',
        height: height * 0.9 + 'px',
        width: dimension + 'px',
      };

      plotCanvas.css(plotCss);

      const thresholds = [];

      for (let i = 0; i < data.thresholds.length; i++) {
        thresholds.push({
          value: data.thresholds[i],
          color: data.colorMap[i],
        });
      }
      thresholds.push({
        value: panel.gauge.maxValue,
        color: data.colorMap[data.colorMap.length - 1],
      });

      const bgColor = config.bootData.user.lightTheme ? 'rgb(230,230,230)' : 'rgb(38,38,38)';

      const fontScale = parseInt(panel.valueFontSize, 10) / 100;
      const fontSize = Math.min(dimension / 5, 100) * fontScale;
      // Reduce gauge width if threshold labels enabled
      const gaugeWidthReduceRatio = panel.gauge.thresholdLabels ? 1.5 : 1;
      const gaugeWidth = Math.min(dimension / 6, 60) / gaugeWidthReduceRatio;
      const thresholdMarkersWidth = gaugeWidth / 5;
      const thresholdLabelFontSize = fontSize / 2.5;

      const options: any = {
        series: {
          gauges: {
            gauge: {
              min: panel.gauge.minValue,
              max: panel.gauge.maxValue,
              background: { color: bgColor },
              border: { color: null },
              shadow: { show: false },
              width: gaugeWidth,
            },
            frame: { show: false },
            label: { show: false },
            layout: { margin: 0, thresholdWidth: 0 },
            cell: { border: { width: 0 } },
            threshold: {
              values: thresholds,
              label: {
                show: panel.gauge.thresholdLabels,
                margin: thresholdMarkersWidth + 1,
                font: { size: thresholdLabelFontSize },
              },
              show: panel.gauge.thresholdMarkers,
              width: thresholdMarkersWidth,
            },
            value: {
              color: panel.colorValue ? getColorForValue(data, data.display.numeric) : null,
              formatter: () => {
                return getValueText();
              },
              font: {
                size: fontSize,
                family: config.theme.typography.fontFamily.sansSerif,
              },
            },
            show: true,
          },
        },
      };

      elem.append(plotCanvas);

      const plotSeries = {
        data: [[0, data.value]],
      };

      $.plot(plotCanvas, [plotSeries], options);
    }

    function addSparkline() {
      const data: ShowData = ctrl.data;
      const width = elem.width();
      if (width < 30) {
        // element has not gotten it's width yet
        // delay sparkline render
        setTimeout(addSparkline, 30);
        return;
      }
      if (!data.sparkline || !data.sparkline.length) {
        // no sparkline data
        return;
      }

      const height = ctrl.height;
      const plotCanvas = $('<div></div>');
      const plotCss: any = {};
      plotCss.position = 'absolute';
      plotCss.bottom = '0px';

      if (panel.sparkline.full) {
        plotCss.left = '0px';
        plotCss.width = width + 'px';
        const dynamicHeightMargin = height <= 100 ? 5 : Math.round(height / 100) * 15 + 5;
        plotCss.height = height - dynamicHeightMargin + 'px';
      } else {
        plotCss.left = '0px';
        plotCss.width = width + 'px';
        plotCss.height = Math.floor(height * 0.25) + 'px';
      }

      plotCanvas.css(plotCss);

      const options = {
        legend: { show: false },
        series: {
          lines: {
            show: true,
            fill: 1,
            lineWidth: 1,
            fillColor: getColorFromHexRgbOrName(panel.sparkline.fillColor, config.theme.type),
            zero: false,
          },
        },
        yaxis: {
          show: false,
          min: panel.sparkline.ymin,
          max: panel.sparkline.ymax,
        },
        xaxis: {
          show: false,
          mode: 'time',
          min: ctrl.range.from.valueOf(),
          max: ctrl.range.to.valueOf(),
        },
        grid: { hoverable: false, show: false },
      };

      elem.append(plotCanvas);

      const plotSeries = {
        data: data.sparkline,
        color: getColorFromHexRgbOrName(panel.sparkline.lineColor, config.theme.type),
      };

      $.plot(plotCanvas, [plotSeries], options);
    }

    function render() {
      if (!ctrl.data) {
        return;
      }
      const { data, panel } = ctrl;

      // get thresholds
      data.thresholds = panel.thresholds
        ? panel.thresholds.split(',').map((strVale: string) => {
            return Number(strVale.trim());
          })
        : [];

      // Map panel colors to hex or rgb/a values
      if (panel.colors) {
        data.colorMap = panel.colors.map((color: string) => getColorFromHexRgbOrName(color, config.theme.type));
      }

      const body = panel.gauge.show ? '' : getBigValueHtml();

      if (panel.colorBackground) {
        const color = getColorForValue(data, data.display.numeric);
        if (color) {
          getPanelContainer().css('background-color', color);
          if (scope.fullscreen) {
            elem.css('background-color', color);
          } else {
            elem.css('background-color', '');
          }
        } else {
          getPanelContainer().css('background-color', '');
          elem.css('background-color', '');
        }
      } else {
        getPanelContainer().css('background-color', '');
        elem.css('background-color', '');
      }

      elem.html(body);

      if (panel.sparkline.show) {
        addSparkline();
      }

      if (panel.gauge.show) {
        addGauge();
      }

      elem.toggleClass('pointer', panel.links.length > 0);

      if (panel.links.length > 0) {
        linkInfo = linkSrv.getDataLinkUIModel(panel.links[0], data.scopedVars, {});
      } else {
        linkInfo = null;
      }
    }

    function hookupDrilldownLinkTooltip() {
      // drilldown link tooltip
      const drilldownTooltip = $('<div id="tooltip" class="">hello</div>"');

      elem.mouseleave(() => {
        if (panel.links.length === 0) {
          return;
        }
        $timeout(() => {
          drilldownTooltip.detach();
        });
      });

      elem.click(evt => {
        if (!linkInfo) {
          return;
        }
        // ignore title clicks in title
        if ($(evt).parents('.panel-header').length > 0) {
          return;
        }

        if (linkInfo.target === '_blank') {
          window.open(linkInfo.href, '_blank');
          return;
        }

        if (linkInfo.href.indexOf('http') === 0) {
          window.location.href = linkInfo.href;
        } else {
          $timeout(() => {
            $location.url(locationUtil.stripBaseFromUrl(linkInfo.href));
          });
        }

        drilldownTooltip.detach();
      });

      elem.mousemove(e => {
        if (!linkInfo) {
          return;
        }

        drilldownTooltip.text('click to go to: ' + linkInfo.title);
        drilldownTooltip.place_tt(e.pageX, e.pageY - 50);
      });
    }

    hookupDrilldownLinkTooltip();

    this.events.on(PanelEvents.render, () => {
      render();
      ctrl.renderingCompleted();
    });
  }