prometheus

Форк
0
/
jquery.flot.stack.js 
197 строк · 6.3 Кб
1
/*
2
SPDX-License-Identifier: MIT
3
Source: https://github.com/grafana/grafana/blob/main/public/vendor/flot/jquery.flot.stock.js
4
*/
5

6
/* eslint-disable prefer-spread */
7
/* eslint-disable no-loop-func */
8
/* eslint-disable @typescript-eslint/no-this-alias */
9
/* eslint-disable no-redeclare */
10
/* eslint-disable no-useless-escape */
11
/* eslint-disable prefer-const */
12
/* eslint-disable @typescript-eslint/explicit-function-return-type */
13
/* eslint-disable @typescript-eslint/no-use-before-define */
14
/* eslint-disable eqeqeq */
15
/* eslint-disable no-var */
16

17
/* Flot plugin for stacking data sets rather than overlyaing them.
18

19
Copyright (c) 2007-2014 IOLA and Ole Laursen.
20
Licensed under the MIT license.
21

22
The plugin assumes the data is sorted on x (or y if stacking horizontally).
23
For line charts, it is assumed that if a line has an undefined gap (from a
24
null point), then the line above it should have the same gap - insert zeros
25
instead of "null" if you want another behaviour. This also holds for the start
26
and end of the chart. Note that stacking a mix of positive and negative values
27
in most instances doesn't make sense (so it looks weird).
28

29
Two or more series are stacked when their "stack" attribute is set to the same
30
key (which can be any number or string or just "true"). To specify the default
31
stack, you can set the stack option like this:
32

33
    series: {
34
        stack: null/false, true, or a key (number/string)
35
    }
36

37
You can also specify it for a single series, like this:
38

39
    $.plot( $("#placeholder"), [{
40
        data: [ ... ],
41
        stack: true
42
    }])
43

44
The stacking order is determined by the order of the data series in the array
45
(later series end up on top of the previous).
46

47
Internally, the plugin modifies the datapoints in each series, adding an
48
offset to the y value. For line series, extra data points are inserted through
49
interpolation. If there's a second y value, it's also adjusted (e.g for bar
50
charts or filled areas).
51

52
*/
53

54
(function($) {
55
  const options = {
56
    series: { stack: null }, // or number/string
57
  };
58

59
  function init(plot) {
60
    function findMatchingSeries(s, allseries) {
61
      let res = null;
62
      for (let i = 0; i < allseries.length; ++i) {
63
        if (s == allseries[i]) break;
64

65
        if (allseries[i].stack == s.stack) res = allseries[i];
66
      }
67

68
      return res;
69
    }
70

71
    function stackData(plot, s, datapoints) {
72
      if (s.stack == null || s.stack === false) return;
73

74
      const other = findMatchingSeries(s, plot.getData());
75
      if (!other) return;
76

77
      let ps = datapoints.pointsize,
78
        points = datapoints.points,
79
        otherps = other.datapoints.pointsize,
80
        otherpoints = other.datapoints.points,
81
        newpoints = [],
82
        px,
83
        py,
84
        intery,
85
        qx,
86
        qy,
87
        bottom,
88
        withlines = s.lines.show,
89
        horizontal = s.bars.horizontal,
90
        withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
91
        withsteps = withlines && s.lines.steps,
92
        keyOffset = horizontal ? 1 : 0,
93
        accumulateOffset = horizontal ? 0 : 1,
94
        i = 0,
95
        j = 0,
96
        l,
97
        m;
98

99
      while (true) {
100
        if (i >= points.length && j >= otherpoints.length) break;
101

102
        l = newpoints.length;
103

104
        if (i < points.length && points[i] == null) {
105
          // take the points from the previous series
106
          for (m = 0; m < ps; ++m) newpoints.push(otherpoints[i + m]);
107
          if (withbottom) newpoints[l + 2] = otherpoints[i + accumulateOffset];
108
          i += ps;
109
        } else if (i >= points.length) {
110
          j += otherps;
111
        } else if (j >= otherpoints.length) {
112
          // take the remaining points from the current series
113
          for (m = 0; m < ps; ++m) newpoints.push(points[i + m]);
114
          i += ps;
115
        } else if (j < otherpoints.length && otherpoints[j] == null) {
116
          // ignore point
117
          j += otherps;
118
        } else {
119
          // cases where we actually got two points
120
          px = points[i + keyOffset];
121
          py = points[i + accumulateOffset];
122
          qx = otherpoints[j + keyOffset];
123
          qy = otherpoints[j + accumulateOffset];
124
          bottom = 0;
125

126
          if (px == qx) {
127
            for (m = 0; m < ps; ++m) newpoints.push(points[i + m]);
128

129
            newpoints[l + accumulateOffset] += qy;
130
            bottom = qy;
131

132
            i += ps;
133
            j += otherps;
134
          } else if (px > qx) {
135
            // take the point from the previous series so that next series will correctly stack
136
            if (i == 0) {
137
              for (m = 0; m < ps; ++m) newpoints.push(otherpoints[j + m]);
138
              bottom = qy;
139
            }
140
            // we got past point below, might need to
141
            // insert interpolated extra point
142
            if (i > 0 && points[i - ps] != null) {
143
              intery = py + ((points[i - ps + accumulateOffset] - py) * (qx - px)) / (points[i - ps + keyOffset] - px);
144
              newpoints.push(qx);
145
              newpoints.push(intery + qy);
146
              for (m = 2; m < ps; ++m) newpoints.push(points[i + m]);
147
              bottom = qy;
148
            }
149

150
            j += otherps;
151
          } else {
152
            // px < qx
153
            for (m = 0; m < ps; ++m) newpoints.push(points[i + m]);
154

155
            // we might be able to interpolate a point below,
156
            // this can give us a better y
157
            if (j > 0 && otherpoints[j - otherps] != null)
158
              bottom =
159
                qy +
160
                ((otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx)) /
161
                  (otherpoints[j - otherps + keyOffset] - qx);
162

163
            newpoints[l + accumulateOffset] += bottom;
164

165
            i += ps;
166
          }
167

168
          if (l != newpoints.length && withbottom) newpoints[l + 2] = bottom;
169
        }
170

171
        // maintain the line steps invariant
172
        if (
173
          withsteps &&
174
          l != newpoints.length &&
175
          l > 0 &&
176
          newpoints[l] != null &&
177
          newpoints[l] != newpoints[l - ps] &&
178
          newpoints[l + 1] != newpoints[l - ps + 1]
179
        ) {
180
          for (m = 0; m < ps; ++m) newpoints[l + ps + m] = newpoints[l + m];
181
          newpoints[l + 1] = newpoints[l - ps + 1];
182
        }
183
      }
184

185
      datapoints.points = newpoints;
186
    }
187

188
    plot.hooks.processDatapoints.push(stackData);
189
  }
190

191
  $.plot.plugins.push({
192
    init: init,
193
    options: options,
194
    name: 'stack',
195
    version: '1.2',
196
  });
197
})(window.jQuery);
198

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.