UNPKG

903 kBJavaScriptView Raw
1var __extends = (this && this.__extends) || function (d, b) {
2 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 function __() { this.constructor = d; }
4 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
5};
6/*
7 * Power BI Visualizations
8 *
9 * Copyright (c) Microsoft Corporation
10 * All rights reserved.
11 * MIT License
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this software and associated documentation files (the ""Software""), to deal
15 * in the Software without restriction, including without limitation the rights
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the Software is
18 * furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 * THE SOFTWARE.
30 */
31///<reference path="../../Typedefs/jquery/jquery.d.ts"/>
32///<reference path="../../Typedefs/globalize/globalize.d.ts"/>
33///<reference path="../../Typedefs/lodash/lodash.d.ts"/>
34/*
35 * Power BI Visualizations
36 *
37 * Copyright (c) Microsoft Corporation
38 * All rights reserved.
39 * MIT License
40 *
41 * Permission is hereby granted, free of charge, to any person obtaining a copy
42 * of this software and associated documentation files (the ""Software""), to deal
43 * in the Software without restriction, including without limitation the rights
44 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45 * copies of the Software, and to permit persons to whom the Software is
46 * furnished to do so, subject to the following conditions:
47 *
48 * The above copyright notice and this permission notice shall be included in
49 * all copies or substantial portions of the Software.
50 *
51 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
54 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57 * THE SOFTWARE.
58 */
59var powerbi;
60(function (powerbi) {
61 var data;
62 (function (data) {
63 /** Default IQueryExprVisitorWithArg implementation that others may derive from. */
64 var DefaultSQExprVisitorWithArg = (function () {
65 function DefaultSQExprVisitorWithArg() {
66 }
67 DefaultSQExprVisitorWithArg.prototype.visitEntity = function (expr, arg) {
68 return this.visitDefault(expr, arg);
69 };
70 DefaultSQExprVisitorWithArg.prototype.visitColumnRef = function (expr, arg) {
71 return this.visitDefault(expr, arg);
72 };
73 DefaultSQExprVisitorWithArg.prototype.visitMeasureRef = function (expr, arg) {
74 return this.visitDefault(expr, arg);
75 };
76 DefaultSQExprVisitorWithArg.prototype.visitAggr = function (expr, arg) {
77 return this.visitDefault(expr, arg);
78 };
79 DefaultSQExprVisitorWithArg.prototype.visitPercentile = function (expr, arg) {
80 return this.visitDefault(expr, arg);
81 };
82 DefaultSQExprVisitorWithArg.prototype.visitHierarchy = function (expr, arg) {
83 return this.visitDefault(expr, arg);
84 };
85 DefaultSQExprVisitorWithArg.prototype.visitHierarchyLevel = function (expr, arg) {
86 return this.visitDefault(expr, arg);
87 };
88 DefaultSQExprVisitorWithArg.prototype.visitPropertyVariationSource = function (expr, arg) {
89 return this.visitDefault(expr, arg);
90 };
91 DefaultSQExprVisitorWithArg.prototype.visitSelectRef = function (expr, arg) {
92 return this.visitDefault(expr, arg);
93 };
94 DefaultSQExprVisitorWithArg.prototype.visitBetween = function (expr, arg) {
95 return this.visitDefault(expr, arg);
96 };
97 DefaultSQExprVisitorWithArg.prototype.visitIn = function (expr, arg) {
98 return this.visitDefault(expr, arg);
99 };
100 DefaultSQExprVisitorWithArg.prototype.visitAnd = function (expr, arg) {
101 return this.visitDefault(expr, arg);
102 };
103 DefaultSQExprVisitorWithArg.prototype.visitOr = function (expr, arg) {
104 return this.visitDefault(expr, arg);
105 };
106 DefaultSQExprVisitorWithArg.prototype.visitCompare = function (expr, arg) {
107 return this.visitDefault(expr, arg);
108 };
109 DefaultSQExprVisitorWithArg.prototype.visitContains = function (expr, arg) {
110 return this.visitDefault(expr, arg);
111 };
112 DefaultSQExprVisitorWithArg.prototype.visitExists = function (expr, arg) {
113 return this.visitDefault(expr, arg);
114 };
115 DefaultSQExprVisitorWithArg.prototype.visitNot = function (expr, arg) {
116 return this.visitDefault(expr, arg);
117 };
118 DefaultSQExprVisitorWithArg.prototype.visitStartsWith = function (expr, arg) {
119 return this.visitDefault(expr, arg);
120 };
121 DefaultSQExprVisitorWithArg.prototype.visitConstant = function (expr, arg) {
122 return this.visitDefault(expr, arg);
123 };
124 DefaultSQExprVisitorWithArg.prototype.visitDateSpan = function (expr, arg) {
125 return this.visitDefault(expr, arg);
126 };
127 DefaultSQExprVisitorWithArg.prototype.visitDateAdd = function (expr, arg) {
128 return this.visitDefault(expr, arg);
129 };
130 DefaultSQExprVisitorWithArg.prototype.visitNow = function (expr, arg) {
131 return this.visitDefault(expr, arg);
132 };
133 DefaultSQExprVisitorWithArg.prototype.visitDefaultValue = function (expr, arg) {
134 return this.visitDefault(expr, arg);
135 };
136 DefaultSQExprVisitorWithArg.prototype.visitAnyValue = function (expr, arg) {
137 return this.visitDefault(expr, arg);
138 };
139 DefaultSQExprVisitorWithArg.prototype.visitArithmetic = function (expr, arg) {
140 return this.visitDefault(expr, arg);
141 };
142 DefaultSQExprVisitorWithArg.prototype.visitFillRule = function (expr, arg) {
143 return this.visitDefault(expr, arg);
144 };
145 DefaultSQExprVisitorWithArg.prototype.visitResourcePackageItem = function (expr, arg) {
146 return this.visitDefault(expr, arg);
147 };
148 DefaultSQExprVisitorWithArg.prototype.visitScopedEval = function (expr, arg) {
149 return this.visitDefault(expr, arg);
150 };
151 DefaultSQExprVisitorWithArg.prototype.visitDefault = function (expr, arg) {
152 return;
153 };
154 return DefaultSQExprVisitorWithArg;
155 }());
156 data.DefaultSQExprVisitorWithArg = DefaultSQExprVisitorWithArg;
157 /** Default ISQExprVisitor implementation that others may derive from. */
158 var DefaultSQExprVisitor = (function (_super) {
159 __extends(DefaultSQExprVisitor, _super);
160 function DefaultSQExprVisitor() {
161 _super.apply(this, arguments);
162 }
163 return DefaultSQExprVisitor;
164 }(DefaultSQExprVisitorWithArg));
165 data.DefaultSQExprVisitor = DefaultSQExprVisitor;
166 /** Default ISQExprVisitor implementation that implements default traversal and that others may derive from. */
167 var DefaultSQExprVisitorWithTraversal = (function () {
168 function DefaultSQExprVisitorWithTraversal() {
169 }
170 DefaultSQExprVisitorWithTraversal.prototype.visitEntity = function (expr) {
171 this.visitDefault(expr);
172 };
173 DefaultSQExprVisitorWithTraversal.prototype.visitColumnRef = function (expr) {
174 expr.source.accept(this);
175 };
176 DefaultSQExprVisitorWithTraversal.prototype.visitMeasureRef = function (expr) {
177 expr.source.accept(this);
178 };
179 DefaultSQExprVisitorWithTraversal.prototype.visitAggr = function (expr) {
180 expr.arg.accept(this);
181 };
182 DefaultSQExprVisitorWithTraversal.prototype.visitPercentile = function (expr) {
183 expr.arg.accept(this);
184 };
185 DefaultSQExprVisitorWithTraversal.prototype.visitHierarchy = function (expr) {
186 expr.arg.accept(this);
187 };
188 DefaultSQExprVisitorWithTraversal.prototype.visitHierarchyLevel = function (expr) {
189 expr.arg.accept(this);
190 };
191 DefaultSQExprVisitorWithTraversal.prototype.visitPropertyVariationSource = function (expr) {
192 expr.arg.accept(this);
193 };
194 DefaultSQExprVisitorWithTraversal.prototype.visitSelectRef = function (expr) {
195 this.visitDefault(expr);
196 };
197 DefaultSQExprVisitorWithTraversal.prototype.visitBetween = function (expr) {
198 expr.arg.accept(this);
199 expr.lower.accept(this);
200 expr.upper.accept(this);
201 };
202 DefaultSQExprVisitorWithTraversal.prototype.visitIn = function (expr) {
203 var args = expr.args;
204 for (var i = 0, len = args.length; i < len; i++)
205 args[i].accept(this);
206 var values = expr.values;
207 for (var i = 0, len = values.length; i < len; i++) {
208 var valueTuple = values[i];
209 for (var j = 0, jlen = valueTuple.length; j < jlen; j++)
210 valueTuple[j].accept(this);
211 }
212 };
213 DefaultSQExprVisitorWithTraversal.prototype.visitAnd = function (expr) {
214 expr.left.accept(this);
215 expr.right.accept(this);
216 };
217 DefaultSQExprVisitorWithTraversal.prototype.visitOr = function (expr) {
218 expr.left.accept(this);
219 expr.right.accept(this);
220 };
221 DefaultSQExprVisitorWithTraversal.prototype.visitCompare = function (expr) {
222 expr.left.accept(this);
223 expr.right.accept(this);
224 };
225 DefaultSQExprVisitorWithTraversal.prototype.visitContains = function (expr) {
226 expr.left.accept(this);
227 expr.right.accept(this);
228 };
229 DefaultSQExprVisitorWithTraversal.prototype.visitExists = function (expr) {
230 expr.arg.accept(this);
231 };
232 DefaultSQExprVisitorWithTraversal.prototype.visitNot = function (expr) {
233 expr.arg.accept(this);
234 };
235 DefaultSQExprVisitorWithTraversal.prototype.visitStartsWith = function (expr) {
236 expr.left.accept(this);
237 expr.right.accept(this);
238 };
239 DefaultSQExprVisitorWithTraversal.prototype.visitConstant = function (expr) {
240 this.visitDefault(expr);
241 };
242 DefaultSQExprVisitorWithTraversal.prototype.visitDateSpan = function (expr) {
243 expr.arg.accept(this);
244 };
245 DefaultSQExprVisitorWithTraversal.prototype.visitDateAdd = function (expr) {
246 expr.arg.accept(this);
247 };
248 DefaultSQExprVisitorWithTraversal.prototype.visitNow = function (expr) {
249 this.visitDefault(expr);
250 };
251 DefaultSQExprVisitorWithTraversal.prototype.visitDefaultValue = function (expr) {
252 this.visitDefault(expr);
253 };
254 DefaultSQExprVisitorWithTraversal.prototype.visitAnyValue = function (expr) {
255 this.visitDefault(expr);
256 };
257 DefaultSQExprVisitorWithTraversal.prototype.visitArithmetic = function (expr) {
258 expr.left.accept(this);
259 expr.right.accept(this);
260 };
261 DefaultSQExprVisitorWithTraversal.prototype.visitFillRule = function (expr) {
262 expr.input.accept(this);
263 var rule = expr.rule, gradient2 = rule.linearGradient2, gradient3 = rule.linearGradient3;
264 if (gradient2) {
265 this.visitLinearGradient2(gradient2);
266 }
267 if (gradient3) {
268 this.visitLinearGradient3(gradient3);
269 }
270 };
271 DefaultSQExprVisitorWithTraversal.prototype.visitLinearGradient2 = function (gradient2) {
272 debug.assertValue(gradient2, 'gradient2');
273 this.visitFillRuleStop(gradient2.min);
274 this.visitFillRuleStop(gradient2.max);
275 };
276 DefaultSQExprVisitorWithTraversal.prototype.visitLinearGradient3 = function (gradient3) {
277 debug.assertValue(gradient3, 'gradient3');
278 this.visitFillRuleStop(gradient3.min);
279 this.visitFillRuleStop(gradient3.mid);
280 this.visitFillRuleStop(gradient3.max);
281 };
282 DefaultSQExprVisitorWithTraversal.prototype.visitResourcePackageItem = function (expr) {
283 this.visitDefault(expr);
284 };
285 DefaultSQExprVisitorWithTraversal.prototype.visitScopedEval = function (expr) {
286 expr.expression.accept(this);
287 for (var _i = 0, _a = expr.scope; _i < _a.length; _i++) {
288 var scopeExpr = _a[_i];
289 scopeExpr.accept(this);
290 }
291 };
292 DefaultSQExprVisitorWithTraversal.prototype.visitDefault = function (expr) {
293 return;
294 };
295 DefaultSQExprVisitorWithTraversal.prototype.visitFillRuleStop = function (stop) {
296 debug.assertValue(stop, 'stop');
297 stop.color.accept(this);
298 var value = stop.value;
299 if (value)
300 value.accept(this);
301 };
302 return DefaultSQExprVisitorWithTraversal;
303 }());
304 data.DefaultSQExprVisitorWithTraversal = DefaultSQExprVisitorWithTraversal;
305 })(data = powerbi.data || (powerbi.data = {}));
306})(powerbi || (powerbi = {}));
307/*
308 * Power BI Visualizations
309 *
310 * Copyright (c) Microsoft Corporation
311 * All rights reserved.
312 * MIT License
313 *
314 * Permission is hereby granted, free of charge, to any person obtaining a copy
315 * of this software and associated documentation files (the ""Software""), to deal
316 * in the Software without restriction, including without limitation the rights
317 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
318 * copies of the Software, and to permit persons to whom the Software is
319 * furnished to do so, subject to the following conditions:
320 *
321 * The above copyright notice and this permission notice shall be included in
322 * all copies or substantial portions of the Software.
323 *
324 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
325 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
326 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
327 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
328 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
329 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
330 * THE SOFTWARE.
331 */
332var powerbi;
333(function (powerbi) {
334 function createEnumType(members) {
335 return new EnumType(members);
336 }
337 powerbi.createEnumType = createEnumType;
338 var EnumType = (function () {
339 function EnumType(allMembers) {
340 debug.assertValue(allMembers, 'allMembers');
341 this.allMembers = allMembers;
342 }
343 EnumType.prototype.members = function (validMembers) {
344 var allMembers = this.allMembers;
345 if (!validMembers)
346 return allMembers;
347 var membersToReturn = [];
348 for (var _i = 0, allMembers_1 = allMembers; _i < allMembers_1.length; _i++) {
349 var member = allMembers_1[_i];
350 if (_.contains(validMembers, member.value))
351 membersToReturn.push(member);
352 }
353 return membersToReturn;
354 };
355 return EnumType;
356 }());
357})(powerbi || (powerbi = {}));
358/*
359 * Power BI Visualizations
360 *
361 * Copyright (c) Microsoft Corporation
362 * All rights reserved.
363 * MIT License
364 *
365 * Permission is hereby granted, free of charge, to any person obtaining a copy
366 * of this software and associated documentation files (the ""Software""), to deal
367 * in the Software without restriction, including without limitation the rights
368 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
369 * copies of the Software, and to permit persons to whom the Software is
370 * furnished to do so, subject to the following conditions:
371 *
372 * The above copyright notice and this permission notice shall be included in
373 * all copies or substantial portions of the Software.
374 *
375 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
376 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
377 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
378 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
379 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
380 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
381 * THE SOFTWARE.
382 */
383var powerbi;
384(function (powerbi) {
385 var FillSolidColorTypeDescriptor;
386 (function (FillSolidColorTypeDescriptor) {
387 /** Gets a value indicating whether the descriptor is nullable or not. */
388 function nullable(descriptor) {
389 debug.assertValue(descriptor, 'descriptor');
390 if (descriptor === true)
391 return false;
392 var advancedDescriptor = descriptor;
393 return !!advancedDescriptor.nullable;
394 }
395 FillSolidColorTypeDescriptor.nullable = nullable;
396 })(FillSolidColorTypeDescriptor = powerbi.FillSolidColorTypeDescriptor || (powerbi.FillSolidColorTypeDescriptor = {}));
397})(powerbi || (powerbi = {}));
398/*
399 * Power BI Visualizations
400 *
401 * Copyright (c) Microsoft Corporation
402 * All rights reserved.
403 * MIT License
404 *
405 * Permission is hereby granted, free of charge, to any person obtaining a copy
406 * of this software and associated documentation files (the ""Software""), to deal
407 * in the Software without restriction, including without limitation the rights
408 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
409 * copies of the Software, and to permit persons to whom the Software is
410 * furnished to do so, subject to the following conditions:
411 *
412 * The above copyright notice and this permission notice shall be included in
413 * all copies or substantial portions of the Software.
414 *
415 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
416 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
417 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
418 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
419 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
420 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
421 * THE SOFTWARE.
422 */
423/*
424 * Power BI Visualizations
425 *
426 * Copyright (c) Microsoft Corporation
427 * All rights reserved.
428 * MIT License
429 *
430 * Permission is hereby granted, free of charge, to any person obtaining a copy
431 * of this software and associated documentation files (the ""Software""), to deal
432 * in the Software without restriction, including without limitation the rights
433 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
434 * copies of the Software, and to permit persons to whom the Software is
435 * furnished to do so, subject to the following conditions:
436 *
437 * The above copyright notice and this permission notice shall be included in
438 * all copies or substantial portions of the Software.
439 *
440 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
441 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
442 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
443 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
444 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
445 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
446 * THE SOFTWARE.
447 */
448var powerbi;
449(function (powerbi) {
450 var ImageDefinition;
451 (function (ImageDefinition) {
452 ImageDefinition.urlType = { misc: { imageUrl: true } };
453 })(ImageDefinition = powerbi.ImageDefinition || (powerbi.ImageDefinition = {}));
454})(powerbi || (powerbi = {}));
455/*
456 * Power BI Visualizations
457 *
458 * Copyright (c) Microsoft Corporation
459 * All rights reserved.
460 * MIT License
461 *
462 * Permission is hereby granted, free of charge, to any person obtaining a copy
463 * of this software and associated documentation files (the ""Software""), to deal
464 * in the Software without restriction, including without limitation the rights
465 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
466 * copies of the Software, and to permit persons to whom the Software is
467 * furnished to do so, subject to the following conditions:
468 *
469 * The above copyright notice and this permission notice shall be included in
470 * all copies or substantial portions of the Software.
471 *
472 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
473 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
474 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
475 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
476 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
477 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
478 * THE SOFTWARE.
479 */
480/*
481 * Power BI Visualizations
482 *
483 * Copyright (c) Microsoft Corporation
484 * All rights reserved.
485 * MIT License
486 *
487 * Permission is hereby granted, free of charge, to any person obtaining a copy
488 * of this software and associated documentation files (the ""Software""), to deal
489 * in the Software without restriction, including without limitation the rights
490 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
491 * copies of the Software, and to permit persons to whom the Software is
492 * furnished to do so, subject to the following conditions:
493 *
494 * The above copyright notice and this permission notice shall be included in
495 * all copies or substantial portions of the Software.
496 *
497 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
498 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
499 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
500 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
501 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
502 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
503 * THE SOFTWARE.
504 */
505var powerbi;
506(function (powerbi) {
507 var StructuralTypeDescriptor;
508 (function (StructuralTypeDescriptor) {
509 function isValid(type) {
510 debug.assertValue(type, 'type');
511 if (type.fill ||
512 type.fillRule ||
513 type.filter ||
514 type.expression ||
515 type.image ||
516 type.paragraphs) {
517 return true;
518 }
519 return false;
520 }
521 StructuralTypeDescriptor.isValid = isValid;
522 })(StructuralTypeDescriptor = powerbi.StructuralTypeDescriptor || (powerbi.StructuralTypeDescriptor = {}));
523})(powerbi || (powerbi = {}));
524/*
525 * Power BI Visualizations
526 *
527 * Copyright (c) Microsoft Corporation
528 * All rights reserved.
529 * MIT License
530 *
531 * Permission is hereby granted, free of charge, to any person obtaining a copy
532 * of this software and associated documentation files (the ""Software""), to deal
533 * in the Software without restriction, including without limitation the rights
534 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
535 * copies of the Software, and to permit persons to whom the Software is
536 * furnished to do so, subject to the following conditions:
537 *
538 * The above copyright notice and this permission notice shall be included in
539 * all copies or substantial portions of the Software.
540 *
541 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
542 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
543 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
544 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
545 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
546 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
547 * THE SOFTWARE.
548 */
549var powerbi;
550(function (powerbi) {
551 var EnumExtensions = jsCommon.EnumExtensions;
552 /** Describes a data value type, including a primitive type and extended type if any (derived from data category). */
553 var ValueType = (function () {
554 /** Do not call the ValueType constructor directly. Use the ValueType.fromXXX methods. */
555 function ValueType(type, category, enumType) {
556 debug.assert((!!type && ExtendedType[type] != null) || type === ExtendedType.Null, 'type');
557 debug.assert(!!category || category === null, 'category');
558 debug.assert(type !== ExtendedType.Enumeration || !!enumType, 'enumType');
559 this.underlyingType = type;
560 this.category = category;
561 if (EnumExtensions.hasFlag(type, ExtendedType.Temporal)) {
562 this.temporalType = new TemporalType(type);
563 }
564 if (EnumExtensions.hasFlag(type, ExtendedType.Geography)) {
565 this.geographyType = new GeographyType(type);
566 }
567 if (EnumExtensions.hasFlag(type, ExtendedType.Miscellaneous)) {
568 this.miscType = new MiscellaneousType(type);
569 }
570 if (EnumExtensions.hasFlag(type, ExtendedType.Formatting)) {
571 this.formattingType = new FormattingType(type);
572 }
573 if (EnumExtensions.hasFlag(type, ExtendedType.Enumeration)) {
574 this.enumType = enumType;
575 }
576 if (EnumExtensions.hasFlag(type, ExtendedType.Scripting)) {
577 this.scriptingType = new ScriptType(type);
578 }
579 }
580 /** Creates or retrieves a ValueType object based on the specified ValueTypeDescriptor. */
581 ValueType.fromDescriptor = function (descriptor) {
582 descriptor = descriptor || {};
583 // Simplified primitive types
584 if (descriptor.text)
585 return ValueType.fromExtendedType(ExtendedType.Text);
586 if (descriptor.integer)
587 return ValueType.fromExtendedType(ExtendedType.Integer);
588 if (descriptor.numeric)
589 return ValueType.fromExtendedType(ExtendedType.Double);
590 if (descriptor.bool)
591 return ValueType.fromExtendedType(ExtendedType.Boolean);
592 if (descriptor.dateTime)
593 return ValueType.fromExtendedType(ExtendedType.DateTime);
594 if (descriptor.duration)
595 return ValueType.fromExtendedType(ExtendedType.Duration);
596 if (descriptor.binary)
597 return ValueType.fromExtendedType(ExtendedType.Binary);
598 if (descriptor.none)
599 return ValueType.fromExtendedType(ExtendedType.None);
600 // Extended types
601 if (descriptor.scripting) {
602 if (descriptor.scripting.source)
603 return ValueType.fromExtendedType(ExtendedType.ScriptSource);
604 }
605 if (descriptor.enumeration)
606 return ValueType.fromEnum(descriptor.enumeration);
607 if (descriptor.temporal) {
608 if (descriptor.temporal.year)
609 return ValueType.fromExtendedType(ExtendedType.Year_Integer);
610 if (descriptor.temporal.month)
611 return ValueType.fromExtendedType(ExtendedType.Month_Integer);
612 }
613 if (descriptor.geography) {
614 if (descriptor.geography.address)
615 return ValueType.fromExtendedType(ExtendedType.Address);
616 if (descriptor.geography.city)
617 return ValueType.fromExtendedType(ExtendedType.City);
618 if (descriptor.geography.continent)
619 return ValueType.fromExtendedType(ExtendedType.Continent);
620 if (descriptor.geography.country)
621 return ValueType.fromExtendedType(ExtendedType.Country);
622 if (descriptor.geography.county)
623 return ValueType.fromExtendedType(ExtendedType.County);
624 if (descriptor.geography.region)
625 return ValueType.fromExtendedType(ExtendedType.Region);
626 if (descriptor.geography.postalCode)
627 return ValueType.fromExtendedType(ExtendedType.PostalCode_Text);
628 if (descriptor.geography.stateOrProvince)
629 return ValueType.fromExtendedType(ExtendedType.StateOrProvince);
630 if (descriptor.geography.place)
631 return ValueType.fromExtendedType(ExtendedType.Place);
632 if (descriptor.geography.latitude)
633 return ValueType.fromExtendedType(ExtendedType.Latitude_Double);
634 if (descriptor.geography.longitude)
635 return ValueType.fromExtendedType(ExtendedType.Longitude_Double);
636 }
637 if (descriptor.misc) {
638 if (descriptor.misc.image)
639 return ValueType.fromExtendedType(ExtendedType.Image);
640 if (descriptor.misc.imageUrl)
641 return ValueType.fromExtendedType(ExtendedType.ImageUrl);
642 if (descriptor.misc.webUrl)
643 return ValueType.fromExtendedType(ExtendedType.WebUrl);
644 if (descriptor.misc.barcode)
645 return ValueType.fromExtendedType(ExtendedType.Barcode_Text);
646 }
647 if (descriptor.formatting) {
648 if (descriptor.formatting.color)
649 return ValueType.fromExtendedType(ExtendedType.Color);
650 if (descriptor.formatting.formatString)
651 return ValueType.fromExtendedType(ExtendedType.FormatString);
652 if (descriptor.formatting.alignment)
653 return ValueType.fromExtendedType(ExtendedType.Alignment);
654 if (descriptor.formatting.labelDisplayUnits)
655 return ValueType.fromExtendedType(ExtendedType.LabelDisplayUnits);
656 if (descriptor.formatting.fontSize)
657 return ValueType.fromExtendedType(ExtendedType.FontSize);
658 if (descriptor.formatting.labelDensity)
659 return ValueType.fromExtendedType(ExtendedType.LabelDensity);
660 }
661 if (descriptor.extendedType) {
662 return ValueType.fromExtendedType(descriptor.extendedType);
663 }
664 return ValueType.fromExtendedType(ExtendedType.Null);
665 };
666 /** Advanced: Generally use fromDescriptor instead. Creates or retrieves a ValueType object for the specified ExtendedType. */
667 ValueType.fromExtendedType = function (extendedType) {
668 extendedType = extendedType || ExtendedType.Null;
669 var primitiveType = getPrimitiveType(extendedType), category = getCategoryFromExtendedType(extendedType);
670 debug.assert(primitiveType !== PrimitiveType.Null || extendedType === ExtendedType.Null, 'Cannot create ValueType for abstract extended type. Consider using fromDescriptor instead.');
671 return ValueType.fromPrimitiveTypeAndCategory(primitiveType, category);
672 };
673 /** Creates or retrieves a ValueType object for the specified PrimitiveType and data category. */
674 ValueType.fromPrimitiveTypeAndCategory = function (primitiveType, category) {
675 primitiveType = primitiveType || PrimitiveType.Null;
676 category = category || null;
677 var id = primitiveType.toString();
678 if (category)
679 id += '|' + category;
680 return ValueType.typeCache[id] || (ValueType.typeCache[id] = new ValueType(toExtendedType(primitiveType, category), category));
681 };
682 /** Creates a ValueType to describe the given IEnumType. */
683 ValueType.fromEnum = function (enumType) {
684 debug.assertValue(enumType, 'enumType');
685 return new ValueType(ExtendedType.Enumeration, null, enumType);
686 };
687 /** Determines if the specified type is compatible from at least one of the otherTypes. */
688 ValueType.isCompatibleTo = function (type, otherTypes) {
689 debug.assertValue(type, 'type');
690 debug.assertValue(otherTypes, 'otherTypes');
691 var valueType = ValueType.fromDescriptor(type);
692 for (var _i = 0, otherTypes_1 = otherTypes; _i < otherTypes_1.length; _i++) {
693 var otherType = otherTypes_1[_i];
694 var otherValueType = ValueType.fromDescriptor(otherType);
695 if (otherValueType.isCompatibleFrom(valueType))
696 return true;
697 }
698 return false;
699 };
700 /** Determines if the instance ValueType is convertable from the 'other' ValueType. */
701 ValueType.prototype.isCompatibleFrom = function (other) {
702 debug.assertValue(other, 'other');
703 var otherPrimitiveType = other.primitiveType;
704 if (this === other ||
705 this.primitiveType === otherPrimitiveType ||
706 otherPrimitiveType === PrimitiveType.Null)
707 return true;
708 return false;
709 };
710 /**
711 * Determines if the instance ValueType is equal to the 'other' ValueType
712 * @param {ValueType} other the other ValueType to check equality against
713 * @returns True if the instance ValueType is equal to the 'other' ValueType
714 */
715 ValueType.prototype.equals = function (other) {
716 return _.isEqual(this, other);
717 };
718 Object.defineProperty(ValueType.prototype, "primitiveType", {
719 /** Gets the exact primitive type of this ValueType. */
720 get: function () {
721 return getPrimitiveType(this.underlyingType);
722 },
723 enumerable: true,
724 configurable: true
725 });
726 Object.defineProperty(ValueType.prototype, "extendedType", {
727 /** Gets the exact extended type of this ValueType. */
728 get: function () {
729 return this.underlyingType;
730 },
731 enumerable: true,
732 configurable: true
733 });
734 Object.defineProperty(ValueType.prototype, "categoryString", {
735 /** Gets the data category string (if any) for this ValueType. */
736 get: function () {
737 return this.category;
738 },
739 enumerable: true,
740 configurable: true
741 });
742 Object.defineProperty(ValueType.prototype, "text", {
743 // Simplified primitive types
744 /** Indicates whether the type represents text values. */
745 get: function () {
746 return this.primitiveType === PrimitiveType.Text;
747 },
748 enumerable: true,
749 configurable: true
750 });
751 Object.defineProperty(ValueType.prototype, "numeric", {
752 /** Indicates whether the type represents any numeric value. */
753 get: function () {
754 return EnumExtensions.hasFlag(this.underlyingType, ExtendedType.Numeric);
755 },
756 enumerable: true,
757 configurable: true
758 });
759 Object.defineProperty(ValueType.prototype, "integer", {
760 /** Indicates whether the type represents integer numeric values. */
761 get: function () {
762 return this.primitiveType === PrimitiveType.Integer;
763 },
764 enumerable: true,
765 configurable: true
766 });
767 Object.defineProperty(ValueType.prototype, "bool", {
768 /** Indicates whether the type represents Boolean values. */
769 get: function () {
770 return this.primitiveType === PrimitiveType.Boolean;
771 },
772 enumerable: true,
773 configurable: true
774 });
775 Object.defineProperty(ValueType.prototype, "dateTime", {
776 /** Indicates whether the type represents any date/time values. */
777 get: function () {
778 return this.primitiveType === PrimitiveType.DateTime ||
779 this.primitiveType === PrimitiveType.Date ||
780 this.primitiveType === PrimitiveType.Time;
781 },
782 enumerable: true,
783 configurable: true
784 });
785 Object.defineProperty(ValueType.prototype, "duration", {
786 /** Indicates whether the type represents duration values. */
787 get: function () {
788 return this.primitiveType === PrimitiveType.Duration;
789 },
790 enumerable: true,
791 configurable: true
792 });
793 Object.defineProperty(ValueType.prototype, "binary", {
794 /** Indicates whether the type represents binary values. */
795 get: function () {
796 return this.primitiveType === PrimitiveType.Binary;
797 },
798 enumerable: true,
799 configurable: true
800 });
801 Object.defineProperty(ValueType.prototype, "none", {
802 /** Indicates whether the type represents none values. */
803 get: function () {
804 return this.primitiveType === PrimitiveType.None;
805 },
806 enumerable: true,
807 configurable: true
808 });
809 Object.defineProperty(ValueType.prototype, "temporal", {
810 // Extended types
811 /** Returns an object describing temporal values represented by the type, if it represents a temporal type. */
812 get: function () {
813 return this.temporalType;
814 },
815 enumerable: true,
816 configurable: true
817 });
818 Object.defineProperty(ValueType.prototype, "geography", {
819 /** Returns an object describing geographic values represented by the type, if it represents a geographic type. */
820 get: function () {
821 return this.geographyType;
822 },
823 enumerable: true,
824 configurable: true
825 });
826 Object.defineProperty(ValueType.prototype, "misc", {
827 /** Returns an object describing the specific values represented by the type, if it represents a miscellaneous extended type. */
828 get: function () {
829 return this.miscType;
830 },
831 enumerable: true,
832 configurable: true
833 });
834 Object.defineProperty(ValueType.prototype, "formatting", {
835 /** Returns an object describing the formatting values represented by the type, if it represents a formatting type. */
836 get: function () {
837 return this.formattingType;
838 },
839 enumerable: true,
840 configurable: true
841 });
842 Object.defineProperty(ValueType.prototype, "enum", {
843 /** Returns an object describing the enum values represented by the type, if it represents an enumeration type. */
844 get: function () {
845 return this.enumType;
846 },
847 enumerable: true,
848 configurable: true
849 });
850 Object.defineProperty(ValueType.prototype, "scripting", {
851 get: function () {
852 return this.scriptingType;
853 },
854 enumerable: true,
855 configurable: true
856 });
857 ValueType.typeCache = {};
858 return ValueType;
859 }());
860 powerbi.ValueType = ValueType;
861 var ScriptType = (function () {
862 function ScriptType(type) {
863 debug.assert(!!type && EnumExtensions.hasFlag(type, ExtendedType.Scripting), 'type');
864 this.underlyingType = type;
865 }
866 Object.defineProperty(ScriptType.prototype, "source", {
867 get: function () {
868 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.ScriptSource);
869 },
870 enumerable: true,
871 configurable: true
872 });
873 return ScriptType;
874 }());
875 powerbi.ScriptType = ScriptType;
876 var TemporalType = (function () {
877 function TemporalType(type) {
878 debug.assert(!!type && EnumExtensions.hasFlag(type, ExtendedType.Temporal), 'type');
879 this.underlyingType = type;
880 }
881 Object.defineProperty(TemporalType.prototype, "year", {
882 get: function () {
883 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Year);
884 },
885 enumerable: true,
886 configurable: true
887 });
888 Object.defineProperty(TemporalType.prototype, "month", {
889 get: function () {
890 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Month);
891 },
892 enumerable: true,
893 configurable: true
894 });
895 return TemporalType;
896 }());
897 powerbi.TemporalType = TemporalType;
898 var GeographyType = (function () {
899 function GeographyType(type) {
900 debug.assert(!!type && EnumExtensions.hasFlag(type, ExtendedType.Geography), 'type');
901 this.underlyingType = type;
902 }
903 Object.defineProperty(GeographyType.prototype, "address", {
904 get: function () {
905 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Address);
906 },
907 enumerable: true,
908 configurable: true
909 });
910 Object.defineProperty(GeographyType.prototype, "city", {
911 get: function () {
912 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.City);
913 },
914 enumerable: true,
915 configurable: true
916 });
917 Object.defineProperty(GeographyType.prototype, "continent", {
918 get: function () {
919 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Continent);
920 },
921 enumerable: true,
922 configurable: true
923 });
924 Object.defineProperty(GeographyType.prototype, "country", {
925 get: function () {
926 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Country);
927 },
928 enumerable: true,
929 configurable: true
930 });
931 Object.defineProperty(GeographyType.prototype, "county", {
932 get: function () {
933 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.County);
934 },
935 enumerable: true,
936 configurable: true
937 });
938 Object.defineProperty(GeographyType.prototype, "region", {
939 get: function () {
940 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Region);
941 },
942 enumerable: true,
943 configurable: true
944 });
945 Object.defineProperty(GeographyType.prototype, "postalCode", {
946 get: function () {
947 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.PostalCode);
948 },
949 enumerable: true,
950 configurable: true
951 });
952 Object.defineProperty(GeographyType.prototype, "stateOrProvince", {
953 get: function () {
954 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.StateOrProvince);
955 },
956 enumerable: true,
957 configurable: true
958 });
959 Object.defineProperty(GeographyType.prototype, "place", {
960 get: function () {
961 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Place);
962 },
963 enumerable: true,
964 configurable: true
965 });
966 Object.defineProperty(GeographyType.prototype, "latitude", {
967 get: function () {
968 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Latitude);
969 },
970 enumerable: true,
971 configurable: true
972 });
973 Object.defineProperty(GeographyType.prototype, "longitude", {
974 get: function () {
975 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Longitude);
976 },
977 enumerable: true,
978 configurable: true
979 });
980 return GeographyType;
981 }());
982 powerbi.GeographyType = GeographyType;
983 var MiscellaneousType = (function () {
984 function MiscellaneousType(type) {
985 debug.assert(!!type && EnumExtensions.hasFlag(type, ExtendedType.Miscellaneous), 'type');
986 this.underlyingType = type;
987 }
988 Object.defineProperty(MiscellaneousType.prototype, "image", {
989 get: function () {
990 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Image);
991 },
992 enumerable: true,
993 configurable: true
994 });
995 Object.defineProperty(MiscellaneousType.prototype, "imageUrl", {
996 get: function () {
997 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.ImageUrl);
998 },
999 enumerable: true,
1000 configurable: true
1001 });
1002 Object.defineProperty(MiscellaneousType.prototype, "webUrl", {
1003 get: function () {
1004 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.WebUrl);
1005 },
1006 enumerable: true,
1007 configurable: true
1008 });
1009 Object.defineProperty(MiscellaneousType.prototype, "barcode", {
1010 get: function () {
1011 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Barcode);
1012 },
1013 enumerable: true,
1014 configurable: true
1015 });
1016 return MiscellaneousType;
1017 }());
1018 powerbi.MiscellaneousType = MiscellaneousType;
1019 var FormattingType = (function () {
1020 function FormattingType(type) {
1021 debug.assert(!!type && EnumExtensions.hasFlag(type, ExtendedType.Formatting), 'type');
1022 this.underlyingType = type;
1023 }
1024 Object.defineProperty(FormattingType.prototype, "color", {
1025 get: function () {
1026 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Color);
1027 },
1028 enumerable: true,
1029 configurable: true
1030 });
1031 Object.defineProperty(FormattingType.prototype, "formatString", {
1032 get: function () {
1033 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.FormatString);
1034 },
1035 enumerable: true,
1036 configurable: true
1037 });
1038 Object.defineProperty(FormattingType.prototype, "alignment", {
1039 get: function () {
1040 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.Alignment);
1041 },
1042 enumerable: true,
1043 configurable: true
1044 });
1045 Object.defineProperty(FormattingType.prototype, "labelDisplayUnits", {
1046 get: function () {
1047 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.LabelDisplayUnits);
1048 },
1049 enumerable: true,
1050 configurable: true
1051 });
1052 Object.defineProperty(FormattingType.prototype, "fontSize", {
1053 get: function () {
1054 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.FontSize);
1055 },
1056 enumerable: true,
1057 configurable: true
1058 });
1059 Object.defineProperty(FormattingType.prototype, "labelDensity", {
1060 get: function () {
1061 return matchesExtendedTypeWithAnyPrimitive(this.underlyingType, ExtendedType.LabelDensity);
1062 },
1063 enumerable: true,
1064 configurable: true
1065 });
1066 return FormattingType;
1067 }());
1068 powerbi.FormattingType = FormattingType;
1069 /** Defines primitive value types. Must be consistent with types defined by server conceptual schema. */
1070 (function (PrimitiveType) {
1071 PrimitiveType[PrimitiveType["Null"] = 0] = "Null";
1072 PrimitiveType[PrimitiveType["Text"] = 1] = "Text";
1073 PrimitiveType[PrimitiveType["Decimal"] = 2] = "Decimal";
1074 PrimitiveType[PrimitiveType["Double"] = 3] = "Double";
1075 PrimitiveType[PrimitiveType["Integer"] = 4] = "Integer";
1076 PrimitiveType[PrimitiveType["Boolean"] = 5] = "Boolean";
1077 PrimitiveType[PrimitiveType["Date"] = 6] = "Date";
1078 PrimitiveType[PrimitiveType["DateTime"] = 7] = "DateTime";
1079 PrimitiveType[PrimitiveType["DateTimeZone"] = 8] = "DateTimeZone";
1080 PrimitiveType[PrimitiveType["Time"] = 9] = "Time";
1081 PrimitiveType[PrimitiveType["Duration"] = 10] = "Duration";
1082 PrimitiveType[PrimitiveType["Binary"] = 11] = "Binary";
1083 PrimitiveType[PrimitiveType["None"] = 12] = "None";
1084 })(powerbi.PrimitiveType || (powerbi.PrimitiveType = {}));
1085 var PrimitiveType = powerbi.PrimitiveType;
1086 /** Defines extended value types, which include primitive types and known data categories constrained to expected primitive types. */
1087 (function (ExtendedType) {
1088 // Flags (1 << 8-15 range [0xFF00])
1089 // Important: Enum members must be declared before they are used in TypeScript.
1090 ExtendedType[ExtendedType["Numeric"] = 256] = "Numeric";
1091 ExtendedType[ExtendedType["Temporal"] = 512] = "Temporal";
1092 ExtendedType[ExtendedType["Geography"] = 1024] = "Geography";
1093 ExtendedType[ExtendedType["Miscellaneous"] = 2048] = "Miscellaneous";
1094 ExtendedType[ExtendedType["Formatting"] = 4096] = "Formatting";
1095 ExtendedType[ExtendedType["Scripting"] = 8192] = "Scripting";
1096 // Primitive types (0-255 range [0xFF] | flags)
1097 // The member names and base values must match those in PrimitiveType.
1098 ExtendedType[ExtendedType["Null"] = 0] = "Null";
1099 ExtendedType[ExtendedType["Text"] = 1] = "Text";
1100 ExtendedType[ExtendedType["Decimal"] = 258] = "Decimal";
1101 ExtendedType[ExtendedType["Double"] = 259] = "Double";
1102 ExtendedType[ExtendedType["Integer"] = 260] = "Integer";
1103 ExtendedType[ExtendedType["Boolean"] = 5] = "Boolean";
1104 ExtendedType[ExtendedType["Date"] = 518] = "Date";
1105 ExtendedType[ExtendedType["DateTime"] = 519] = "DateTime";
1106 ExtendedType[ExtendedType["DateTimeZone"] = 520] = "DateTimeZone";
1107 ExtendedType[ExtendedType["Time"] = 521] = "Time";
1108 ExtendedType[ExtendedType["Duration"] = 10] = "Duration";
1109 ExtendedType[ExtendedType["Binary"] = 11] = "Binary";
1110 ExtendedType[ExtendedType["None"] = 12] = "None";
1111 // Extended types (0-32767 << 16 range [0xFFFF0000] | corresponding primitive type | flags)
1112 // Temporal
1113 ExtendedType[ExtendedType["Year"] = 66048] = "Year";
1114 ExtendedType[ExtendedType["Year_Text"] = 66049] = "Year_Text";
1115 ExtendedType[ExtendedType["Year_Integer"] = 66308] = "Year_Integer";
1116 ExtendedType[ExtendedType["Year_Date"] = 66054] = "Year_Date";
1117 ExtendedType[ExtendedType["Year_DateTime"] = 66055] = "Year_DateTime";
1118 ExtendedType[ExtendedType["Month"] = 131584] = "Month";
1119 ExtendedType[ExtendedType["Month_Text"] = 131585] = "Month_Text";
1120 ExtendedType[ExtendedType["Month_Integer"] = 131844] = "Month_Integer";
1121 ExtendedType[ExtendedType["Month_Date"] = 131590] = "Month_Date";
1122 ExtendedType[ExtendedType["Month_DateTime"] = 131591] = "Month_DateTime";
1123 // Geography
1124 ExtendedType[ExtendedType["Address"] = 6554625] = "Address";
1125 ExtendedType[ExtendedType["City"] = 6620161] = "City";
1126 ExtendedType[ExtendedType["Continent"] = 6685697] = "Continent";
1127 ExtendedType[ExtendedType["Country"] = 6751233] = "Country";
1128 ExtendedType[ExtendedType["County"] = 6816769] = "County";
1129 ExtendedType[ExtendedType["Region"] = 6882305] = "Region";
1130 ExtendedType[ExtendedType["PostalCode"] = 6947840] = "PostalCode";
1131 ExtendedType[ExtendedType["PostalCode_Text"] = 6947841] = "PostalCode_Text";
1132 ExtendedType[ExtendedType["PostalCode_Integer"] = 6948100] = "PostalCode_Integer";
1133 ExtendedType[ExtendedType["StateOrProvince"] = 7013377] = "StateOrProvince";
1134 ExtendedType[ExtendedType["Place"] = 7078913] = "Place";
1135 ExtendedType[ExtendedType["Latitude"] = 7144448] = "Latitude";
1136 ExtendedType[ExtendedType["Latitude_Decimal"] = 7144706] = "Latitude_Decimal";
1137 ExtendedType[ExtendedType["Latitude_Double"] = 7144707] = "Latitude_Double";
1138 ExtendedType[ExtendedType["Longitude"] = 7209984] = "Longitude";
1139 ExtendedType[ExtendedType["Longitude_Decimal"] = 7210242] = "Longitude_Decimal";
1140 ExtendedType[ExtendedType["Longitude_Double"] = 7210243] = "Longitude_Double";
1141 // Miscellaneous
1142 ExtendedType[ExtendedType["Image"] = 13109259] = "Image";
1143 ExtendedType[ExtendedType["ImageUrl"] = 13174785] = "ImageUrl";
1144 ExtendedType[ExtendedType["WebUrl"] = 13240321] = "WebUrl";
1145 ExtendedType[ExtendedType["Barcode"] = 13305856] = "Barcode";
1146 ExtendedType[ExtendedType["Barcode_Text"] = 13305857] = "Barcode_Text";
1147 ExtendedType[ExtendedType["Barcode_Integer"] = 13306116] = "Barcode_Integer";
1148 // Formatting
1149 ExtendedType[ExtendedType["Color"] = 19664897] = "Color";
1150 ExtendedType[ExtendedType["FormatString"] = 19730433] = "FormatString";
1151 ExtendedType[ExtendedType["Alignment"] = 20058113] = "Alignment";
1152 ExtendedType[ExtendedType["LabelDisplayUnits"] = 20123649] = "LabelDisplayUnits";
1153 ExtendedType[ExtendedType["FontSize"] = 20189443] = "FontSize";
1154 ExtendedType[ExtendedType["LabelDensity"] = 20254979] = "LabelDensity";
1155 // Enumeration
1156 ExtendedType[ExtendedType["Enumeration"] = 26214401] = "Enumeration";
1157 // Scripting
1158 ExtendedType[ExtendedType["ScriptSource"] = 32776193] = "ScriptSource";
1159 })(powerbi.ExtendedType || (powerbi.ExtendedType = {}));
1160 var ExtendedType = powerbi.ExtendedType;
1161 var PrimitiveTypeMask = 0xFF;
1162 var PrimitiveTypeWithFlagsMask = 0xFFFF;
1163 var PrimitiveTypeFlagsExcludedMask = 0xFFFF0000;
1164 function getPrimitiveType(extendedType) {
1165 return extendedType & PrimitiveTypeMask;
1166 }
1167 function isPrimitiveType(extendedType) {
1168 return (extendedType & PrimitiveTypeWithFlagsMask) === extendedType;
1169 }
1170 function getCategoryFromExtendedType(extendedType) {
1171 if (isPrimitiveType(extendedType))
1172 return null;
1173 var category = ExtendedType[extendedType];
1174 if (category) {
1175 // Check for ExtendedType declaration without a primitive type.
1176 // If exists, use it as category (e.g. Longitude rather than Longitude_Double)
1177 // Otherwise use the ExtendedType declaration with a primitive type (e.g. Address)
1178 var delimIdx = category.lastIndexOf('_');
1179 if (delimIdx > 0) {
1180 var baseCategory = category.slice(0, delimIdx);
1181 if (ExtendedType[baseCategory]) {
1182 debug.assert((ExtendedType[baseCategory] & PrimitiveTypeFlagsExcludedMask) === (extendedType & PrimitiveTypeFlagsExcludedMask), 'Unexpected value for ExtendedType base member of ' + extendedType);
1183 category = baseCategory;
1184 }
1185 }
1186 }
1187 return category || null;
1188 }
1189 function toExtendedType(primitiveType, category) {
1190 var primitiveString = PrimitiveType[primitiveType];
1191 var t = ExtendedType[primitiveString];
1192 if (t == null) {
1193 debug.assertFail('Unexpected primitiveType ' + primitiveType);
1194 t = ExtendedType.Null;
1195 }
1196 if (primitiveType && category) {
1197 var categoryType = ExtendedType[category];
1198 if (categoryType) {
1199 var categoryPrimitiveType = getPrimitiveType(categoryType);
1200 if (categoryPrimitiveType === PrimitiveType.Null) {
1201 // Category supports multiple primitive types, check if requested primitive type is supported
1202 // (note: important to use t here rather than primitiveType as it may include primitive type flags)
1203 categoryType = t | categoryType;
1204 if (ExtendedType[categoryType]) {
1205 debug.assert(ExtendedType[categoryType] === (category + '_' + primitiveString), 'Unexpected name for ExtendedType member ' + categoryType);
1206 t = categoryType;
1207 }
1208 }
1209 else if (categoryPrimitiveType === primitiveType) {
1210 // Primitive type matches the single supported type for the category
1211 t = categoryType;
1212 }
1213 }
1214 }
1215 return t;
1216 }
1217 function matchesExtendedTypeWithAnyPrimitive(a, b) {
1218 return (a & PrimitiveTypeFlagsExcludedMask) === (b & PrimitiveTypeFlagsExcludedMask);
1219 }
1220})(powerbi || (powerbi = {}));
1221/*
1222 * Power BI Visualizations
1223 *
1224 * Copyright (c) Microsoft Corporation
1225 * All rights reserved.
1226 * MIT License
1227 *
1228 * Permission is hereby granted, free of charge, to any person obtaining a copy
1229 * of this software and associated documentation files (the ""Software""), to deal
1230 * in the Software without restriction, including without limitation the rights
1231 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1232 * copies of the Software, and to permit persons to whom the Software is
1233 * furnished to do so, subject to the following conditions:
1234 *
1235 * The above copyright notice and this permission notice shall be included in
1236 * all copies or substantial portions of the Software.
1237 *
1238 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1239 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1240 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1241 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1242 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1243 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1244 * THE SOFTWARE.
1245 */
1246var powerbi;
1247(function (powerbi) {
1248 var data;
1249 (function (data) {
1250 (function (DataShapeBindingLimitType) {
1251 DataShapeBindingLimitType[DataShapeBindingLimitType["Top"] = 0] = "Top";
1252 DataShapeBindingLimitType[DataShapeBindingLimitType["First"] = 1] = "First";
1253 DataShapeBindingLimitType[DataShapeBindingLimitType["Last"] = 2] = "Last";
1254 DataShapeBindingLimitType[DataShapeBindingLimitType["Sample"] = 3] = "Sample";
1255 DataShapeBindingLimitType[DataShapeBindingLimitType["Bottom"] = 4] = "Bottom";
1256 })(data.DataShapeBindingLimitType || (data.DataShapeBindingLimitType = {}));
1257 var DataShapeBindingLimitType = data.DataShapeBindingLimitType;
1258 (function (SubtotalType) {
1259 SubtotalType[SubtotalType["None"] = 0] = "None";
1260 SubtotalType[SubtotalType["Before"] = 1] = "Before";
1261 SubtotalType[SubtotalType["After"] = 2] = "After";
1262 })(data.SubtotalType || (data.SubtotalType = {}));
1263 var SubtotalType = data.SubtotalType;
1264 })(data = powerbi.data || (powerbi.data = {}));
1265})(powerbi || (powerbi = {}));
1266/*
1267 * Power BI Visualizations
1268 *
1269 * Copyright (c) Microsoft Corporation
1270 * All rights reserved.
1271 * MIT License
1272 *
1273 * Permission is hereby granted, free of charge, to any person obtaining a copy
1274 * of this software and associated documentation files (the ""Software""), to deal
1275 * in the Software without restriction, including without limitation the rights
1276 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1277 * copies of the Software, and to permit persons to whom the Software is
1278 * furnished to do so, subject to the following conditions:
1279 *
1280 * The above copyright notice and this permission notice shall be included in
1281 * all copies or substantial portions of the Software.
1282 *
1283 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1284 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1285 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1286 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1287 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1288 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1289 * THE SOFTWARE.
1290 */
1291var powerbi;
1292(function (powerbi) {
1293 var data;
1294 (function (data) {
1295 var DataShapeBindingDataReduction;
1296 (function (DataShapeBindingDataReduction) {
1297 function createFrom(reduction) {
1298 if (!reduction)
1299 return;
1300 var result;
1301 if (reduction.top) {
1302 result = {
1303 Top: {}
1304 };
1305 if (reduction.top.count)
1306 result.Top.Count = reduction.top.count;
1307 }
1308 if (reduction.bottom) {
1309 result = {
1310 Bottom: {}
1311 };
1312 if (reduction.bottom.count)
1313 result.Bottom.Count = reduction.bottom.count;
1314 }
1315 if (reduction.sample) {
1316 result = {
1317 Sample: {}
1318 };
1319 if (reduction.sample.count)
1320 result.Sample.Count = reduction.sample.count;
1321 }
1322 if (reduction.window) {
1323 result = {
1324 Window: {}
1325 };
1326 if (reduction.window.count)
1327 result.Window.Count = reduction.window.count;
1328 }
1329 return result;
1330 }
1331 DataShapeBindingDataReduction.createFrom = createFrom;
1332 })(DataShapeBindingDataReduction = data.DataShapeBindingDataReduction || (data.DataShapeBindingDataReduction = {}));
1333 })(data = powerbi.data || (powerbi.data = {}));
1334})(powerbi || (powerbi = {}));
1335/*
1336 * Power BI Visualizations
1337 *
1338 * Copyright (c) Microsoft Corporation
1339 * All rights reserved.
1340 * MIT License
1341 *
1342 * Permission is hereby granted, free of charge, to any person obtaining a copy
1343 * of this software and associated documentation files (the ""Software""), to deal
1344 * in the Software without restriction, including without limitation the rights
1345 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1346 * copies of the Software, and to permit persons to whom the Software is
1347 * furnished to do so, subject to the following conditions:
1348 *
1349 * The above copyright notice and this permission notice shall be included in
1350 * all copies or substantial portions of the Software.
1351 *
1352 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1353 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1354 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1355 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1356 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1357 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1358 * THE SOFTWARE.
1359 */
1360var powerbi;
1361(function (powerbi) {
1362 var data;
1363 (function (data) {
1364 /** Represents a federated conceptual schema. */
1365 var FederatedConceptualSchema = (function () {
1366 function FederatedConceptualSchema(options) {
1367 debug.assertValue(options, 'options');
1368 this.schemas = options.schemas;
1369 if (options.links)
1370 this.links = options.links;
1371 }
1372 FederatedConceptualSchema.prototype.schema = function (name) {
1373 return this.schemas[name];
1374 };
1375 return FederatedConceptualSchema;
1376 }());
1377 data.FederatedConceptualSchema = FederatedConceptualSchema;
1378 })(data = powerbi.data || (powerbi.data = {}));
1379})(powerbi || (powerbi = {}));
1380/*
1381 * Power BI Visualizations
1382 *
1383 * Copyright (c) Microsoft Corporation
1384 * All rights reserved.
1385 * MIT License
1386 *
1387 * Permission is hereby granted, free of charge, to any person obtaining a copy
1388 * of this software and associated documentation files (the ""Software""), to deal
1389 * in the Software without restriction, including without limitation the rights
1390 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1391 * copies of the Software, and to permit persons to whom the Software is
1392 * furnished to do so, subject to the following conditions:
1393 *
1394 * The above copyright notice and this permission notice shall be included in
1395 * all copies or substantial portions of the Software.
1396 *
1397 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1398 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1399 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1400 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1401 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1402 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1403 * THE SOFTWARE.
1404 */
1405var powerbi;
1406(function (powerbi) {
1407 var data;
1408 (function (data_1) {
1409 var Selector;
1410 (function (Selector) {
1411 function filterFromSelector(selectors, isNot) {
1412 if (_.isEmpty(selectors))
1413 return;
1414 var exprs = [];
1415 for (var i = 0, ilen = selectors.length; i < ilen; i++) {
1416 var identity = selectors[i];
1417 var data_2 = identity.data;
1418 var exprToAdd = undefined;
1419 if (data_2 && data_2.length) {
1420 for (var j = 0, jlen = data_2.length; j < jlen; j++) {
1421 exprToAdd = data_1.SQExprBuilder.and(exprToAdd, identity.data[j].expr);
1422 }
1423 }
1424 if (exprToAdd)
1425 exprs.push(exprToAdd);
1426 }
1427 if (!_.isEmpty(exprs))
1428 return powerbi.DataViewScopeIdentity.filterFromExprs(exprs, isNot);
1429 }
1430 Selector.filterFromSelector = filterFromSelector;
1431 function matchesData(selector, identities) {
1432 debug.assertValue(selector, 'selector');
1433 debug.assertValue(selector.data, 'selector.data');
1434 debug.assertValue(identities, 'identities');
1435 var selectorData = selector.data;
1436 if (selectorData.length !== identities.length)
1437 return false;
1438 for (var i = 0, len = selectorData.length; i < len; i++) {
1439 var dataItem = selector.data[i];
1440 var selectorDataItem = dataItem;
1441 if (selectorDataItem.expr) {
1442 if (!powerbi.DataViewScopeIdentity.equals(selectorDataItem, identities[i]))
1443 return false;
1444 }
1445 else {
1446 if (!data_1.DataViewScopeWildcard.matches(dataItem, identities[i]))
1447 return false;
1448 }
1449 }
1450 return true;
1451 }
1452 Selector.matchesData = matchesData;
1453 function matchesKeys(selector, keysList) {
1454 debug.assertValue(selector, 'selector');
1455 debug.assertValue(selector.data, 'selector.data');
1456 debug.assertValue(keysList, 'keysList');
1457 var selectorData = selector.data, selectorDataLength = selectorData.length;
1458 if (selectorDataLength !== keysList.length)
1459 return false;
1460 for (var i = 0; i < selectorDataLength; i++) {
1461 var selectorDataItem = selector.data[i], selectorDataExprs = void 0;
1462 if (selectorDataItem.expr) {
1463 selectorDataExprs = data_1.ScopeIdentityExtractor.getKeys(selectorDataItem.expr);
1464 }
1465 else if (selectorDataItem.exprs) {
1466 selectorDataExprs = selectorDataItem.exprs;
1467 }
1468 else {
1469 // In case DataViewRoleWildcard
1470 return false;
1471 }
1472 if (!selectorDataExprs)
1473 continue;
1474 if (!data_1.SQExprUtils.sequenceEqual(keysList[i], selectorDataExprs))
1475 return false;
1476 }
1477 return true;
1478 }
1479 Selector.matchesKeys = matchesKeys;
1480 /** Determines whether two selectors are equal. */
1481 function equals(x, y) {
1482 // Normalize falsy to null
1483 x = x || null;
1484 y = y || null;
1485 if (x === y)
1486 return true;
1487 if (!x !== !y)
1488 return false;
1489 debug.assertValue(x, 'x');
1490 debug.assertValue(y, 'y');
1491 if (x.id !== y.id)
1492 return false;
1493 if (x.metadata !== y.metadata)
1494 return false;
1495 if (!equalsDataArray(x.data, y.data))
1496 return false;
1497 return true;
1498 }
1499 Selector.equals = equals;
1500 function equalsDataArray(x, y) {
1501 // Normalize falsy to null
1502 x = x || null;
1503 y = y || null;
1504 if (x === y)
1505 return true;
1506 if (!x !== !y)
1507 return false;
1508 if (x.length !== y.length)
1509 return false;
1510 for (var i = 0, len = x.length; i < len; i++) {
1511 if (!equalsData(x[i], y[i]))
1512 return false;
1513 }
1514 return true;
1515 }
1516 function equalsData(x, y) {
1517 var selector1 = x;
1518 var selector2 = y;
1519 if (selector1.expr && selector2.expr)
1520 return powerbi.DataViewScopeIdentity.equals(selector1, selector2);
1521 if (selector1.exprs && selector2.exprs)
1522 return data_1.DataViewScopeWildcard.equals(selector1, selector2);
1523 if (selector1.roles && selector2.roles)
1524 return data_1.DataViewRoleWildcard.equals(selector1, selector2);
1525 return false;
1526 }
1527 function getKey(selector) {
1528 var toStringify = {};
1529 if (selector.data) {
1530 var data_3 = [];
1531 for (var i = 0, ilen = selector.data.length; i < ilen; i++) {
1532 data_3.push(selector.data[i].key);
1533 }
1534 toStringify.data = data_3;
1535 }
1536 if (selector.metadata)
1537 toStringify.metadata = selector.metadata;
1538 if (selector.id)
1539 toStringify.id = selector.id;
1540 return JSON.stringify(toStringify);
1541 }
1542 Selector.getKey = getKey;
1543 function containsWildcard(selector) {
1544 debug.assertValue(selector, 'selector');
1545 var dataItems = selector.data;
1546 if (!dataItems)
1547 return false;
1548 for (var _i = 0, dataItems_1 = dataItems; _i < dataItems_1.length; _i++) {
1549 var dataItem = dataItems_1[_i];
1550 var wildCard = dataItem;
1551 if (wildCard.exprs || wildCard.roles)
1552 return true;
1553 }
1554 return false;
1555 }
1556 Selector.containsWildcard = containsWildcard;
1557 function hasRoleWildcard(selector) {
1558 debug.assertValue(selector, 'selector');
1559 var dataItems = selector.data;
1560 if (_.isEmpty(dataItems))
1561 return false;
1562 for (var _i = 0, dataItems_2 = dataItems; _i < dataItems_2.length; _i++) {
1563 var dataItem = dataItems_2[_i];
1564 if (isRoleWildcard(dataItem))
1565 return true;
1566 }
1567 return false;
1568 }
1569 Selector.hasRoleWildcard = hasRoleWildcard;
1570 function isRoleWildcard(dataItem) {
1571 return !_.isEmpty(dataItem.roles);
1572 }
1573 Selector.isRoleWildcard = isRoleWildcard;
1574 })(Selector = data_1.Selector || (data_1.Selector = {}));
1575 })(data = powerbi.data || (powerbi.data = {}));
1576})(powerbi || (powerbi = {}));
1577/*
1578 * Power BI Visualizations
1579 *
1580 * Copyright (c) Microsoft Corporation
1581 * All rights reserved.
1582 * MIT License
1583 *
1584 * Permission is hereby granted, free of charge, to any person obtaining a copy
1585 * of this software and associated documentation files (the ""Software""), to deal
1586 * in the Software without restriction, including without limitation the rights
1587 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1588 * copies of the Software, and to permit persons to whom the Software is
1589 * furnished to do so, subject to the following conditions:
1590 *
1591 * The above copyright notice and this permission notice shall be included in
1592 * all copies or substantial portions of the Software.
1593 *
1594 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1595 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1596 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1597 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1598 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1599 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1600 * THE SOFTWARE.
1601 */
1602var powerbi;
1603(function (powerbi) {
1604 var data;
1605 (function (data) {
1606 (function (EntitySourceType) {
1607 EntitySourceType[EntitySourceType["Table"] = 0] = "Table";
1608 EntitySourceType[EntitySourceType["Pod"] = 1] = "Pod";
1609 })(data.EntitySourceType || (data.EntitySourceType = {}));
1610 var EntitySourceType = data.EntitySourceType;
1611 function getArithmeticOperatorName(arithmeticOperatorKind) {
1612 switch (arithmeticOperatorKind) {
1613 case 0 /* Add */:
1614 return "Add";
1615 case 1 /* Subtract */:
1616 return "Subtract";
1617 case 2 /* Multiply */:
1618 return "Multiply";
1619 case 3 /* Divide */:
1620 return "Divide";
1621 }
1622 throw new Error('Unexpected ArithmeticOperatorKind: ' + arithmeticOperatorKind);
1623 }
1624 data.getArithmeticOperatorName = getArithmeticOperatorName;
1625 (function (TimeUnit) {
1626 TimeUnit[TimeUnit["Day"] = 0] = "Day";
1627 TimeUnit[TimeUnit["Week"] = 1] = "Week";
1628 TimeUnit[TimeUnit["Month"] = 2] = "Month";
1629 TimeUnit[TimeUnit["Year"] = 3] = "Year";
1630 TimeUnit[TimeUnit["Decade"] = 4] = "Decade";
1631 TimeUnit[TimeUnit["Second"] = 5] = "Second";
1632 TimeUnit[TimeUnit["Minute"] = 6] = "Minute";
1633 TimeUnit[TimeUnit["Hour"] = 7] = "Hour";
1634 })(data.TimeUnit || (data.TimeUnit = {}));
1635 var TimeUnit = data.TimeUnit;
1636 (function (QueryAggregateFunction) {
1637 QueryAggregateFunction[QueryAggregateFunction["Sum"] = 0] = "Sum";
1638 QueryAggregateFunction[QueryAggregateFunction["Avg"] = 1] = "Avg";
1639 QueryAggregateFunction[QueryAggregateFunction["Count"] = 2] = "Count";
1640 QueryAggregateFunction[QueryAggregateFunction["Min"] = 3] = "Min";
1641 QueryAggregateFunction[QueryAggregateFunction["Max"] = 4] = "Max";
1642 QueryAggregateFunction[QueryAggregateFunction["CountNonNull"] = 5] = "CountNonNull";
1643 QueryAggregateFunction[QueryAggregateFunction["Median"] = 6] = "Median";
1644 QueryAggregateFunction[QueryAggregateFunction["StandardDeviation"] = 7] = "StandardDeviation";
1645 QueryAggregateFunction[QueryAggregateFunction["Variance"] = 8] = "Variance";
1646 })(data.QueryAggregateFunction || (data.QueryAggregateFunction = {}));
1647 var QueryAggregateFunction = data.QueryAggregateFunction;
1648 (function (QueryComparisonKind) {
1649 QueryComparisonKind[QueryComparisonKind["Equal"] = 0] = "Equal";
1650 QueryComparisonKind[QueryComparisonKind["GreaterThan"] = 1] = "GreaterThan";
1651 QueryComparisonKind[QueryComparisonKind["GreaterThanOrEqual"] = 2] = "GreaterThanOrEqual";
1652 QueryComparisonKind[QueryComparisonKind["LessThan"] = 3] = "LessThan";
1653 QueryComparisonKind[QueryComparisonKind["LessThanOrEqual"] = 4] = "LessThanOrEqual";
1654 })(data.QueryComparisonKind || (data.QueryComparisonKind = {}));
1655 var QueryComparisonKind = data.QueryComparisonKind;
1656 /** Defines semantic data types. */
1657 (function (SemanticType) {
1658 SemanticType[SemanticType["None"] = 0] = "None";
1659 SemanticType[SemanticType["Number"] = 1] = "Number";
1660 SemanticType[SemanticType["Integer"] = 3] = "Integer";
1661 SemanticType[SemanticType["DateTime"] = 4] = "DateTime";
1662 SemanticType[SemanticType["Time"] = 8] = "Time";
1663 SemanticType[SemanticType["Date"] = 20] = "Date";
1664 SemanticType[SemanticType["Month"] = 35] = "Month";
1665 SemanticType[SemanticType["Year"] = 67] = "Year";
1666 SemanticType[SemanticType["YearAndMonth"] = 128] = "YearAndMonth";
1667 SemanticType[SemanticType["MonthAndDay"] = 256] = "MonthAndDay";
1668 SemanticType[SemanticType["Decade"] = 515] = "Decade";
1669 SemanticType[SemanticType["YearAndWeek"] = 1024] = "YearAndWeek";
1670 SemanticType[SemanticType["String"] = 2048] = "String";
1671 SemanticType[SemanticType["Boolean"] = 4096] = "Boolean";
1672 SemanticType[SemanticType["Table"] = 8192] = "Table";
1673 SemanticType[SemanticType["Range"] = 16384] = "Range";
1674 })(data.SemanticType || (data.SemanticType = {}));
1675 var SemanticType = data.SemanticType;
1676 (function (FilterKind) {
1677 FilterKind[FilterKind["Default"] = 0] = "Default";
1678 FilterKind[FilterKind["Period"] = 1] = "Period";
1679 })(data.FilterKind || (data.FilterKind = {}));
1680 var FilterKind = data.FilterKind;
1681 })(data = powerbi.data || (powerbi.data = {}));
1682})(powerbi || (powerbi = {}));
1683/*
1684 * Power BI Visualizations
1685 *
1686 * Copyright (c) Microsoft Corporation
1687 * All rights reserved.
1688 * MIT License
1689 *
1690 * Permission is hereby granted, free of charge, to any person obtaining a copy
1691 * of this software and associated documentation files (the ""Software""), to deal
1692 * in the Software without restriction, including without limitation the rights
1693 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1694 * copies of the Software, and to permit persons to whom the Software is
1695 * furnished to do so, subject to the following conditions:
1696 *
1697 * The above copyright notice and this permission notice shall be included in
1698 * all copies or substantial portions of the Software.
1699 *
1700 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1701 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1702 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1703 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1704 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1705 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1706 * THE SOFTWARE.
1707 */
1708var powerbi;
1709(function (powerbi) {
1710 var data;
1711 (function (data) {
1712 var QueryProjectionCollection = (function () {
1713 function QueryProjectionCollection(items, activeProjectionRefs, showAll) {
1714 debug.assertValue(items, 'items');
1715 this.items = items;
1716 this._activeProjectionRefs = activeProjectionRefs;
1717 this._showAll = showAll;
1718 }
1719 /** Returns all projections in a mutable array. */
1720 QueryProjectionCollection.prototype.all = function () {
1721 return this.items;
1722 };
1723 Object.defineProperty(QueryProjectionCollection.prototype, "activeProjectionRefs", {
1724 get: function () {
1725 return this._activeProjectionRefs;
1726 },
1727 set: function (queryReferences) {
1728 if (!_.isEmpty(queryReferences)) {
1729 var queryRefs = this.items.map(function (val) { return val.queryRef; });
1730 for (var _i = 0, queryReferences_1 = queryReferences; _i < queryReferences_1.length; _i++) {
1731 var queryReference = queryReferences_1[_i];
1732 if (!_.contains(queryRefs, queryReference))
1733 return;
1734 }
1735 this._activeProjectionRefs = queryReferences;
1736 }
1737 },
1738 enumerable: true,
1739 configurable: true
1740 });
1741 Object.defineProperty(QueryProjectionCollection.prototype, "showAll", {
1742 get: function () {
1743 return this._showAll;
1744 },
1745 set: function (value) {
1746 this._showAll = value;
1747 },
1748 enumerable: true,
1749 configurable: true
1750 });
1751 QueryProjectionCollection.prototype.addActiveQueryReference = function (queryRef) {
1752 if (!this._activeProjectionRefs)
1753 this._activeProjectionRefs = [queryRef];
1754 else
1755 this._activeProjectionRefs.push(queryRef);
1756 };
1757 QueryProjectionCollection.prototype.getLastActiveQueryReference = function () {
1758 if (!_.isEmpty(this._activeProjectionRefs)) {
1759 return this._activeProjectionRefs[this._activeProjectionRefs.length - 1];
1760 }
1761 };
1762 /** Replaces the given oldQueryRef with newQueryRef in this QueryProjectionCollection. */
1763 QueryProjectionCollection.prototype.replaceQueryRef = function (oldQueryRef, newQueryRef) {
1764 debug.assertValue(oldQueryRef, 'oldQueryRef');
1765 debug.assertValue(newQueryRef, 'newQueryRef');
1766 debug.assert(oldQueryRef !== newQueryRef, 'oldQueryRef !== newQueryRef');
1767 debug.assert(_.isEmpty(this._activeProjectionRefs), 'replaceQueryRef(...) is not supported on the QueryProjectionCollection of a drillable role');
1768 // Note: the same queryRef can get projected multiple times
1769 for (var _i = 0, _a = this.items; _i < _a.length; _i++) {
1770 var item = _a[_i];
1771 if (item.queryRef === oldQueryRef) {
1772 item.queryRef = newQueryRef;
1773 }
1774 }
1775 };
1776 QueryProjectionCollection.prototype.clone = function () {
1777 return new QueryProjectionCollection(_.cloneDeep(this.items), _.clone(this._activeProjectionRefs), this._showAll);
1778 };
1779 return QueryProjectionCollection;
1780 }());
1781 data.QueryProjectionCollection = QueryProjectionCollection;
1782 var QueryProjectionsByRole;
1783 (function (QueryProjectionsByRole) {
1784 /** Clones the QueryProjectionsByRole. */
1785 function clone(roles) {
1786 if (!roles)
1787 return roles;
1788 var clonedRoles = {};
1789 for (var roleName in roles)
1790 clonedRoles[roleName] = roles[roleName].clone();
1791 return clonedRoles;
1792 }
1793 QueryProjectionsByRole.clone = clone;
1794 /** Returns the QueryProjectionCollection for that role. Even returns empty collections so that 'drillable' and 'activeProjection' fields are preserved. */
1795 function getRole(roles, name) {
1796 debug.assertAnyValue(roles, 'roles');
1797 debug.assertValue(name, 'name');
1798 if (!roles)
1799 return;
1800 return roles[name];
1801 }
1802 QueryProjectionsByRole.getRole = getRole;
1803 })(QueryProjectionsByRole = data.QueryProjectionsByRole || (data.QueryProjectionsByRole = {}));
1804 })(data = powerbi.data || (powerbi.data = {}));
1805})(powerbi || (powerbi = {}));
1806/*
1807 * Power BI Visualizations
1808 *
1809 * Copyright (c) Microsoft Corporation
1810 * All rights reserved.
1811 * MIT License
1812 *
1813 * Permission is hereby granted, free of charge, to any person obtaining a copy
1814 * of this software and associated documentation files (the ""Software""), to deal
1815 * in the Software without restriction, including without limitation the rights
1816 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1817 * copies of the Software, and to permit persons to whom the Software is
1818 * furnished to do so, subject to the following conditions:
1819 *
1820 * The above copyright notice and this permission notice shall be included in
1821 * all copies or substantial portions of the Software.
1822 *
1823 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1824 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1825 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1826 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1827 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1828 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1829 * THE SOFTWARE.
1830 */
1831var powerbi;
1832(function (powerbi) {
1833 /** The system used to determine display units used during formatting */
1834 (function (DisplayUnitSystemType) {
1835 /** Default display unit system, which saves space by using units such as K, M, bn with PowerView rules for when to pick a unit. Suitable for chart axes. */
1836 DisplayUnitSystemType[DisplayUnitSystemType["Default"] = 0] = "Default";
1837 /** A verbose display unit system that will only respect the formatting defined in the model. Suitable for explore mode single-value cards. */
1838 DisplayUnitSystemType[DisplayUnitSystemType["Verbose"] = 1] = "Verbose";
1839 /**
1840 * A display unit system that uses units such as K, M, bn if we have at least one of those units (e.g. 0.9M is not valid as it's less than 1 million).
1841 * Suitable for dashboard tile cards
1842 */
1843 DisplayUnitSystemType[DisplayUnitSystemType["WholeUnits"] = 2] = "WholeUnits";
1844 /**A display unit system that also contains Auto and None units for data labels*/
1845 DisplayUnitSystemType[DisplayUnitSystemType["DataLabels"] = 3] = "DataLabels";
1846 })(powerbi.DisplayUnitSystemType || (powerbi.DisplayUnitSystemType = {}));
1847 var DisplayUnitSystemType = powerbi.DisplayUnitSystemType;
1848})(powerbi || (powerbi = {}));
1849/*
1850 * Power BI Visualizations
1851 *
1852 * Copyright (c) Microsoft Corporation
1853 * All rights reserved.
1854 * MIT License
1855 *
1856 * Permission is hereby granted, free of charge, to any person obtaining a copy
1857 * of this software and associated documentation files (the ""Software""), to deal
1858 * in the Software without restriction, including without limitation the rights
1859 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1860 * copies of the Software, and to permit persons to whom the Software is
1861 * furnished to do so, subject to the following conditions:
1862 *
1863 * The above copyright notice and this permission notice shall be included in
1864 * all copies or substantial portions of the Software.
1865 *
1866 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1867 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1868 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1869 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1870 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1871 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1872 * THE SOFTWARE.
1873 */
1874var powerbi;
1875(function (powerbi) {
1876 /** Repreasents the sequence of the dates/times */
1877 var DateTimeSequence = (function () {
1878 // Constructors
1879 /** Creates new instance of the DateTimeSequence */
1880 function DateTimeSequence(unit) {
1881 this.unit = unit;
1882 this.sequence = [];
1883 this.min = new Date("9999-12-31T23:59:59.999");
1884 this.max = new Date("0001-01-01T00:00:00.000");
1885 }
1886 // Methods
1887 /**
1888 * Add a new Date to a sequence.
1889 * @param date - date to add
1890 */
1891 DateTimeSequence.prototype.add = function (date) {
1892 if (date < this.min) {
1893 this.min = date;
1894 }
1895 if (date > this.max) {
1896 this.max = date;
1897 }
1898 this.sequence.push(date);
1899 };
1900 // Methods
1901 /**
1902 * Extends the sequence to cover new date range
1903 * @param min - new min to be covered by sequence
1904 * @param max - new max to be covered by sequence
1905 */
1906 DateTimeSequence.prototype.extendToCover = function (min, max) {
1907 var x = this.min;
1908 while (min < x) {
1909 x = DateTimeSequence.addInterval(x, -this.interval, this.unit);
1910 this.sequence.splice(0, 0, x);
1911 }
1912 this.min = x;
1913 x = this.max;
1914 while (x < max) {
1915 x = DateTimeSequence.addInterval(x, this.interval, this.unit);
1916 this.sequence.push(x);
1917 }
1918 this.max = x;
1919 };
1920 /**
1921 * Move the sequence to cover new date range
1922 * @param min - new min to be covered by sequence
1923 * @param max - new max to be covered by sequence
1924 */
1925 DateTimeSequence.prototype.moveToCover = function (min, max) {
1926 var delta = DateTimeSequence.getDelta(min, max, this.unit);
1927 var count = Math.floor(delta / this.interval);
1928 this.min = DateTimeSequence.addInterval(this.min, count * this.interval, this.unit);
1929 this.sequence = [];
1930 this.sequence.push(this.min);
1931 this.max = this.min;
1932 while (this.max < max) {
1933 this.max = DateTimeSequence.addInterval(this.max, this.interval, this.unit);
1934 this.sequence.push(this.max);
1935 }
1936 };
1937 // Static
1938 /**
1939 * Calculate a new DateTimeSequence
1940 * @param dataMin - Date representing min of the data range
1941 * @param dataMax - Date representing max of the data range
1942 * @param expectedCount - expected number of intervals in the sequence
1943 * @param unit - of the intervals in the sequence
1944 */
1945 DateTimeSequence.calculate = function (dataMin, dataMax, expectedCount, unit) {
1946 if (!unit) {
1947 unit = DateTimeSequence.getIntervalUnit(dataMin, dataMax, expectedCount);
1948 }
1949 switch (unit) {
1950 case powerbi.DateTimeUnit.Year:
1951 return DateTimeSequence.calculateYears(dataMin, dataMax, expectedCount);
1952 case powerbi.DateTimeUnit.Month:
1953 return DateTimeSequence.calculateMonths(dataMin, dataMax, expectedCount);
1954 case powerbi.DateTimeUnit.Week:
1955 return DateTimeSequence.calculateWeeks(dataMin, dataMax, expectedCount);
1956 case powerbi.DateTimeUnit.Day:
1957 return DateTimeSequence.calculateDays(dataMin, dataMax, expectedCount);
1958 case powerbi.DateTimeUnit.Hour:
1959 return DateTimeSequence.calculateHours(dataMin, dataMax, expectedCount);
1960 case powerbi.DateTimeUnit.Minute:
1961 return DateTimeSequence.calculateMinutes(dataMin, dataMax, expectedCount);
1962 case powerbi.DateTimeUnit.Second:
1963 return DateTimeSequence.calculateSeconds(dataMin, dataMax, expectedCount);
1964 case powerbi.DateTimeUnit.Millisecond:
1965 return DateTimeSequence.calculateMilliseconds(dataMin, dataMax, expectedCount);
1966 default:
1967 debug.assertFail("Unsupported DateTimeUnit");
1968 }
1969 };
1970 DateTimeSequence.calculateYears = function (dataMin, dataMax, expectedCount) {
1971 debug.assertValue(dataMin, "dataMin");
1972 debug.assertValue(dataMax, "dataMax");
1973 debug.assert(!expectedCount || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "Expected count is out of range");
1974 // Calculate range and sequence
1975 var yearsRange = powerbi.NumericSequenceRange.calculateDataRange(dataMin.getFullYear(), dataMax.getFullYear(), false);
1976 // Calculate year sequence
1977 var sequence = powerbi.NumericSequence.calculate(powerbi.NumericSequenceRange.calculate(0, yearsRange.max - yearsRange.min), expectedCount, 0, null, null, [1, 2, 5]);
1978 var newMinYear = Math.floor(yearsRange.min / sequence.interval) * sequence.interval;
1979 var date = new Date(newMinYear, 0, 1);
1980 // Convert to date sequence
1981 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Year);
1982 return result;
1983 };
1984 DateTimeSequence.calculateMonths = function (dataMin, dataMax, expectedCount) {
1985 debug.assertValue(dataMin, "dataMin");
1986 debug.assertValue(dataMax, "dataMax");
1987 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
1988 // Calculate range
1989 var minYear = dataMin.getFullYear();
1990 var maxYear = dataMax.getFullYear();
1991 var minMonth = dataMin.getMonth();
1992 var maxMonth = (maxYear - minYear) * 12 + dataMax.getMonth();
1993 var date = new Date(minYear, 0, 1);
1994 // Calculate month sequence
1995 var sequence = powerbi.NumericSequence.calculateUnits(minMonth, maxMonth, expectedCount, [1, 2, 3, 6, 12]);
1996 // Convert to date sequence
1997 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Month);
1998 return result;
1999 };
2000 DateTimeSequence.calculateWeeks = function (dataMin, dataMax, expectedCount) {
2001 debug.assertValue(dataMin, "dataMin");
2002 debug.assertValue(dataMax, "dataMax");
2003 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
2004 var firstDayOfWeek = 0;
2005 var minDayOfWeek = dataMin.getDay();
2006 var dayOffset = (minDayOfWeek - firstDayOfWeek + 7) % 7;
2007 var minDay = dataMin.getDate() - dayOffset;
2008 // Calculate range
2009 var date = new Date(dataMin.getFullYear(), dataMin.getMonth(), minDay);
2010 var min = 0;
2011 var max = powerbi.Double.ceilWithPrecision(DateTimeSequence.getDelta(date, dataMax, powerbi.DateTimeUnit.Week));
2012 // Calculate week sequence
2013 var sequence = powerbi.NumericSequence.calculateUnits(min, max, expectedCount, [1, 2, 4, 8]);
2014 // Convert to date sequence
2015 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Week);
2016 return result;
2017 };
2018 DateTimeSequence.calculateDays = function (dataMin, dataMax, expectedCount) {
2019 debug.assertValue(dataMin, "dataMin");
2020 debug.assertValue(dataMax, "dataMax");
2021 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
2022 // Calculate range
2023 var date = new Date(dataMin.getFullYear(), dataMin.getMonth(), dataMin.getDate());
2024 var min = 0;
2025 var max = powerbi.Double.ceilWithPrecision(DateTimeSequence.getDelta(dataMin, dataMax, powerbi.DateTimeUnit.Day));
2026 // Calculate day sequence
2027 var sequence = powerbi.NumericSequence.calculateUnits(min, max, expectedCount, [1, 2, 7, 14]);
2028 // Convert to date sequence
2029 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Day);
2030 return result;
2031 };
2032 DateTimeSequence.calculateHours = function (dataMin, dataMax, expectedCount) {
2033 debug.assertValue(dataMin, "dataMin");
2034 debug.assertValue(dataMax, "dataMax");
2035 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
2036 // Calculate range
2037 var date = new Date(dataMin.getFullYear(), dataMin.getMonth(), dataMin.getDate());
2038 var min = powerbi.Double.floorWithPrecision(DateTimeSequence.getDelta(date, dataMin, powerbi.DateTimeUnit.Hour));
2039 var max = powerbi.Double.ceilWithPrecision(DateTimeSequence.getDelta(date, dataMax, powerbi.DateTimeUnit.Hour));
2040 // Calculate hour sequence
2041 var sequence = powerbi.NumericSequence.calculateUnits(min, max, expectedCount, [1, 2, 3, 6, 12, 24]);
2042 // Convert to date sequence
2043 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Hour);
2044 return result;
2045 };
2046 DateTimeSequence.calculateMinutes = function (dataMin, dataMax, expectedCount) {
2047 debug.assertValue(dataMin, "dataMin");
2048 debug.assertValue(dataMax, "dataMax");
2049 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
2050 // Calculate range
2051 var date = new Date(dataMin.getFullYear(), dataMin.getMonth(), dataMin.getDate(), dataMin.getHours());
2052 var min = powerbi.Double.floorWithPrecision(DateTimeSequence.getDelta(date, dataMin, powerbi.DateTimeUnit.Minute));
2053 var max = powerbi.Double.ceilWithPrecision(DateTimeSequence.getDelta(date, dataMax, powerbi.DateTimeUnit.Minute));
2054 // Calculate minutes numeric sequence
2055 var sequence = powerbi.NumericSequence.calculateUnits(min, max, expectedCount, [1, 2, 5, 10, 15, 30, 60, 60 * 2, 60 * 3, 60 * 6, 60 * 12, 60 * 24]);
2056 // Convert to date sequence
2057 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Minute);
2058 return result;
2059 };
2060 DateTimeSequence.calculateSeconds = function (dataMin, dataMax, expectedCount) {
2061 debug.assertValue(dataMin, "dataMin");
2062 debug.assertValue(dataMax, "dataMax");
2063 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
2064 // Calculate range
2065 var date = new Date(dataMin.getFullYear(), dataMin.getMonth(), dataMin.getDate(), dataMin.getHours(), dataMin.getMinutes());
2066 var min = powerbi.Double.floorWithPrecision(DateTimeSequence.getDelta(date, dataMin, powerbi.DateTimeUnit.Second));
2067 var max = powerbi.Double.ceilWithPrecision(DateTimeSequence.getDelta(date, dataMax, powerbi.DateTimeUnit.Second));
2068 // Calculate minutes numeric sequence
2069 var sequence = powerbi.NumericSequence.calculateUnits(min, max, expectedCount, [1, 2, 5, 10, 15, 30, 60, 60 * 2, 60 * 5, 60 * 10, 60 * 15, 60 * 30, 60 * 60]);
2070 // Convert to date sequence
2071 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Second);
2072 return result;
2073 };
2074 DateTimeSequence.calculateMilliseconds = function (dataMin, dataMax, expectedCount) {
2075 debug.assertValue(dataMin, "dataMin");
2076 debug.assertValue(dataMax, "dataMax");
2077 debug.assert(expectedCount === undefined || (expectedCount >= DateTimeSequence.MIN_COUNT && expectedCount <= DateTimeSequence.MAX_COUNT), "expected count is out of range");
2078 // Calculate range
2079 var date = new Date(dataMin.getFullYear(), dataMin.getMonth(), dataMin.getDate(), dataMin.getHours(), dataMin.getMinutes(), dataMin.getSeconds());
2080 var min = DateTimeSequence.getDelta(date, dataMin, powerbi.DateTimeUnit.Millisecond);
2081 var max = DateTimeSequence.getDelta(date, dataMax, powerbi.DateTimeUnit.Millisecond);
2082 // Calculate milliseconds numeric sequence
2083 var sequence = powerbi.NumericSequence.calculate(powerbi.NumericSequenceRange.calculate(min, max), expectedCount, 0);
2084 // Convert to date sequence
2085 var result = DateTimeSequence.fromNumericSequence(date, sequence, powerbi.DateTimeUnit.Millisecond);
2086 return result;
2087 };
2088 DateTimeSequence.addInterval = function (value, interval, unit) {
2089 interval = Math.round(interval);
2090 switch (unit) {
2091 case powerbi.DateTimeUnit.Year:
2092 return DateUtils.addYears(value, interval);
2093 case powerbi.DateTimeUnit.Month:
2094 return DateUtils.addMonths(value, interval);
2095 case powerbi.DateTimeUnit.Week:
2096 return DateUtils.addWeeks(value, interval);
2097 case powerbi.DateTimeUnit.Day:
2098 return DateUtils.addDays(value, interval);
2099 case powerbi.DateTimeUnit.Hour:
2100 return DateUtils.addHours(value, interval);
2101 case powerbi.DateTimeUnit.Minute:
2102 return DateUtils.addMinutes(value, interval);
2103 case powerbi.DateTimeUnit.Second:
2104 return DateUtils.addSeconds(value, interval);
2105 case powerbi.DateTimeUnit.Millisecond:
2106 return DateUtils.addMilliseconds(value, interval);
2107 }
2108 };
2109 DateTimeSequence.fromNumericSequence = function (date, sequence, unit) {
2110 var result = new DateTimeSequence(unit);
2111 for (var i = 0; i < sequence.sequence.length; i++) {
2112 var x = sequence.sequence[i];
2113 var d = DateTimeSequence.addInterval(date, x, unit);
2114 result.add(d);
2115 }
2116 result.interval = sequence.interval;
2117 result.intervalOffset = sequence.intervalOffset;
2118 return result;
2119 };
2120 DateTimeSequence.getDelta = function (min, max, unit) {
2121 var delta = 0;
2122 switch (unit) {
2123 case powerbi.DateTimeUnit.Year:
2124 delta = max.getFullYear() - min.getFullYear();
2125 break;
2126 case powerbi.DateTimeUnit.Month:
2127 delta = (max.getFullYear() - min.getFullYear()) * 12 + max.getMonth() - min.getMonth();
2128 break;
2129 case powerbi.DateTimeUnit.Week:
2130 delta = (max.getTime() - min.getTime()) / (7 * 24 * 3600000);
2131 break;
2132 case powerbi.DateTimeUnit.Day:
2133 delta = (max.getTime() - min.getTime()) / (24 * 3600000);
2134 break;
2135 case powerbi.DateTimeUnit.Hour:
2136 delta = (max.getTime() - min.getTime()) / 3600000;
2137 break;
2138 case powerbi.DateTimeUnit.Minute:
2139 delta = (max.getTime() - min.getTime()) / 60000;
2140 break;
2141 case powerbi.DateTimeUnit.Second:
2142 delta = (max.getTime() - min.getTime()) / 1000;
2143 break;
2144 case powerbi.DateTimeUnit.Millisecond:
2145 delta = max.getTime() - min.getTime();
2146 break;
2147 }
2148 return delta;
2149 };
2150 DateTimeSequence.getIntervalUnit = function (min, max, maxCount) {
2151 maxCount = Math.max(maxCount, 2);
2152 var totalDays = DateTimeSequence.getDelta(min, max, powerbi.DateTimeUnit.Day);
2153 if (totalDays > 356 && totalDays >= 30 * 6 * maxCount)
2154 return powerbi.DateTimeUnit.Year;
2155 if (totalDays > 60 && totalDays > 7 * maxCount)
2156 return powerbi.DateTimeUnit.Month;
2157 if (totalDays > 14 && totalDays > 2 * maxCount)
2158 return powerbi.DateTimeUnit.Week;
2159 var totalHours = DateTimeSequence.getDelta(min, max, powerbi.DateTimeUnit.Hour);
2160 if (totalDays > 2 && totalHours > 12 * maxCount)
2161 return powerbi.DateTimeUnit.Day;
2162 if (totalHours >= 24 && totalHours >= maxCount)
2163 return powerbi.DateTimeUnit.Hour;
2164 var totalMinutes = DateTimeSequence.getDelta(min, max, powerbi.DateTimeUnit.Minute);
2165 if (totalMinutes > 2 && totalMinutes >= maxCount)
2166 return powerbi.DateTimeUnit.Minute;
2167 var totalSeconds = DateTimeSequence.getDelta(min, max, powerbi.DateTimeUnit.Second);
2168 if (totalSeconds > 2 && totalSeconds >= 0.8 * maxCount)
2169 return powerbi.DateTimeUnit.Second;
2170 var totalMilliseconds = DateTimeSequence.getDelta(min, max, powerbi.DateTimeUnit.Millisecond);
2171 if (totalMilliseconds > 0)
2172 return powerbi.DateTimeUnit.Millisecond;
2173 // If the size of the range is 0 we need to guess the unit based on the date's non-zero values starting with milliseconds
2174 var date = min;
2175 if (date.getMilliseconds() !== 0)
2176 return powerbi.DateTimeUnit.Millisecond;
2177 if (date.getSeconds() !== 0)
2178 return powerbi.DateTimeUnit.Second;
2179 if (date.getMinutes() !== 0)
2180 return powerbi.DateTimeUnit.Minute;
2181 if (date.getHours() !== 0)
2182 return powerbi.DateTimeUnit.Hour;
2183 if (date.getDate() !== 1)
2184 return powerbi.DateTimeUnit.Day;
2185 if (date.getMonth() !== 0)
2186 return powerbi.DateTimeUnit.Month;
2187 return powerbi.DateTimeUnit.Year;
2188 };
2189 // Constants
2190 DateTimeSequence.MIN_COUNT = 1;
2191 DateTimeSequence.MAX_COUNT = 1000;
2192 return DateTimeSequence;
2193 }());
2194 powerbi.DateTimeSequence = DateTimeSequence;
2195 /** DateUtils module provides DateTimeSequence with set of additional date manipulation routines */
2196 var DateUtils;
2197 (function (DateUtils) {
2198 var MonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
2199 var MonthDaysLeap = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
2200 /**
2201 * Returns bool indicating weither the provided year is a leap year.
2202 * @param year - year value
2203 */
2204 function isLeap(year) {
2205 return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);
2206 }
2207 /**
2208 * Returns number of days in the provided year/month.
2209 * @param year - year value
2210 * @param month - month value
2211 */
2212 function getMonthDays(year, month) {
2213 return isLeap(year) ? MonthDaysLeap[month] : MonthDays[month];
2214 }
2215 /**
2216 * Adds a specified number of years to the provided date.
2217 * @param date - date value
2218 * @param yearDelta - number of years to add
2219 */
2220 function addYears(date, yearDelta) {
2221 var year = date.getFullYear();
2222 var month = date.getMonth();
2223 var day = date.getDate();
2224 var isLeapDay = month === 2 && day === 29;
2225 var result = new Date(date.getTime());
2226 year = year + yearDelta;
2227 if (isLeapDay && !isLeap(year)) {
2228 day = 28;
2229 }
2230 result.setFullYear(year, month, day);
2231 return result;
2232 }
2233 DateUtils.addYears = addYears;
2234 /**
2235 * Adds a specified number of months to the provided date.
2236 * @param date - date value
2237 * @param monthDelta - number of months to add
2238 */
2239 function addMonths(date, monthDelta) {
2240 var year = date.getFullYear();
2241 var month = date.getMonth();
2242 var day = date.getDate();
2243 var result = new Date(date.getTime());
2244 year += (monthDelta - (monthDelta % 12)) / 12;
2245 month += monthDelta % 12;
2246 // VSTS 1325771: Certain column charts don't display any data
2247 // Wrap arround the month if is after december (value 11)
2248 if (month > 11) {
2249 month = month % 12;
2250 year++;
2251 }
2252 day = Math.min(day, getMonthDays(year, month));
2253 result.setFullYear(year, month, day);
2254 return result;
2255 }
2256 DateUtils.addMonths = addMonths;
2257 /**
2258 * Adds a specified number of weeks to the provided date.
2259 * @param date - date value
2260 * @param weeks - number of weeks to add
2261 */
2262 function addWeeks(date, weeks) {
2263 return addDays(date, weeks * 7);
2264 }
2265 DateUtils.addWeeks = addWeeks;
2266 /**
2267 * Adds a specified number of days to the provided date.
2268 * @param date - date value
2269 * @param days - number of days to add
2270 */
2271 function addDays(date, days) {
2272 var year = date.getFullYear();
2273 var month = date.getMonth();
2274 var day = date.getDate();
2275 var result = new Date(date.getTime());
2276 result.setFullYear(year, month, day + days);
2277 return result;
2278 }
2279 DateUtils.addDays = addDays;
2280 /**
2281 * Adds a specified number of hours to the provided date.
2282 * @param date - date value
2283 * @param hours - number of hours to add
2284 */
2285 function addHours(date, hours) {
2286 return new Date(date.getTime() + hours * 3600000);
2287 }
2288 DateUtils.addHours = addHours;
2289 /**
2290 * Adds a specified number of minutes to the provided date.
2291 * @param date - date value
2292 * @param minutes - number of minutes to add
2293 */
2294 function addMinutes(date, minutes) {
2295 return new Date(date.getTime() + minutes * 60000);
2296 }
2297 DateUtils.addMinutes = addMinutes;
2298 /**
2299 * Adds a specified number of seconds to the provided date.
2300 * @param date - date value
2301 * @param seconds - number of seconds to add
2302 */
2303 function addSeconds(date, seconds) {
2304 return new Date(date.getTime() + seconds * 1000);
2305 }
2306 DateUtils.addSeconds = addSeconds;
2307 /**
2308 * Adds a specified number of milliseconds to the provided date.
2309 * @param date - date value
2310 * @param milliseconds - number of milliseconds to add
2311 */
2312 function addMilliseconds(date, milliseconds) {
2313 return new Date(date.getTime() + milliseconds);
2314 }
2315 DateUtils.addMilliseconds = addMilliseconds;
2316 })(DateUtils = powerbi.DateUtils || (powerbi.DateUtils = {}));
2317})(powerbi || (powerbi = {}));
2318/*
2319 * Power BI Visualizations
2320 *
2321 * Copyright (c) Microsoft Corporation
2322 * All rights reserved.
2323 * MIT License
2324 *
2325 * Permission is hereby granted, free of charge, to any person obtaining a copy
2326 * of this software and associated documentation files (the ""Software""), to deal
2327 * in the Software without restriction, including without limitation the rights
2328 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2329 * copies of the Software, and to permit persons to whom the Software is
2330 * furnished to do so, subject to the following conditions:
2331 *
2332 * The above copyright notice and this permission notice shall be included in
2333 * all copies or substantial portions of the Software.
2334 *
2335 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2336 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2337 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2338 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2339 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2340 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2341 * THE SOFTWARE.
2342 */
2343var powerbi;
2344(function (powerbi) {
2345 // Constants
2346 var maxExponent = 24;
2347 var defaultScientificBigNumbersBoundary = 1E15;
2348 var scientificSmallNumbersBoundary = 1E-4;
2349 var PERCENTAGE_FORMAT = '%';
2350 var SCIENTIFIC_FORMAT = 'E+0';
2351 var DEFAULT_SCIENTIFIC_FORMAT = '0.##' + SCIENTIFIC_FORMAT;
2352 // Regular expressions
2353 /**
2354 * This regex looks for strings that match one of the following conditions:
2355 * - Optionally contain "0", "#", followed by a period, followed by at least one "0" or "#" (Ex. ###,000.###)
2356 * - Contains at least one of "0", "#", or "," (Ex. ###,000)
2357 * - Contain a "g" (indicates to use the general .NET numeric format string)
2358 * The entire string (start to end) must match, and the match is not case-sensitive.
2359 */
2360 var SUPPORTED_SCIENTIFIC_FORMATS = /^([0\#,]*\.[0\#]+|[0\#,]+|g)$/i;
2361 var DisplayUnit = (function () {
2362 function DisplayUnit() {
2363 }
2364 // Methods
2365 DisplayUnit.prototype.project = function (value) {
2366 if (this.value) {
2367 return powerbi.Double.removeDecimalNoise(value / this.value);
2368 }
2369 else {
2370 return value;
2371 }
2372 };
2373 DisplayUnit.prototype.reverseProject = function (value) {
2374 if (this.value) {
2375 return value * this.value;
2376 }
2377 else {
2378 return value;
2379 }
2380 };
2381 DisplayUnit.prototype.isApplicableTo = function (value) {
2382 value = Math.abs(value);
2383 var precision = powerbi.Double.getPrecision(value, 3);
2384 return powerbi.Double.greaterOrEqualWithPrecision(value, this.applicableRangeMin, precision) && powerbi.Double.lessWithPrecision(value, this.applicableRangeMax, precision);
2385 };
2386 DisplayUnit.prototype.isScaling = function () {
2387 return this.value > 1;
2388 };
2389 return DisplayUnit;
2390 }());
2391 powerbi.DisplayUnit = DisplayUnit;
2392 var DisplayUnitSystem = (function () {
2393 // Constructor
2394 function DisplayUnitSystem(units) {
2395 this.units = units ? units : [];
2396 }
2397 Object.defineProperty(DisplayUnitSystem.prototype, "title", {
2398 // Properties
2399 get: function () {
2400 return this.displayUnit ? this.displayUnit.title : undefined;
2401 },
2402 enumerable: true,
2403 configurable: true
2404 });
2405 // Methods
2406 DisplayUnitSystem.prototype.update = function (value) {
2407 if (value === undefined)
2408 return;
2409 this.unitBaseValue = value;
2410 this.displayUnit = this.findApplicableDisplayUnit(value);
2411 };
2412 DisplayUnitSystem.prototype.findApplicableDisplayUnit = function (value) {
2413 for (var _i = 0, _a = this.units; _i < _a.length; _i++) {
2414 var unit = _a[_i];
2415 if (unit.isApplicableTo(value))
2416 return unit;
2417 }
2418 return undefined;
2419 };
2420 DisplayUnitSystem.prototype.format = function (value, format, decimals, trailingZeros) {
2421 debug.assert(typeof (value) === "number", "value must be a number");
2422 if (this.isFormatSupported(format)) {
2423 decimals = this.getNumberOfDecimalsForFormatting(format, decimals);
2424 if (this.hasScientitifcFormat(format)) {
2425 return this.formatHelper(value, '', format, decimals, trailingZeros);
2426 }
2427 if (this.isScalingUnit() && this.shouldRespectScalingUnit(format)) {
2428 return this.formatHelper(this.displayUnit.project(value), this.displayUnit.labelFormat, format, decimals, trailingZeros);
2429 }
2430 if (decimals != null) {
2431 return this.formatHelper(value, '', format, decimals, trailingZeros);
2432 }
2433 }
2434 return powerbi.formattingService.formatValue(value, format);
2435 };
2436 DisplayUnitSystem.prototype.isFormatSupported = function (format) {
2437 return !DisplayUnitSystem.UNSUPPORTED_FORMATS.test(format);
2438 };
2439 DisplayUnitSystem.prototype.isPercentageFormat = function (format) {
2440 return format && format.indexOf(PERCENTAGE_FORMAT) >= 0;
2441 };
2442 DisplayUnitSystem.prototype.shouldRespectScalingUnit = function (format) {
2443 return !this.isPercentageFormat(format);
2444 };
2445 DisplayUnitSystem.prototype.getNumberOfDecimalsForFormatting = function (format, decimals) {
2446 return decimals;
2447 };
2448 DisplayUnitSystem.prototype.isScalingUnit = function () {
2449 return this.displayUnit && this.displayUnit.isScaling();
2450 };
2451 DisplayUnitSystem.prototype.formatHelper = function (value, nonScientificFormat, format, decimals, trailingZeros) {
2452 // If the format is "general" and we want to override the number of decimal places then use the default numeric format string.
2453 if ((format === 'g' || format === 'G') && decimals != null)
2454 format = powerbi.visuals.valueFormatter.DefaultNumericFormat;
2455 format = powerbi.NumberFormat.addDecimalsToFormat(format, decimals, trailingZeros);
2456 if (format && !powerbi.formattingService.isStandardNumberFormat(format))
2457 return powerbi.formattingService.formatNumberWithCustomOverride(value, format, nonScientificFormat);
2458 if (!format)
2459 format = 'G';
2460 if (!nonScientificFormat)
2461 nonScientificFormat = '{0}';
2462 var text = powerbi.formattingService.formatValue(value, format);
2463 return powerbi.formattingService.format(nonScientificFormat, [text]);
2464 };
2465 /** Formats a single value by choosing an appropriate base for the DisplayUnitSystem before formatting. */
2466 DisplayUnitSystem.prototype.formatSingleValue = function (value, format, decimals, trailingZeros) {
2467 // Change unit base to a value appropriate for this value
2468 this.update(this.shouldUseValuePrecision(value) ? powerbi.Double.getPrecision(value, 8) : value);
2469 return this.format(value, format, decimals, trailingZeros);
2470 };
2471 DisplayUnitSystem.prototype.shouldUseValuePrecision = function (value) {
2472 if (this.units.length === 0)
2473 return true;
2474 // Check if the value is big enough to have a valid unit by checking against the smallest unit (that it's value bigger than 1).
2475 var applicableRangeMin = 0;
2476 for (var i = 0; i < this.units.length; i++) {
2477 if (this.units[i].isScaling()) {
2478 applicableRangeMin = this.units[i].applicableRangeMin;
2479 break;
2480 }
2481 }
2482 return Math.abs(value) < applicableRangeMin;
2483 };
2484 DisplayUnitSystem.prototype.isScientific = function (value) {
2485 return value < -defaultScientificBigNumbersBoundary || value > defaultScientificBigNumbersBoundary ||
2486 (-scientificSmallNumbersBoundary < value && value < scientificSmallNumbersBoundary && value !== 0);
2487 };
2488 DisplayUnitSystem.prototype.hasScientitifcFormat = function (format) {
2489 return format && format.toUpperCase().indexOf("E") !== -1;
2490 };
2491 DisplayUnitSystem.prototype.supportsScientificFormat = function (format) {
2492 if (format)
2493 return SUPPORTED_SCIENTIFIC_FORMATS.test(format);
2494 return true;
2495 };
2496 DisplayUnitSystem.prototype.shouldFallbackToScientific = function (value, format) {
2497 return !this.hasScientitifcFormat(format)
2498 && this.supportsScientificFormat(format)
2499 && this.isScientific(value);
2500 };
2501 DisplayUnitSystem.prototype.getScientificFormat = function (data, format, decimals, trailingZeros) {
2502 // Use scientific format outside of the range
2503 if (this.isFormatSupported(format) && this.shouldFallbackToScientific(data, format)) {
2504 var numericFormat = powerbi.NumberFormat.getNumericFormat(data, format);
2505 if (decimals)
2506 numericFormat = powerbi.NumberFormat.addDecimalsToFormat(numericFormat ? numericFormat : '0', Math.abs(decimals), trailingZeros);
2507 if (numericFormat)
2508 return numericFormat + SCIENTIFIC_FORMAT;
2509 else
2510 return DEFAULT_SCIENTIFIC_FORMAT;
2511 }
2512 return format;
2513 };
2514 DisplayUnitSystem.UNSUPPORTED_FORMATS = /^(p\d*)|(.*\%)|(e\d*)$/i;
2515 return DisplayUnitSystem;
2516 }());
2517 powerbi.DisplayUnitSystem = DisplayUnitSystem;
2518 /** Provides a unit system that is defined by formatting in the model, and is suitable for visualizations shown in single number visuals in explore mode. */
2519 var NoDisplayUnitSystem = (function (_super) {
2520 __extends(NoDisplayUnitSystem, _super);
2521 // Constructor
2522 function NoDisplayUnitSystem() {
2523 _super.call(this, []);
2524 }
2525 return NoDisplayUnitSystem;
2526 }(DisplayUnitSystem));
2527 powerbi.NoDisplayUnitSystem = NoDisplayUnitSystem;
2528 /** Provides a unit system that creates a more concise format for displaying values. This is suitable for most of the cases where
2529 we are showing values (chart axes) and as such it is the default unit system. */
2530 var DefaultDisplayUnitSystem = (function (_super) {
2531 __extends(DefaultDisplayUnitSystem, _super);
2532 // Constructor
2533 function DefaultDisplayUnitSystem(unitLookup) {
2534 _super.call(this, DefaultDisplayUnitSystem.getUnits(unitLookup));
2535 }
2536 // Methods
2537 DefaultDisplayUnitSystem.prototype.format = function (data, format, decimals, trailingZeros) {
2538 format = this.getScientificFormat(data, format, decimals, trailingZeros);
2539 return _super.prototype.format.call(this, data, format, decimals, trailingZeros);
2540 };
2541 DefaultDisplayUnitSystem.reset = function () {
2542 DefaultDisplayUnitSystem.units = null;
2543 };
2544 DefaultDisplayUnitSystem.getUnits = function (unitLookup) {
2545 if (!DefaultDisplayUnitSystem.units) {
2546 DefaultDisplayUnitSystem.units = createDisplayUnits(unitLookup, function (value, previousUnitValue, min) {
2547 // When dealing with millions/billions/trillions we need to switch to millions earlier: for example instead of showing 100K 200K 300K we should show 0.1M 0.2M 0.3M etc
2548 if (value - previousUnitValue >= 1000) {
2549 return value / 10;
2550 }
2551 return min;
2552 });
2553 // Ensure last unit has max of infinity
2554 DefaultDisplayUnitSystem.units[DefaultDisplayUnitSystem.units.length - 1].applicableRangeMax = Infinity;
2555 }
2556 return DefaultDisplayUnitSystem.units;
2557 };
2558 return DefaultDisplayUnitSystem;
2559 }(DisplayUnitSystem));
2560 powerbi.DefaultDisplayUnitSystem = DefaultDisplayUnitSystem;
2561 /** Provides a unit system that creates a more concise format for displaying values, but only allows showing a unit if we have at least
2562 one of those units (e.g. 0.9M is not allowed since it's less than 1 million). This is suitable for cases such as dashboard tiles
2563 where we have restricted space but do not want to show partial units. */
2564 var WholeUnitsDisplayUnitSystem = (function (_super) {
2565 __extends(WholeUnitsDisplayUnitSystem, _super);
2566 // Constructor
2567 function WholeUnitsDisplayUnitSystem(unitLookup) {
2568 _super.call(this, WholeUnitsDisplayUnitSystem.getUnits(unitLookup));
2569 }
2570 WholeUnitsDisplayUnitSystem.reset = function () {
2571 WholeUnitsDisplayUnitSystem.units = null;
2572 };
2573 WholeUnitsDisplayUnitSystem.getUnits = function (unitLookup) {
2574 if (!WholeUnitsDisplayUnitSystem.units) {
2575 WholeUnitsDisplayUnitSystem.units = createDisplayUnits(unitLookup);
2576 // Ensure last unit has max of infinity
2577 WholeUnitsDisplayUnitSystem.units[WholeUnitsDisplayUnitSystem.units.length - 1].applicableRangeMax = Infinity;
2578 }
2579 return WholeUnitsDisplayUnitSystem.units;
2580 };
2581 WholeUnitsDisplayUnitSystem.prototype.format = function (data, format, decimals, trailingZeros) {
2582 format = this.getScientificFormat(data, format, decimals, trailingZeros);
2583 return _super.prototype.format.call(this, data, format, decimals, trailingZeros);
2584 };
2585 return WholeUnitsDisplayUnitSystem;
2586 }(DisplayUnitSystem));
2587 powerbi.WholeUnitsDisplayUnitSystem = WholeUnitsDisplayUnitSystem;
2588 var DataLabelsDisplayUnitSystem = (function (_super) {
2589 __extends(DataLabelsDisplayUnitSystem, _super);
2590 function DataLabelsDisplayUnitSystem(unitLookup) {
2591 _super.call(this, DataLabelsDisplayUnitSystem.getUnits(unitLookup));
2592 }
2593 DataLabelsDisplayUnitSystem.prototype.isFormatSupported = function (format) {
2594 return !DataLabelsDisplayUnitSystem.UNSUPPORTED_FORMATS.test(format);
2595 };
2596 DataLabelsDisplayUnitSystem.getUnits = function (unitLookup) {
2597 if (!DataLabelsDisplayUnitSystem.units) {
2598 var units = [];
2599 var adjustMinBasedOnPreviousUnit = function (value, previousUnitValue, min) {
2600 // Never returns true, we are always ignoring
2601 // We do not early switch (e.g. 100K instead of 0.1M)
2602 // Intended? If so, remove this function, otherwise, remove if statement
2603 if (value === -1)
2604 if (value - previousUnitValue >= 1000) {
2605 return value / 10;
2606 }
2607 return min;
2608 };
2609 // Add Auto & None
2610 var names = unitLookup(-1);
2611 addUnitIfNonEmpty(units, DataLabelsDisplayUnitSystem.AUTO_DISPLAYUNIT_VALUE, names.title, names.format, adjustMinBasedOnPreviousUnit);
2612 names = unitLookup(0);
2613 addUnitIfNonEmpty(units, DataLabelsDisplayUnitSystem.NONE_DISPLAYUNIT_VALUE, names.title, names.format, adjustMinBasedOnPreviousUnit);
2614 // Add normal units
2615 DataLabelsDisplayUnitSystem.units = units.concat(createDisplayUnits(unitLookup, adjustMinBasedOnPreviousUnit));
2616 // Ensure last unit has max of infinity
2617 DataLabelsDisplayUnitSystem.units[DataLabelsDisplayUnitSystem.units.length - 1].applicableRangeMax = Infinity;
2618 }
2619 return DataLabelsDisplayUnitSystem.units;
2620 };
2621 DataLabelsDisplayUnitSystem.prototype.format = function (data, format, decimals, trailingZeros) {
2622 format = this.getScientificFormat(data, format, decimals, trailingZeros);
2623 return _super.prototype.format.call(this, data, format, decimals, trailingZeros);
2624 };
2625 // Constants
2626 DataLabelsDisplayUnitSystem.AUTO_DISPLAYUNIT_VALUE = 0;
2627 DataLabelsDisplayUnitSystem.NONE_DISPLAYUNIT_VALUE = 1;
2628 DataLabelsDisplayUnitSystem.UNSUPPORTED_FORMATS = /^(e\d*)$/i;
2629 return DataLabelsDisplayUnitSystem;
2630 }(DisplayUnitSystem));
2631 powerbi.DataLabelsDisplayUnitSystem = DataLabelsDisplayUnitSystem;
2632 function createDisplayUnits(unitLookup, adjustMinBasedOnPreviousUnit) {
2633 var units = [];
2634 for (var i = 3; i < maxExponent; i++) {
2635 var names = unitLookup(i);
2636 if (names)
2637 addUnitIfNonEmpty(units, powerbi.Double.pow10(i), names.title, names.format, adjustMinBasedOnPreviousUnit);
2638 }
2639 return units;
2640 }
2641 function addUnitIfNonEmpty(units, value, title, labelFormat, adjustMinBasedOnPreviousUnit) {
2642 if (title || labelFormat) {
2643 var min = value;
2644 if (units.length > 0) {
2645 var previousUnit = units[units.length - 1];
2646 if (adjustMinBasedOnPreviousUnit)
2647 min = adjustMinBasedOnPreviousUnit(value, previousUnit.value, min);
2648 previousUnit.applicableRangeMax = min;
2649 }
2650 var unit = new DisplayUnit();
2651 unit.value = value;
2652 unit.applicableRangeMin = min;
2653 unit.applicableRangeMax = min * 1000;
2654 unit.title = title;
2655 unit.labelFormat = labelFormat;
2656 units.push(unit);
2657 }
2658 }
2659})(powerbi || (powerbi = {}));
2660/*
2661 * Power BI Visualizations
2662 *
2663 * Copyright (c) Microsoft Corporation
2664 * All rights reserved.
2665 * MIT License
2666 *
2667 * Permission is hereby granted, free of charge, to any person obtaining a copy
2668 * of this software and associated documentation files (the ""Software""), to deal
2669 * in the Software without restriction, including without limitation the rights
2670 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2671 * copies of the Software, and to permit persons to whom the Software is
2672 * furnished to do so, subject to the following conditions:
2673 *
2674 * The above copyright notice and this permission notice shall be included in
2675 * all copies or substantial portions of the Software.
2676 *
2677 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2678 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2679 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2680 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2681 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2682 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2683 * THE SOFTWARE.
2684 */
2685var powerbi;
2686(function (powerbi) {
2687 var NumericSequence = (function () {
2688 function NumericSequence() {
2689 }
2690 NumericSequence.calculate = function (range, expectedCount, maxAllowedMargin, minPower, useZeroRefPoint, steps) {
2691 debug.assertValue(range, "range");
2692 debug.assert(expectedCount === undefined || (expectedCount >= NumericSequence.MIN_COUNT && expectedCount <= NumericSequence.MAX_COUNT), "expectedCount");
2693 debug.assert(minPower === undefined || (minPower >= powerbi.Double.MIN_EXP && minPower <= powerbi.Double.MAX_EXP), "minPower");
2694 debug.assert(maxAllowedMargin === undefined || (maxAllowedMargin >= 0), "maxAllowedMargin");
2695 var result = new NumericSequence();
2696 if (expectedCount === undefined)
2697 expectedCount = 10;
2698 else
2699 expectedCount = powerbi.Double.ensureInRange(expectedCount, NumericSequence.MIN_COUNT, NumericSequence.MAX_COUNT);
2700 if (minPower === undefined)
2701 minPower = powerbi.Double.MIN_EXP;
2702 if (useZeroRefPoint === undefined)
2703 useZeroRefPoint = false;
2704 if (maxAllowedMargin === undefined)
2705 maxAllowedMargin = 1;
2706 if (steps === undefined)
2707 steps = [1, 2, 5];
2708 // Handle single stop case
2709 if (range.forcedSingleStop) {
2710 result.interval = range.getSize();
2711 result.intervalOffset = result.interval - (range.forcedSingleStop - range.min);
2712 result.min = range.min;
2713 result.max = range.max;
2714 result.sequence = [range.forcedSingleStop];
2715 return result;
2716 }
2717 var interval = 0;
2718 var min = 0;
2719 var max = 9;
2720 var canExtendMin = maxAllowedMargin > 0 && !range.hasFixedMin;
2721 var canExtendMax = maxAllowedMargin > 0 && !range.hasFixedMax;
2722 var size = range.getSize();
2723 var exp = powerbi.Double.log10(size);
2724 // Account for Exp of steps
2725 var stepExp = powerbi.Double.log10(steps[0]);
2726 exp = exp - stepExp;
2727 // Account for MaxCount
2728 var expectedCountExp = powerbi.Double.log10(expectedCount);
2729 exp = exp - expectedCountExp;
2730 // Account for MinPower
2731 exp = Math.max(exp, minPower - stepExp + 1);
2732 var count = undefined;
2733 // Create array of "good looking" numbers
2734 if (interval !== 0) {
2735 // If explicit interval is defined - use it instead of the steps array.
2736 var power = powerbi.Double.pow10(exp);
2737 var roundMin = powerbi.Double.floorToPrecision(range.min, power);
2738 var roundMax = powerbi.Double.ceilToPrecision(range.max, power);
2739 var roundRange = powerbi.NumericSequenceRange.calculateFixedRange(roundMin, roundMax);
2740 roundRange.shrinkByStep(range, interval);
2741 min = roundRange.min;
2742 max = roundRange.max;
2743 count = Math.floor(roundRange.getSize() / interval);
2744 }
2745 else {
2746 // No interval defined -> find optimal interval
2747 var dexp = void 0;
2748 for (dexp = 0; dexp < 3; dexp++) {
2749 var e = exp + dexp;
2750 var power = powerbi.Double.pow10(e);
2751 var roundMin = powerbi.Double.floorToPrecision(range.min, power);
2752 var roundMax = powerbi.Double.ceilToPrecision(range.max, power);
2753 // Go throught the steps array looking for the smallest step that produces the right interval count.
2754 var stepsCount = steps.length;
2755 var stepPower = powerbi.Double.pow10(e - 1);
2756 for (var i = 0; i < stepsCount; i++) {
2757 var step = steps[i] * stepPower;
2758 var roundRange = powerbi.NumericSequenceRange.calculateFixedRange(roundMin, roundMax, useZeroRefPoint);
2759 roundRange.shrinkByStep(range, step);
2760 // If the range is based on Data we might need to extend it to provide nice data margins.
2761 if (canExtendMin && range.min === roundRange.min && maxAllowedMargin >= 1)
2762 roundRange.min -= step;
2763 if (canExtendMax && range.max === roundRange.max && maxAllowedMargin >= 1)
2764 roundRange.max += step;
2765 // Count the intervals
2766 count = powerbi.Double.ceilWithPrecision(roundRange.getSize() / step);
2767 if (count <= expectedCount || (dexp === 2 && i === stepsCount - 1) || (expectedCount === 1 && count === 2 && (step > range.getSize() || (range.min < 0 && range.max > 0 && step * 2 >= range.getSize())))) {
2768 interval = step;
2769 min = roundRange.min;
2770 max = roundRange.max;
2771 break;
2772 }
2773 }
2774 // Increase the scale power until the interval is found
2775 if (interval !== 0)
2776 break;
2777 }
2778 }
2779 // Avoid extreme count cases (>1000 ticks)
2780 if (count > expectedCount * 32 || count > NumericSequence.MAX_COUNT) {
2781 count = Math.min(expectedCount * 32, NumericSequence.MAX_COUNT);
2782 interval = (max - min) / count;
2783 }
2784 result.min = min;
2785 result.max = max;
2786 result.interval = interval;
2787 result.intervalOffset = min - range.min;
2788 result.maxAllowedMargin = maxAllowedMargin;
2789 result.canExtendMin = canExtendMin;
2790 result.canExtendMax = canExtendMax;
2791 // Fill in the Sequence
2792 var precision = powerbi.Double.getPrecision(interval, 0);
2793 result.precision = precision;
2794 var sequence = [];
2795 var x = powerbi.Double.roundToPrecision(min, precision);
2796 sequence.push(x);
2797 for (var i = 0; i < count; i++) {
2798 x = powerbi.Double.roundToPrecision(x + interval, precision);
2799 sequence.push(x);
2800 }
2801 result.sequence = sequence;
2802 result.trimMinMax(range.min, range.max);
2803 return result;
2804 };
2805 /**
2806 * Calculates the sequence of int numbers which are mapped to the multiples of the units grid.
2807 * @min - The minimum of the range.
2808 * @max - The maximum of the range.
2809 * @maxCount - The max count of intervals.
2810 * @steps - array of intervals.
2811 */
2812 NumericSequence.calculateUnits = function (min, max, maxCount, steps) {
2813 // Initialization actions
2814 maxCount = powerbi.Double.ensureInRange(maxCount, NumericSequence.MIN_COUNT, NumericSequence.MAX_COUNT);
2815 if (min === max) {
2816 max = min + 1;
2817 }
2818 var stepCount = 0;
2819 var step = 0;
2820 // Calculate step
2821 for (var i = 0; i < steps.length; i++) {
2822 step = steps[i];
2823 var maxStepCount = powerbi.Double.ceilWithPrecision(max / step);
2824 var minStepCount = powerbi.Double.floorWithPrecision(min / step);
2825 stepCount = maxStepCount - minStepCount;
2826 if (stepCount <= maxCount) {
2827 break;
2828 }
2829 }
2830 // Calculate the offset
2831 var offset = -min;
2832 offset = offset % step;
2833 // Create sequence
2834 var result = new NumericSequence();
2835 result.sequence = [];
2836 for (var x = min + offset;; x += step) {
2837 result.sequence.push(x);
2838 if (x >= max)
2839 break;
2840 }
2841 result.interval = step;
2842 result.intervalOffset = offset;
2843 result.min = result.sequence[0];
2844 result.max = result.sequence[result.sequence.length - 1];
2845 return result;
2846 };
2847 NumericSequence.prototype.trimMinMax = function (min, max) {
2848 var minMargin = (min - this.min) / this.interval;
2849 var maxMargin = (this.max - max) / this.interval;
2850 var marginPrecision = 0.001;
2851 if (!this.canExtendMin || (minMargin > this.maxAllowedMargin && minMargin > marginPrecision)) {
2852 this.min = min;
2853 }
2854 if (!this.canExtendMax || (maxMargin > this.maxAllowedMargin && maxMargin > marginPrecision)) {
2855 this.max = max;
2856 }
2857 };
2858 NumericSequence.MIN_COUNT = 1;
2859 NumericSequence.MAX_COUNT = 1000;
2860 return NumericSequence;
2861 }());
2862 powerbi.NumericSequence = NumericSequence;
2863})(powerbi || (powerbi = {}));
2864/*
2865 * Power BI Visualizations
2866 *
2867 * Copyright (c) Microsoft Corporation
2868 * All rights reserved.
2869 * MIT License
2870 *
2871 * Permission is hereby granted, free of charge, to any person obtaining a copy
2872 * of this software and associated documentation files (the ""Software""), to deal
2873 * in the Software without restriction, including without limitation the rights
2874 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2875 * copies of the Software, and to permit persons to whom the Software is
2876 * furnished to do so, subject to the following conditions:
2877 *
2878 * The above copyright notice and this permission notice shall be included in
2879 * all copies or substantial portions of the Software.
2880 *
2881 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2882 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2883 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2884 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2885 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2886 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2887 * THE SOFTWARE.
2888 */
2889var powerbi;
2890(function (powerbi) {
2891 var NumericSequenceRange = (function () {
2892 function NumericSequenceRange() {
2893 }
2894 NumericSequenceRange.prototype._ensureIncludeZero = function () {
2895 if (this.includeZero) {
2896 // fixed min and max has higher priority than includeZero
2897 if (this.min > 0 && !this.hasFixedMin) {
2898 this.min = 0;
2899 }
2900 if (this.max < 0 && !this.hasFixedMax) {
2901 this.max = 0;
2902 }
2903 }
2904 };
2905 NumericSequenceRange.prototype._ensureNotEmpty = function () {
2906 if (this.min === this.max) {
2907 if (!this.min) {
2908 this.min = 0;
2909 this.max = NumericSequenceRange.DEFAULT_MAX;
2910 this.hasFixedMin = true;
2911 this.hasFixedMax = true;
2912 }
2913 else {
2914 // We are dealing with a single data value (includeZero is not set)
2915 // In order to fix the range we need to extend it in both directions by half of the interval.
2916 // Interval is calculated based on the number:
2917 // 1. Integers below 10,000 are extended by 0.5: so the [2006-2006] empty range is extended to [2005.5-2006.5] range and the ForsedSingleStop=2006
2918 // 2. Other numbers are extended by half of their power: [700,001-700,001] => [650,001-750,001] and the ForsedSingleStop=null as we want the intervals to be calculated to cover the range.
2919 var value = this.min;
2920 var exp = powerbi.Double.log10(Math.abs(value));
2921 var step = void 0;
2922 if (exp >= 0 && exp < 4) {
2923 step = 0.5;
2924 this.forcedSingleStop = value;
2925 }
2926 else {
2927 step = powerbi.Double.pow10(exp) / 2;
2928 this.forcedSingleStop = null;
2929 }
2930 this.min = value - step;
2931 this.max = value + step;
2932 }
2933 }
2934 };
2935 NumericSequenceRange.prototype._ensureDirection = function () {
2936 if (this.min > this.max) {
2937 var temp = this.min;
2938 this.min = this.max;
2939 this.max = temp;
2940 }
2941 };
2942 NumericSequenceRange.prototype.getSize = function () {
2943 return this.max - this.min;
2944 };
2945 NumericSequenceRange.prototype.shrinkByStep = function (range, step) {
2946 debug.assertValue(range, "range");
2947 debug.assert(step > 0, "step");
2948 var oldCount = this.min / step;
2949 var newCount = range.min / step;
2950 var deltaCount = Math.floor(newCount - oldCount);
2951 this.min += deltaCount * step;
2952 oldCount = this.max / step;
2953 newCount = range.max / step;
2954 deltaCount = Math.ceil(newCount - oldCount);
2955 this.max += deltaCount * step;
2956 };
2957 NumericSequenceRange.calculate = function (dataMin, dataMax, fixedMin, fixedMax, includeZero) {
2958 debug.assert(dataMin <= dataMax, "dataMin should be less or equal to dataMax.");
2959 debug.assert(!fixedMin || !fixedMax || fixedMin <= fixedMax, "fixedMin should be less or equal to fixedMax.");
2960 var result = new NumericSequenceRange();
2961 result.includeZero = includeZero ? true : false;
2962 result.hasDataRange = ValueUtil.hasValue(dataMin) && ValueUtil.hasValue(dataMax);
2963 result.hasFixedMin = ValueUtil.hasValue(fixedMin);
2964 result.hasFixedMax = ValueUtil.hasValue(fixedMax);
2965 dataMin = powerbi.Double.ensureInRange(dataMin, NumericSequenceRange.MIN_SUPPORTED_DOUBLE, NumericSequenceRange.MAX_SUPPORTED_DOUBLE);
2966 dataMax = powerbi.Double.ensureInRange(dataMax, NumericSequenceRange.MIN_SUPPORTED_DOUBLE, NumericSequenceRange.MAX_SUPPORTED_DOUBLE);
2967 // Calculate the range using the min, max, dataRange
2968 if (result.hasFixedMin && result.hasFixedMax) {
2969 result.min = fixedMin;
2970 result.max = fixedMax;
2971 }
2972 else if (result.hasFixedMin) {
2973 result.min = fixedMin;
2974 result.max = dataMax > fixedMin ? dataMax : fixedMin;
2975 }
2976 else if (result.hasFixedMax) {
2977 result.min = dataMin < fixedMax ? dataMin : fixedMax;
2978 result.max = fixedMax;
2979 }
2980 else if (result.hasDataRange) {
2981 result.min = dataMin;
2982 result.max = dataMax;
2983 }
2984 else {
2985 result.min = 0;
2986 result.max = 0;
2987 }
2988 result._ensureIncludeZero();
2989 result._ensureNotEmpty();
2990 result._ensureDirection();
2991 if (result.min === 0) {
2992 result.hasFixedMin = true; // If the range starts from zero we should prevent extending the intervals into the negative range
2993 }
2994 else if (result.max === 0) {
2995 result.hasFixedMax = true; // If the range ends at zero we should prevent extending the intervals into the positive range
2996 }
2997 return result;
2998 };
2999 NumericSequenceRange.calculateDataRange = function (dataMin, dataMax, includeZero) {
3000 if (!ValueUtil.hasValue(dataMin) || !ValueUtil.hasValue(dataMax)) {
3001 return NumericSequenceRange.calculateFixedRange(0, NumericSequenceRange.DEFAULT_MAX);
3002 }
3003 else {
3004 return NumericSequenceRange.calculate(dataMin, dataMax, null, null, includeZero);
3005 }
3006 };
3007 NumericSequenceRange.calculateFixedRange = function (fixedMin, fixedMax, includeZero) {
3008 debug.assertValue(fixedMin, "fixedMin");
3009 debug.assertValue(fixedMax, "fixedMax");
3010 var result = new NumericSequenceRange();
3011 result.hasDataRange = false;
3012 result.includeZero = includeZero;
3013 result.min = fixedMin;
3014 result.max = fixedMax;
3015 result._ensureIncludeZero();
3016 result._ensureNotEmpty();
3017 result._ensureDirection();
3018 result.hasFixedMin = true;
3019 result.hasFixedMax = true;
3020 return result;
3021 };
3022 NumericSequenceRange.DEFAULT_MAX = 10;
3023 NumericSequenceRange.MIN_SUPPORTED_DOUBLE = -1E307;
3024 NumericSequenceRange.MAX_SUPPORTED_DOUBLE = 1E307;
3025 return NumericSequenceRange;
3026 }());
3027 powerbi.NumericSequenceRange = NumericSequenceRange;
3028 /** Note: Exported for testability */
3029 var ValueUtil;
3030 (function (ValueUtil) {
3031 function hasValue(value) {
3032 return value !== undefined && value !== null;
3033 }
3034 ValueUtil.hasValue = hasValue;
3035 })(ValueUtil = powerbi.ValueUtil || (powerbi.ValueUtil = {}));
3036})(powerbi || (powerbi = {}));
3037/*
3038 * Power BI Visualizations
3039 *
3040 * Copyright (c) Microsoft Corporation
3041 * All rights reserved.
3042 * MIT License
3043 *
3044 * Permission is hereby granted, free of charge, to any person obtaining a copy
3045 * of this software and associated documentation files (the ""Software""), to deal
3046 * in the Software without restriction, including without limitation the rights
3047 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3048 * copies of the Software, and to permit persons to whom the Software is
3049 * furnished to do so, subject to the following conditions:
3050 *
3051 * The above copyright notice and this permission notice shall be included in
3052 * all copies or substantial portions of the Software.
3053 *
3054 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3055 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3056 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3057 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3058 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3059 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3060 * THE SOFTWARE.
3061 */
3062var powerbi;
3063(function (powerbi) {
3064 var visuals;
3065 (function (visuals) {
3066 var valueFormatter;
3067 (function (valueFormatter) {
3068 var StringExtensions = jsCommon.StringExtensions;
3069 var BeautifiedFormat = {
3070 '0.00 %;-0.00 %;0.00 %': 'Percentage',
3071 '0.0 %;-0.0 %;0.0 %': 'Percentage1',
3072 };
3073 valueFormatter.DefaultIntegerFormat = 'g';
3074 valueFormatter.DefaultNumericFormat = '#,0.00';
3075 valueFormatter.DefaultDateFormat = 'd';
3076 var defaultLocalizedStrings = {
3077 'NullValue': '(Blank)',
3078 'BooleanTrue': 'True',
3079 'BooleanFalse': 'False',
3080 'NaNValue': 'NaN',
3081 'InfinityValue': '+Infinity',
3082 'NegativeInfinityValue': '-Infinity',
3083 'RestatementComma': '{0}, {1}',
3084 'RestatementCompoundAnd': '{0} and {1}',
3085 'RestatementCompoundOr': '{0} or {1}',
3086 'DisplayUnitSystem_EAuto_Title': 'Auto',
3087 'DisplayUnitSystem_E0_Title': 'None',
3088 'DisplayUnitSystem_E3_LabelFormat': '{0}K',
3089 'DisplayUnitSystem_E3_Title': 'Thousands',
3090 'DisplayUnitSystem_E6_LabelFormat': '{0}M',
3091 'DisplayUnitSystem_E6_Title': 'Millions',
3092 'DisplayUnitSystem_E9_LabelFormat': '{0}bn',
3093 'DisplayUnitSystem_E9_Title': 'Billions',
3094 'DisplayUnitSystem_E12_LabelFormat': '{0}T',
3095 'DisplayUnitSystem_E12_Title': 'Trillions',
3096 'Percentage': '#,0.##%',
3097 'Percentage1': '#,0.#%',
3098 'TableTotalLabel': 'Total',
3099 'Tooltip_HighlightedValueDisplayName': 'Highlighted',
3100 'Funnel_PercentOfFirst': 'Percent of first',
3101 'Funnel_PercentOfPrevious': 'Percent of previous',
3102 'Funnel_PercentOfFirst_Highlight': 'Percent of first (highlighted)',
3103 'Funnel_PercentOfPrevious_Highlight': 'Percent of previous (highlighted)',
3104 // Geotagging strings
3105 'GeotaggingString_Continent': 'continent',
3106 'GeotaggingString_Continents': 'continents',
3107 'GeotaggingString_Country': 'country',
3108 'GeotaggingString_Countries': 'countries',
3109 'GeotaggingString_State': 'state',
3110 'GeotaggingString_States': 'states',
3111 'GeotaggingString_City': 'city',
3112 'GeotaggingString_Cities': 'cities',
3113 'GeotaggingString_Town': 'town',
3114 'GeotaggingString_Towns': 'towns',
3115 'GeotaggingString_Province': 'province',
3116 'GeotaggingString_Provinces': 'provinces',
3117 'GeotaggingString_County': 'county',
3118 'GeotaggingString_Counties': 'counties',
3119 'GeotaggingString_Village': 'village',
3120 'GeotaggingString_Villages': 'villages',
3121 'GeotaggingString_Post': 'post',
3122 'GeotaggingString_Zip': 'zip',
3123 'GeotaggingString_Code': 'code',
3124 'GeotaggingString_Place': 'place',
3125 'GeotaggingString_Places': 'places',
3126 'GeotaggingString_Address': 'address',
3127 'GeotaggingString_Addresses': 'addresses',
3128 'GeotaggingString_Street': 'street',
3129 'GeotaggingString_Streets': 'streets',
3130 'GeotaggingString_Longitude': 'longitude',
3131 'GeotaggingString_Longitude_Short': 'lon',
3132 'GeotaggingString_Latitude': 'latitude',
3133 'GeotaggingString_Latitude_Short': 'lat',
3134 'GeotaggingString_PostalCode': 'postal code',
3135 'GeotaggingString_PostalCodes': 'postal codes',
3136 'GeotaggingString_ZipCode': 'zip code',
3137 'GeotaggingString_ZipCodes': 'zip codes',
3138 'GeotaggingString_Territory': 'territory',
3139 'GeotaggingString_Territories': 'territories',
3140 };
3141 function beautify(format) {
3142 var key = BeautifiedFormat[format];
3143 if (key)
3144 return defaultLocalizedStrings[key] || format;
3145 return format;
3146 }
3147 function describeUnit(exponent) {
3148 var exponentLookup = (exponent === -1) ? 'Auto' : exponent.toString();
3149 var title = defaultLocalizedStrings["DisplayUnitSystem_E" + exponentLookup + "_Title"];
3150 var format = (exponent <= 0) ? '{0}' : defaultLocalizedStrings["DisplayUnitSystem_E" + exponentLookup + "_LabelFormat"];
3151 if (title || format)
3152 return { title: title, format: format };
3153 }
3154 function getLocalizedString(stringId) {
3155 return defaultLocalizedStrings[stringId];
3156 }
3157 valueFormatter.getLocalizedString = getLocalizedString;
3158 // NOTE: Define default locale options, but these can be overriden by setLocaleOptions.
3159 var locale = {
3160 null: defaultLocalizedStrings['NullValue'],
3161 true: defaultLocalizedStrings['BooleanTrue'],
3162 false: defaultLocalizedStrings['BooleanFalse'],
3163 NaN: defaultLocalizedStrings['NaNValue'],
3164 infinity: defaultLocalizedStrings['InfinityValue'],
3165 negativeInfinity: defaultLocalizedStrings['NegativeInfinityValue'],
3166 beautify: function (format) { return beautify(format); },
3167 describe: function (exponent) { return describeUnit(exponent); },
3168 restatementComma: defaultLocalizedStrings['RestatementComma'],
3169 restatementCompoundAnd: defaultLocalizedStrings['RestatementCompoundAnd'],
3170 restatementCompoundOr: defaultLocalizedStrings['RestatementCompoundOr'],
3171 };
3172 var MaxScaledDecimalPlaces = 2;
3173 var MaxValueForDisplayUnitRounding = 1000;
3174 var MinIntegerValueForDisplayUnits = 10000;
3175 var MinPrecisionForDisplayUnits = 2;
3176 var DateTimeMetadataColumn = {
3177 displayName: '',
3178 type: powerbi.ValueType.fromPrimitiveTypeAndCategory(powerbi.PrimitiveType.DateTime),
3179 };
3180 function getFormatMetadata(format) {
3181 return powerbi.NumberFormat.getCustomFormatMetadata(format);
3182 }
3183 valueFormatter.getFormatMetadata = getFormatMetadata;
3184 function setLocaleOptions(options) {
3185 debug.assertValue(options, 'options');
3186 locale = options;
3187 powerbi.DefaultDisplayUnitSystem.reset();
3188 powerbi.WholeUnitsDisplayUnitSystem.reset();
3189 }
3190 valueFormatter.setLocaleOptions = setLocaleOptions;
3191 function createDefaultFormatter(formatString, allowFormatBeautification) {
3192 if (allowFormatBeautification === void 0) { allowFormatBeautification = false; }
3193 var formatBeaut = allowFormatBeautification ? locale.beautify(formatString) : formatString;
3194 return {
3195 format: function (value) {
3196 if (value == null)
3197 return locale.null;
3198 return formatCore(value, formatBeaut);
3199 }
3200 };
3201 }
3202 valueFormatter.createDefaultFormatter = createDefaultFormatter;
3203 /** Creates an IValueFormatter to be used for a range of values. */
3204 function create(options) {
3205 debug.assertValue(options, 'options');
3206 var format = !!options.allowFormatBeautification ? locale.beautify(options.format) : options.format;
3207 if (shouldUseNumericDisplayUnits(options)) {
3208 var displayUnitSystem_1 = createDisplayUnitSystem(options.displayUnitSystemType);
3209 var singleValueFormattingMode_1 = !!options.formatSingleValues;
3210 displayUnitSystem_1.update(Math.max(Math.abs(options.value || 0), Math.abs(options.value2 || 0)));
3211 var forcePrecision_1 = options.precision != null;
3212 var decimals_1;
3213 if (forcePrecision_1)
3214 decimals_1 = -options.precision;
3215 else if (displayUnitSystem_1.displayUnit && displayUnitSystem_1.displayUnit.value > 1)
3216 decimals_1 = -MaxScaledDecimalPlaces;
3217 // Detect axis precision
3218 if (options.detectAxisPrecision) {
3219 // Trailing zeroes
3220 forcePrecision_1 = true;
3221 var axisValue = options.value;
3222 if (displayUnitSystem_1.displayUnit && displayUnitSystem_1.displayUnit.value > 0)
3223 axisValue = axisValue / displayUnitSystem_1.displayUnit.value;
3224 if (powerbi.Double.isInteger(axisValue))
3225 decimals_1 = 0;
3226 else
3227 decimals_1 = powerbi.Double.log10(axisValue);
3228 }
3229 return {
3230 format: function (value) {
3231 var formattedValue = getStringFormat(value, true /*nullsAreBlank*/);
3232 if (!StringExtensions.isNullOrUndefinedOrWhiteSpaceString(formattedValue))
3233 return formattedValue;
3234 // Round to Double.DEFAULT_PRECISION
3235 if (value && !displayUnitSystem_1.isScalingUnit() && Math.abs(value) < MaxValueForDisplayUnitRounding && !forcePrecision_1)
3236 value = powerbi.Double.roundToPrecision(value);
3237 return singleValueFormattingMode_1 ?
3238 displayUnitSystem_1.formatSingleValue(value, format, decimals_1, forcePrecision_1) :
3239 displayUnitSystem_1.format(value, format, decimals_1, forcePrecision_1);
3240 },
3241 displayUnit: displayUnitSystem_1.displayUnit,
3242 options: options
3243 };
3244 }
3245 if (shouldUseDateUnits(options.value, options.value2, options.tickCount)) {
3246 var unit_1 = powerbi.DateTimeSequence.getIntervalUnit(options.value /* minDate */, options.value2 /* maxDate */, options.tickCount);
3247 return {
3248 format: function (value) {
3249 if (value == null)
3250 return locale.null;
3251 var formatString = powerbi.formattingService.dateFormatString(unit_1);
3252 return formatCore(value, formatString);
3253 },
3254 options: options
3255 };
3256 }
3257 return createDefaultFormatter(format);
3258 }
3259 valueFormatter.create = create;
3260 function format(value, format, allowFormatBeautification) {
3261 if (value == null)
3262 return locale.null;
3263 return formatCore(value, !!allowFormatBeautification ? locale.beautify(format) : format);
3264 }
3265 valueFormatter.format = format;
3266 function getValueFormat(value, columnType) {
3267 // If column type not defined or is not datetime
3268 // ...and the value is of time datetime,
3269 // then use the default date format string
3270 if ((!columnType || !columnType.dateTime) && value instanceof Date)
3271 return getFormatString(DateTimeMetadataColumn, null, false);
3272 }
3273 function formatValueColumn(value, column, formatStringProp) {
3274 var valueFormat = getValueFormat(value, column.type);
3275 if (valueFormat)
3276 return formatCore(value, valueFormat);
3277 else
3278 return formatCore(value, getFormatString(column, formatStringProp));
3279 }
3280 valueFormatter.formatValueColumn = formatValueColumn;
3281 function createDisplayUnitSystem(displayUnitSystemType) {
3282 if (displayUnitSystemType == null)
3283 return new powerbi.DefaultDisplayUnitSystem(locale.describe);
3284 switch (displayUnitSystemType) {
3285 case powerbi.DisplayUnitSystemType.Default:
3286 return new powerbi.DefaultDisplayUnitSystem(locale.describe);
3287 case powerbi.DisplayUnitSystemType.WholeUnits:
3288 return new powerbi.WholeUnitsDisplayUnitSystem(locale.describe);
3289 case powerbi.DisplayUnitSystemType.Verbose:
3290 return new powerbi.NoDisplayUnitSystem();
3291 case powerbi.DisplayUnitSystemType.DataLabels:
3292 return new powerbi.DataLabelsDisplayUnitSystem(locale.describe);
3293 default:
3294 debug.assertFail('Unknown display unit system type');
3295 return new powerbi.DefaultDisplayUnitSystem(locale.describe);
3296 }
3297 }
3298 function shouldUseNumericDisplayUnits(options) {
3299 var value = options.value;
3300 var value2 = options.value2;
3301 var format = options.format;
3302 // For singleValue visuals like card, gauge we don't want to roundoff data to the nearest thousands so format the whole number / integers below 10K to not use display units
3303 if (options.formatSingleValues && format) {
3304 if (Math.abs(value) < MinIntegerValueForDisplayUnits) {
3305 var isCustomFormat = !powerbi.NumberFormat.isStandardFormat(format);
3306 if (isCustomFormat) {
3307 var precision = powerbi.NumberFormat.getCustomFormatMetadata(format, true /*calculatePrecision*/).precision;
3308 if (precision < MinPrecisionForDisplayUnits)
3309 return false;
3310 }
3311 else if (powerbi.Double.isInteger(value))
3312 return false;
3313 }
3314 }
3315 if ((typeof value === 'number') || (typeof value2 === 'number')) {
3316 return true;
3317 }
3318 }
3319 function shouldUseDateUnits(value, value2, tickCount) {
3320 // must check both value and value2 because we'll need to get an interval for date units
3321 return (value instanceof Date) && (value2 instanceof Date) && (tickCount !== undefined && tickCount !== null);
3322 }
3323 /*
3324 * Get the column format. Order of precendence is:
3325 * 1. Column format
3326 * 2. Default PowerView policy for column type
3327 */
3328 function getFormatString(column, formatStringProperty, suppressTypeFallback) {
3329 if (column) {
3330 if (formatStringProperty) {
3331 var propertyValue = powerbi.DataViewObjects.getValue(column.objects, formatStringProperty);
3332 if (propertyValue)
3333 return propertyValue;
3334 }
3335 if (!suppressTypeFallback) {
3336 var columnType = column.type;
3337 if (columnType) {
3338 if (columnType.dateTime)
3339 return valueFormatter.DefaultDateFormat;
3340 if (columnType.integer)
3341 return valueFormatter.DefaultIntegerFormat;
3342 if (columnType.numeric)
3343 return valueFormatter.DefaultNumericFormat;
3344 }
3345 }
3346 }
3347 }
3348 valueFormatter.getFormatString = getFormatString;
3349 function formatListCompound(strings, conjunction) {
3350 var result;
3351 if (!strings) {
3352 return null;
3353 }
3354 var length = strings.length;
3355 if (length > 0) {
3356 result = strings[0];
3357 var lastIndex = length - 1;
3358 for (var i = 1, len = lastIndex; i < len; i++) {
3359 var value = strings[i];
3360 result = StringExtensions.format(locale.restatementComma, result, value);
3361 }
3362 if (length > 1) {
3363 var value = strings[lastIndex];
3364 result = StringExtensions.format(conjunction, result, value);
3365 }
3366 }
3367 else {
3368 result = null;
3369 }
3370 return result;
3371 }
3372 /** The returned string will look like 'A, B, ..., and C' */
3373 function formatListAnd(strings) {
3374 return formatListCompound(strings, locale.restatementCompoundAnd);
3375 }
3376 valueFormatter.formatListAnd = formatListAnd;
3377 /** The returned string will look like 'A, B, ..., or C' */
3378 function formatListOr(strings) {
3379 return formatListCompound(strings, locale.restatementCompoundOr);
3380 }
3381 valueFormatter.formatListOr = formatListOr;
3382 function formatCore(value, format) {
3383 var formattedValue = getStringFormat(value, false /*nullsAreBlank*/);
3384 if (!StringExtensions.isNullOrUndefinedOrWhiteSpaceString(formattedValue))
3385 return formattedValue;
3386 return powerbi.formattingService.formatValue(value, format);
3387 }
3388 function getStringFormat(value, nullsAreBlank) {
3389 if (value == null && nullsAreBlank)
3390 return locale.null;
3391 if (value === true)
3392 return locale.true;
3393 if (value === false)
3394 return locale.false;
3395 if (typeof value === 'number' && isNaN(value))
3396 return locale.NaN;
3397 if (value === Number.NEGATIVE_INFINITY)
3398 return locale.negativeInfinity;
3399 if (value === Number.POSITIVE_INFINITY)
3400 return locale.infinity;
3401 return '';
3402 }
3403 function getDisplayUnits(displayUnitSystemType) {
3404 var displayUnitSystem = createDisplayUnitSystem(displayUnitSystemType);
3405 return displayUnitSystem.units;
3406 }
3407 valueFormatter.getDisplayUnits = getDisplayUnits;
3408 })(valueFormatter = visuals.valueFormatter || (visuals.valueFormatter = {}));
3409 })(visuals = powerbi.visuals || (powerbi.visuals = {}));
3410})(powerbi || (powerbi = {}));
3411/*
3412 * Power BI Visualizations
3413 *
3414 * Copyright (c) Microsoft Corporation
3415 * All rights reserved.
3416 * MIT License
3417 *
3418 * Permission is hereby granted, free of charge, to any person obtaining a copy
3419 * of this software and associated documentation files (the ""Software""), to deal
3420 * in the Software without restriction, including without limitation the rights
3421 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3422 * copies of the Software, and to permit persons to whom the Software is
3423 * furnished to do so, subject to the following conditions:
3424 *
3425 * The above copyright notice and this permission notice shall be included in
3426 * all copies or substantial portions of the Software.
3427 *
3428 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3429 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3430 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3431 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3432 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3433 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3434 * THE SOFTWARE.
3435 */
3436/*
3437 * Power BI Visualizations
3438 *
3439 * Copyright (c) Microsoft Corporation
3440 * All rights reserved.
3441 * MIT License
3442 *
3443 * Permission is hereby granted, free of charge, to any person obtaining a copy
3444 * of this software and associated documentation files (the ""Software""), to deal
3445 * in the Software without restriction, including without limitation the rights
3446 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3447 * copies of the Software, and to permit persons to whom the Software is
3448 * furnished to do so, subject to the following conditions:
3449 *
3450 * The above copyright notice and this permission notice shall be included in
3451 * all copies or substantial portions of the Software.
3452 *
3453 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3454 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3455 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3456 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3457 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3458 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3459 * THE SOFTWARE.
3460 */
3461/*
3462 * Power BI Visualizations
3463 *
3464 * Copyright (c) Microsoft Corporation
3465 * All rights reserved.
3466 * MIT License
3467 *
3468 * Permission is hereby granted, free of charge, to any person obtaining a copy
3469 * of this software and associated documentation files (the ""Software""), to deal
3470 * in the Software without restriction, including without limitation the rights
3471 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3472 * copies of the Software, and to permit persons to whom the Software is
3473 * furnished to do so, subject to the following conditions:
3474 *
3475 * The above copyright notice and this permission notice shall be included in
3476 * all copies or substantial portions of the Software.
3477 *
3478 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3479 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3480 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3481 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3482 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3483 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3484 * THE SOFTWARE.
3485 */
3486var powerbi;
3487(function (powerbi) {
3488 var data;
3489 (function (data) {
3490 var DataRoleHelper;
3491 (function (DataRoleHelper) {
3492 function getMeasureIndexOfRole(grouped, roleName) {
3493 if (!_.isEmpty(grouped)) {
3494 var firstGroup = grouped[0];
3495 if (firstGroup.values && firstGroup.values.length > 0) {
3496 for (var i = 0, len = firstGroup.values.length; i < len; ++i) {
3497 var value = firstGroup.values[i];
3498 if (value && value.source) {
3499 if (hasRole(value.source, roleName))
3500 return i;
3501 }
3502 }
3503 }
3504 }
3505 return -1;
3506 }
3507 DataRoleHelper.getMeasureIndexOfRole = getMeasureIndexOfRole;
3508 function getCategoryIndexOfRole(categories, roleName) {
3509 if (!_.isEmpty(categories)) {
3510 for (var i = 0, ilen = categories.length; i < ilen; i++) {
3511 if (hasRole(categories[i].source, roleName))
3512 return i;
3513 }
3514 }
3515 return -1;
3516 }
3517 DataRoleHelper.getCategoryIndexOfRole = getCategoryIndexOfRole;
3518 function hasRole(column, name) {
3519 var roles = column.roles;
3520 return roles && roles[name];
3521 }
3522 DataRoleHelper.hasRole = hasRole;
3523 function hasRoleInDataView(dataView, name) {
3524 return dataView != null
3525 && dataView.metadata != null
3526 && dataView.metadata.columns
3527 && _.any(dataView.metadata.columns, function (c) { return c.roles && c.roles[name] !== undefined; });
3528 }
3529 DataRoleHelper.hasRoleInDataView = hasRoleInDataView;
3530 function hasRoleInValueColumn(valueColumn, name) {
3531 return valueColumn && valueColumn.source && valueColumn.source.roles && (valueColumn.source.roles[name] === true);
3532 }
3533 DataRoleHelper.hasRoleInValueColumn = hasRoleInValueColumn;
3534 })(DataRoleHelper = data.DataRoleHelper || (data.DataRoleHelper = {}));
3535 })(data = powerbi.data || (powerbi.data = {}));
3536})(powerbi || (powerbi = {}));
3537/*
3538 * Power BI Visualizations
3539 *
3540 * Copyright (c) Microsoft Corporation
3541 * All rights reserved.
3542 * MIT License
3543 *
3544 * Permission is hereby granted, free of charge, to any person obtaining a copy
3545 * of this software and associated documentation files (the ""Software""), to deal
3546 * in the Software without restriction, including without limitation the rights
3547 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3548 * copies of the Software, and to permit persons to whom the Software is
3549 * furnished to do so, subject to the following conditions:
3550 *
3551 * The above copyright notice and this permission notice shall be included in
3552 * all copies or substantial portions of the Software.
3553 *
3554 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3555 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3556 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3557 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3558 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3559 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3560 * THE SOFTWARE.
3561 */
3562var powerbi;
3563(function (powerbi) {
3564 var data;
3565 (function (data) {
3566 var DataRoleHelper = powerbi.data.DataRoleHelper;
3567 function createIDataViewCategoricalReader(dataView) {
3568 return new DataViewCategoricalReader(dataView);
3569 }
3570 data.createIDataViewCategoricalReader = createIDataViewCategoricalReader;
3571 var DataViewCategoricalReader = (function () {
3572 function DataViewCategoricalReader(dataView) {
3573 debug.assertValue(dataView, 'dataView');
3574 this.dataView = dataView;
3575 // Validate categories
3576 var categorical;
3577 if (dataView)
3578 categorical = dataView.categorical;
3579 var categories;
3580 if (categorical)
3581 categories = this.categories = categorical.categories;
3582 this.hasValidCategories = !_.isEmpty(categories);
3583 // Validate values
3584 var values;
3585 if (categorical)
3586 values = categorical.values;
3587 // We need to access grouped as long as values is non-null; if it's an empty array (meaning there is a category + series), we'll use grouped for non-value stuff
3588 // TODO: think a bit more about how to represent this internally; Maybe split this up between hasGroup and hasValidValues or something
3589 this.hasAnyValidValues = false;
3590 if (values != null) {
3591 var grouped = dataView.categorical.values.grouped();
3592 if (grouped.length > 0) {
3593 this.hasAnyValidValues = true;
3594 this.grouped = grouped;
3595 // Iterate through the first group's values to populate the valueRoleIndexMapping
3596 var valueRoleIndexMapping = {};
3597 var firstGroupValues = grouped[0].values;
3598 for (var valueIndex = 0, valueCount = firstGroupValues.length; valueIndex < valueCount; valueIndex++) {
3599 var valueRoles = firstGroupValues[valueIndex].source.roles;
3600 for (var role in valueRoles) {
3601 if (valueRoles[role]) {
3602 if (!valueRoleIndexMapping[role])
3603 valueRoleIndexMapping[role] = [];
3604 valueRoleIndexMapping[role].push(valueIndex);
3605 }
3606 }
3607 }
3608 this.valueRoleIndexMapping = valueRoleIndexMapping;
3609 }
3610 }
3611 if (this.hasAnyValidValues)
3612 this.dataHasDynamicSeries = !!this.dataView.categorical.values.source;
3613 }
3614 // Category methods
3615 DataViewCategoricalReader.prototype.hasCategories = function () {
3616 return this.hasValidCategories;
3617 };
3618 DataViewCategoricalReader.prototype.getCategoryCount = function () {
3619 if (this.hasValidCategories)
3620 return this.categories[0].values.length;
3621 else
3622 return 0;
3623 };
3624 DataViewCategoricalReader.prototype.getCategoryValues = function (roleName) {
3625 if (this.hasValidCategories) {
3626 var categories = this.getCategoryFromRole(roleName);
3627 return categories ? categories.values : undefined;
3628 }
3629 };
3630 DataViewCategoricalReader.prototype.getCategoryValue = function (roleName, categoryIndex) {
3631 if (this.hasValidCategories) {
3632 var categories = this.getCategoryFromRole(roleName);
3633 return categories ? categories.values[categoryIndex] : undefined;
3634 }
3635 };
3636 DataViewCategoricalReader.prototype.getCategoryColumn = function (roleName) {
3637 if (this.hasValidCategories)
3638 return this.getCategoryFromRole(roleName);
3639 };
3640 DataViewCategoricalReader.prototype.getCategoryMetadataColumn = function (roleName) {
3641 if (this.hasValidCategories) {
3642 var categories = this.getCategoryFromRole(roleName);
3643 return categories ? categories.source : undefined;
3644 }
3645 };
3646 DataViewCategoricalReader.prototype.getCategoryColumnIdentityFields = function (roleName) {
3647 if (this.hasValidCategories) {
3648 var categories = this.getCategoryFromRole(roleName);
3649 return categories ? categories.identityFields : undefined;
3650 }
3651 };
3652 DataViewCategoricalReader.prototype.getCategoryDisplayName = function (roleName) {
3653 if (this.hasValidCategories) {
3654 var targetColumn = this.getCategoryColumn(roleName);
3655 if (targetColumn && targetColumn.source) {
3656 return targetColumn.source.displayName;
3657 }
3658 }
3659 };
3660 DataViewCategoricalReader.prototype.hasCompositeCategories = function () {
3661 if (this.hasValidCategories)
3662 return this.categories.length > 1;
3663 };
3664 DataViewCategoricalReader.prototype.hasCategoryWithRole = function (roleName) {
3665 return DataRoleHelper.getCategoryIndexOfRole(this.categories, roleName) !== -1;
3666 };
3667 DataViewCategoricalReader.prototype.getCategoryObjects = function (roleName, categoryIndex) {
3668 if (this.hasValidCategories) {
3669 var category = this.getCategoryFromRole(roleName);
3670 if (category && category.objects) {
3671 return category.objects[categoryIndex];
3672 }
3673 }
3674 };
3675 DataViewCategoricalReader.prototype.getCategoryFromRole = function (roleName) {
3676 var categories = this.categories;
3677 return categories[DataRoleHelper.getCategoryIndexOfRole(categories, roleName)];
3678 };
3679 // Value and measure methods
3680 DataViewCategoricalReader.prototype.hasValues = function (roleName) {
3681 return this.valueRoleIndexMapping && !_.isEmpty(this.valueRoleIndexMapping[roleName]);
3682 };
3683 DataViewCategoricalReader.prototype.getValue = function (roleName, categoryIndex, seriesIndex) {
3684 if (seriesIndex === void 0) { seriesIndex = 0; }
3685 if (this.hasValues(roleName)) {
3686 if (this.dataHasDynamicSeries) {
3687 // For dynamic series, we only ever obtain the first value column from a role
3688 return this.getValueInternal(roleName, categoryIndex, seriesIndex, 0, false /* getHighlight */);
3689 }
3690 else {
3691 // For static series or single series, we obtain value columns from the first series
3692 // and use the seriesIndex to index into the value columns within the role
3693 return this.getValueInternal(roleName, categoryIndex, 0, seriesIndex, false /* getHighlight */);
3694 }
3695 }
3696 };
3697 DataViewCategoricalReader.prototype.getHighlight = function (roleName, categoryIndex, seriesIndex) {
3698 if (seriesIndex === void 0) { seriesIndex = 0; }
3699 if (this.hasValues(roleName)) {
3700 if (this.dataHasDynamicSeries) {
3701 // For dynamic series, we only ever obtain the first value column from a role
3702 return this.getValueInternal(roleName, categoryIndex, seriesIndex, 0, true /* getHighlight */);
3703 }
3704 else {
3705 // For static series or single series, we obtain value columns from the first series
3706 // and use the seriesIndex to index into the value columns within the role
3707 return this.getValueInternal(roleName, categoryIndex, 0, seriesIndex, true /* getHighlight */);
3708 }
3709 }
3710 };
3711 DataViewCategoricalReader.prototype.getAllValuesForRole = function (roleName, categoryIndex, seriesIndex) {
3712 if (seriesIndex === void 0) { seriesIndex = 0; }
3713 if (this.hasValues(roleName)) {
3714 var valuesInRole = [];
3715 for (var roleValueIndex = void 0, roleValueCount = this.valueRoleIndexMapping[roleName].length; roleValueIndex < roleValueCount; roleValueIndex++) {
3716 valuesInRole.push(this.getValueInternal(roleName, categoryIndex, seriesIndex, roleValueIndex, false /* getHighlight */));
3717 }
3718 return valuesInRole;
3719 }
3720 };
3721 DataViewCategoricalReader.prototype.getAllHighlightsForRole = function (roleName, categoryIndex, seriesIndex) {
3722 if (seriesIndex === void 0) { seriesIndex = 0; }
3723 if (this.hasValues(roleName)) {
3724 var valuesInRole = [];
3725 for (var roleValueIndex = void 0, roleValueCount = this.valueRoleIndexMapping[roleName].length; roleValueIndex < roleValueCount; roleValueIndex++) {
3726 valuesInRole.push(this.getValueInternal(roleName, categoryIndex, seriesIndex, roleValueIndex, true /* getHighlight */));
3727 }
3728 return valuesInRole;
3729 }
3730 };
3731 /**
3732 * Obtains the value from grouped.
3733 *
3734 * Grouped: [0] [1] [2] [3] (seriesIndex)
3735 * / \
3736 * .values: [T0] [V0] [V1] [T1] [V2] (valueColumnIndex)
3737 * / \ \ \
3738 * v.values: [0, 1, 2, 3, 4] [5, 6, 7, 8, 9] (categoryIndex)
3739 *
3740 *--------------------------------|
3741 * |Category |
3742 * Series|Value Columns |A B C D E|
3743 *--------------------------------|
3744 * 0|col0 (tooltip)| |
3745 * |col1 (value) | |
3746 * |col2 (value) | |
3747 * |col3 (tooltip)| |
3748 * |col4 (value) | |
3749 *--------------------------------|
3750 * 1|col0 (tooltip)| |
3751 * |col1 (value) |0 1 2 3 4|
3752 * |col2 (value) |5 6 7 8 9|
3753 * |col3 (tooltip)| |
3754 * |col4 (value) | |
3755 *--------------------------------|
3756 * 2|col0 (tooltip)|... |
3757 *
3758 * valueColumnIndexInRole is for indexing into the values for a single role
3759 * valueColumnIndex is for indexing into the entire value array including
3760 * all roles
3761 *
3762 * The valueRoleIndexMapping converts roleValueIndex and role (value role
3763 * with an index of 1) into groupedValueIndex (2)
3764 *
3765 * Example: getValueInternal(V, 3, 1, 1) returns 8: The second group,
3766 * the second value column with role "value" (which is converted to a
3767 * groupedValueIndex of 2) and the fourth value within that value column.
3768 */
3769 DataViewCategoricalReader.prototype.getValueInternal = function (roleName, categoryIndex, groupIndex, valueColumnIndexInRole, getHighlight) {
3770 if (this.hasValues(roleName)) {
3771 var valueColumnIndex = this.valueRoleIndexMapping[roleName][valueColumnIndexInRole];
3772 var groupedValues = this.grouped[groupIndex].values[valueColumnIndex];
3773 return getHighlight ? groupedValues.highlights[categoryIndex] : groupedValues.values[categoryIndex];
3774 }
3775 };
3776 DataViewCategoricalReader.prototype.getFirstNonNullValueForCategory = function (roleName, categoryIndex) {
3777 if (this.hasValues(roleName)) {
3778 if (!this.dataHasDynamicSeries) {
3779 debug.assert(this.grouped.length === 1, "getFirstNonNullValueForCategory shouldn't be called if you have a static series");
3780 return this.getValue(roleName, categoryIndex);
3781 }
3782 for (var seriesIndex = 0, seriesCount = this.grouped.length; seriesIndex < seriesCount; seriesIndex++) {
3783 var value = this.getValue(roleName, categoryIndex, seriesIndex);
3784 if (value != null) {
3785 return value;
3786 }
3787 }
3788 }
3789 };
3790 DataViewCategoricalReader.prototype.getMeasureQueryName = function (roleName) {
3791 if (this.hasValues(roleName))
3792 return this.grouped[0].values[this.valueRoleIndexMapping[roleName][0]].source.queryName;
3793 };
3794 DataViewCategoricalReader.prototype.getValueColumn = function (roleName, seriesIndex) {
3795 if (seriesIndex === void 0) { seriesIndex = 0; }
3796 if (this.hasValues(roleName)) {
3797 if (this.dataHasDynamicSeries) {
3798 return this.grouped[seriesIndex].values[this.valueRoleIndexMapping[roleName][0]];
3799 }
3800 else {
3801 return this.grouped[0].values[this.valueRoleIndexMapping[roleName][seriesIndex]];
3802 }
3803 }
3804 };
3805 DataViewCategoricalReader.prototype.getValueMetadataColumn = function (roleName, seriesIndex) {
3806 if (seriesIndex === void 0) { seriesIndex = 0; }
3807 var valueColumn = this.getValueColumn(roleName, seriesIndex);
3808 if (valueColumn) {
3809 return valueColumn.source;
3810 }
3811 };
3812 DataViewCategoricalReader.prototype.getValueDisplayName = function (roleName, seriesIndex) {
3813 if (this.hasValues(roleName)) {
3814 var targetColumn = this.getValueColumn(roleName, seriesIndex);
3815 if (targetColumn && targetColumn.source) {
3816 return targetColumn.source.displayName;
3817 }
3818 }
3819 };
3820 // Series methods
3821 DataViewCategoricalReader.prototype.hasDynamicSeries = function () {
3822 return this.dataHasDynamicSeries;
3823 };
3824 DataViewCategoricalReader.prototype.getSeriesCount = function (valueRoleName) {
3825 if (this.hasAnyValidValues) {
3826 if (this.dataHasDynamicSeries) {
3827 return this.grouped.length;
3828 }
3829 else if (valueRoleName) {
3830 return this.valueRoleIndexMapping[valueRoleName].length;
3831 }
3832 else {
3833 return 1;
3834 }
3835 }
3836 };
3837 DataViewCategoricalReader.prototype.getSeriesObjects = function (seriesIndex) {
3838 if (this.hasAnyValidValues)
3839 return this.grouped[seriesIndex].objects;
3840 };
3841 DataViewCategoricalReader.prototype.getSeriesValueColumns = function () {
3842 if (this.hasAnyValidValues)
3843 return this.dataView.categorical.values;
3844 };
3845 DataViewCategoricalReader.prototype.getSeriesValueColumnGroup = function (seriesIndex) {
3846 if (this.hasAnyValidValues)
3847 return this.grouped[seriesIndex];
3848 };
3849 DataViewCategoricalReader.prototype.getSeriesMetadataColumn = function () {
3850 if (this.hasAnyValidValues)
3851 return this.dataView.categorical.values.source;
3852 };
3853 DataViewCategoricalReader.prototype.getSeriesColumnIdentityFields = function () {
3854 if (this.hasAnyValidValues)
3855 return this.dataView.categorical.values.identityFields;
3856 };
3857 DataViewCategoricalReader.prototype.getSeriesName = function (seriesIndex) {
3858 if (this.hasAnyValidValues)
3859 return this.grouped[seriesIndex].name;
3860 };
3861 DataViewCategoricalReader.prototype.getSeriesDisplayName = function () {
3862 if (this.hasAnyValidValues && this.dataHasDynamicSeries)
3863 return this.dataView.categorical.values.source.displayName;
3864 };
3865 return DataViewCategoricalReader;
3866 }());
3867 })(data = powerbi.data || (powerbi.data = {}));
3868})(powerbi || (powerbi = {}));
3869/*
3870 * Power BI Visualizations
3871 *
3872 * Copyright (c) Microsoft Corporation
3873 * All rights reserved.
3874 * MIT License
3875 *
3876 * Permission is hereby granted, free of charge, to any person obtaining a copy
3877 * of this software and associated documentation files (the ""Software""), to deal
3878 * in the Software without restriction, including without limitation the rights
3879 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3880 * copies of the Software, and to permit persons to whom the Software is
3881 * furnished to do so, subject to the following conditions:
3882 *
3883 * The above copyright notice and this permission notice shall be included in
3884 * all copies or substantial portions of the Software.
3885 *
3886 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3887 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3888 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3889 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3890 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3891 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3892 * THE SOFTWARE.
3893 */
3894var powerbi;
3895(function (powerbi) {
3896 var data;
3897 (function (data) {
3898 var inherit = powerbi.Prototype.inherit;
3899 var inheritSingle = powerbi.Prototype.inheritSingle;
3900 var valueFormatter = powerbi.visuals.valueFormatter;
3901 var DataViewConcatenateCategoricalColumns;
3902 (function (DataViewConcatenateCategoricalColumns) {
3903 function detectAndApply(dataView, objectDescriptors, roleMappings, projectionOrdering, selects, projectionActiveItems) {
3904 debug.assertValue(dataView, 'dataView');
3905 debug.assertAnyValue(roleMappings, 'roleMappings');
3906 debug.assertAnyValue(projectionOrdering, 'projectionOrdering');
3907 var result = dataView;
3908 var dataViewCategorical = dataView.categorical;
3909 if (dataViewCategorical) {
3910 var concatenationSource = detectCategoricalRoleForHierarchicalGroup(dataViewCategorical, dataView.metadata, roleMappings, selects, projectionActiveItems);
3911 if (concatenationSource) {
3912 // Consider: Perhaps the re-ordering of categorical columns should happen in the function transformSelects(...) of dataViewTransform?
3913 var columnsSortedByProjectionOrdering = sortColumnsByProjectionOrdering(projectionOrdering, concatenationSource.roleName, concatenationSource.categories);
3914 if (columnsSortedByProjectionOrdering.length >= 2) {
3915 var activeItemsToIgnoreInConcatenation = _.chain(projectionActiveItems[concatenationSource.roleName])
3916 .filter(function (activeItemInfo) { return activeItemInfo.suppressConcat; })
3917 .map(function (activeItemInfo) { return activeItemInfo.queryRef; })
3918 .value();
3919 result = applyConcatenation(dataView, objectDescriptors, concatenationSource.roleName, columnsSortedByProjectionOrdering, activeItemsToIgnoreInConcatenation);
3920 }
3921 }
3922 }
3923 return result;
3924 }
3925 DataViewConcatenateCategoricalColumns.detectAndApply = detectAndApply;
3926 /** For applying concatenation to the DataViewCategorical that is the data for one of the frames in a play chart. */
3927 function applyToPlayChartCategorical(metadata, objectDescriptors, categoryRoleName, categorical) {
3928 debug.assertValue(metadata, 'metadata');
3929 debug.assertAnyValue(objectDescriptors, 'objectDescriptors');
3930 debug.assertValue(categorical, 'categorical');
3931 var result;
3932 if (!_.isEmpty(categorical.categories) && categorical.categories.length >= 2) {
3933 // In PlayChart, the code converts the Visual DataView with a matrix into multiple Visual DataViews, each with a categorical.
3934 // metadata and metadata.columns could already be inherited objects as they come from the Visual DataView with a matrix.
3935 // To guarantee that this method does not have any side effect on prototypeMetadata (which might already be an inherited obj),
3936 // use inherit() rather than inheritSingle() here.
3937 var transformingColumns_1 = inherit(metadata.columns);
3938 var transformingMetadata = inherit(metadata, function (m) { m.columns = transformingColumns_1; });
3939 var transformingDataView = { metadata: transformingMetadata, categorical: categorical };
3940 result = applyConcatenation(transformingDataView, objectDescriptors, categoryRoleName, categorical.categories, []);
3941 }
3942 else {
3943 result = { metadata: metadata, categorical: categorical };
3944 }
3945 return result;
3946 }
3947 DataViewConcatenateCategoricalColumns.applyToPlayChartCategorical = applyToPlayChartCategorical;
3948 /**
3949 * Returns the role and its assocated category columns (from dataViewCategorical.categories)
3950 * that should be concatenated for the case of hierarchical group.
3951 *
3952 * Note: In the future if we support sibling hierarchical groups in categorical,
3953 * change the return type to CategoryColumnsByRole[] and update detection logic.
3954 */
3955 function detectCategoricalRoleForHierarchicalGroup(dataViewCategorical, metadata, dataViewMappings, selects, projectionActiveItems) {
3956 debug.assertValue(dataViewCategorical, 'dataViewCategorical');
3957 debug.assertAnyValue(dataViewMappings, 'dataViewMappings');
3958 var result;
3959 var roleKinds = data.DataViewSelectTransform.createRoleKindFromMetadata(selects, metadata);
3960 var projections = data.DataViewSelectTransform.projectionsFromSelects(selects, projectionActiveItems);
3961 var supportedRoleMappings = powerbi.DataViewAnalysis.chooseDataViewMappings(projections, dataViewMappings, roleKinds).supportedMappings;
3962 // The following code will choose a role name only if all supportedRoleMappings share the same role for Categorical Category.
3963 // Handling multiple supportedRoleMappings is necessary for TransformActions with splits, which can happen in scenarios such as:
3964 // 1. combo chart with a field for both Line and Column values, and
3965 // 2. chart with regression line enabled.
3966 // In case 1, you can pretty much get exactly the one from supportedRoleMappings for which this code is currently processing for,
3967 // by looking at the index of the current split in DataViewTransformActions.splits.
3968 // In case 2, however, supportedRoleMappings.length will be different than DataViewTransformActions.splits.length, hence it is
3969 // not straight forward to figure out for which one in supportedRoleMappings is this code currently processing.
3970 // SO... This code will just choose the category role name if it is consistent across all supportedRoleMappings.
3971 var isEveryRoleMappingForCategorical = !_.isEmpty(supportedRoleMappings) &&
3972 _.every(supportedRoleMappings, function (roleMapping) { return !!roleMapping.categorical; });
3973 if (isEveryRoleMappingForCategorical) {
3974 var targetRoleName_1 = getSingleCategoryRoleNameInEveryRoleMapping(supportedRoleMappings);
3975 if (targetRoleName_1 &&
3976 isVisualExpectingMaxOneCategoryColumn(targetRoleName_1, supportedRoleMappings)) {
3977 var categoryColumnsForTargetRole_1 = _.filter(dataViewCategorical.categories, function (categoryColumn) { return categoryColumn.source.roles && !!categoryColumn.source.roles[targetRoleName_1]; });
3978 // There is no need to concatenate columns unless there is actually more than one column
3979 if (categoryColumnsForTargetRole_1.length >= 2) {
3980 // At least for now, we expect all category columns for the same role to have the same number of value entries.
3981 // If that's not the case, we won't run the concatenate logic for that role at all...
3982 var areValuesCountsEqual = _.every(categoryColumnsForTargetRole_1, function (categoryColumn) { return categoryColumn.values.length === categoryColumnsForTargetRole_1[0].values.length; });
3983 if (areValuesCountsEqual) {
3984 result = {
3985 roleName: targetRoleName_1,
3986 categories: categoryColumnsForTargetRole_1,
3987 };
3988 }
3989 }
3990 }
3991 }
3992 return result;
3993 }
3994 /** If all mappings in the specified roleMappings have the same single role name for their categorical category roles, return that role name, else returns undefined. */
3995 function getSingleCategoryRoleNameInEveryRoleMapping(categoricalRoleMappings) {
3996 debug.assertNonEmpty(categoricalRoleMappings, 'categoricalRoleMappings');
3997 debug.assert(_.every(categoricalRoleMappings, function (roleMapping) { return !!roleMapping.categorical; }), 'All mappings in categoricalRoleMappings must contain a DataViewCategoricalMapping');
3998 var result;
3999 // With "list" in role mapping, it is possible to have multiple role names for category.
4000 // For now, proceed to concatenate category columns only when categories are bound to 1 Role.
4001 // We can change this if we want to support independent (sibling) group hierarchies in categorical.
4002 var uniqueCategoryRoles = _.chain(categoricalRoleMappings)
4003 .map(function (roleMapping) {
4004 var categoryRoles = getAllRolesInCategories(roleMapping.categorical);
4005 return categoryRoles.length === 1 ? categoryRoles[0] : undefined;
4006 })
4007 .uniq() // Note: _.uniq() does not treat two arrays with same elements as equal
4008 .value();
4009 var isSameCategoryRoleNameInAllRoleMappings = uniqueCategoryRoles.length === 1 && !_.isUndefined(uniqueCategoryRoles[0]);
4010 if (isSameCategoryRoleNameInAllRoleMappings) {
4011 result = uniqueCategoryRoles[0];
4012 }
4013 return result;
4014 }
4015 function isVisualExpectingMaxOneCategoryColumn(categoricalRoleName, roleMappings) {
4016 debug.assertValue(categoricalRoleName, 'categoricalRoleName');
4017 debug.assertNonEmpty(roleMappings, 'roleMappings');
4018 var isVisualExpectingMaxOneCategoryColumn = _.every(roleMappings, function (roleMapping) {
4019 return !_.isEmpty(roleMapping.conditions) &&
4020 _.every(roleMapping.conditions, function (condition) { return condition[categoricalRoleName] && condition[categoricalRoleName].max === 1; });
4021 });
4022 return isVisualExpectingMaxOneCategoryColumn;
4023 }
4024 /**
4025 * Returns the array of role names that are mapped to categorical categories.
4026 * Returns an empty array if none exists.
4027 */
4028 function getAllRolesInCategories(categoricalRoleMapping) {
4029 debug.assertValue(categoricalRoleMapping, 'categoricalRoleMapping');
4030 var roleNames = [];
4031 powerbi.DataViewMapping.visitCategoricalCategories(categoricalRoleMapping.categories, {
4032 visitRole: function (roleName) {
4033 roleNames.push(roleName);
4034 }
4035 });
4036 return roleNames;
4037 }
4038 function applyConcatenation(dataView, objectDescriptors, roleName, columnsSortedByProjectionOrdering, queryRefsToIgnore) {
4039 debug.assertValue(dataView, 'dataView');
4040 debug.assertAnyValue(objectDescriptors, 'objectDescriptors');
4041 debug.assertValue(roleName, 'roleName');
4042 debug.assert(columnsSortedByProjectionOrdering && columnsSortedByProjectionOrdering.length >= 2, 'columnsSortedByProjectionOrdering && columnsSortedByProjectionOrdering.length >= 2');
4043 var formatStringPropId = data.DataViewObjectDescriptors.findFormatString(objectDescriptors);
4044 var concatenatedValues = concatenateValues(columnsSortedByProjectionOrdering, queryRefsToIgnore, formatStringPropId);
4045 var columnsSourceSortedByProjectionOrdering = _.map(columnsSortedByProjectionOrdering, function (categoryColumn) { return categoryColumn.source; });
4046 var concatenatedColumnMetadata = createConcatenatedColumnMetadata(roleName, columnsSourceSortedByProjectionOrdering, queryRefsToIgnore);
4047 var transformedDataView = inheritSingle(dataView);
4048 addToMetadata(transformedDataView, concatenatedColumnMetadata);
4049 var concatenatedCategoryColumn = createConcatenatedCategoryColumn(columnsSortedByProjectionOrdering, concatenatedColumnMetadata, concatenatedValues);
4050 var dataViewCategorical = dataView.categorical;
4051 var transformedCategoricalCategories = _.difference(dataViewCategorical.categories, columnsSortedByProjectionOrdering);
4052 transformedCategoricalCategories.push(concatenatedCategoryColumn);
4053 var transformedCategorical = inheritSingle(dataViewCategorical);
4054 transformedCategorical.categories = transformedCategoricalCategories;
4055 transformedDataView.categorical = transformedCategorical;
4056 return transformedDataView;
4057 }
4058 function concatenateValues(columnsSortedByProjectionOrdering, queryRefsToIgnore, formatStringPropId) {
4059 debug.assertValue(columnsSortedByProjectionOrdering, 'columnsSortedByProjectionOrdering');
4060 debug.assertAnyValue(queryRefsToIgnore, 'queryRefsToIgnore');
4061 debug.assertAnyValue(formatStringPropId, 'formatStringPropId');
4062 var concatenatedValues = [];
4063 // concatenate the values in dataViewCategorical.categories[0..length-1].values[j], and store it in combinedValues[j]
4064 for (var _i = 0, columnsSortedByProjectionOrdering_1 = columnsSortedByProjectionOrdering; _i < columnsSortedByProjectionOrdering_1.length; _i++) {
4065 var categoryColumn = columnsSortedByProjectionOrdering_1[_i];
4066 var formatString = valueFormatter.getFormatString(categoryColumn.source, formatStringPropId);
4067 for (var i = 0, len = categoryColumn.values.length; i < len; i++) {
4068 if (!_.contains(queryRefsToIgnore, categoryColumn.source.queryName)) {
4069 var value = categoryColumn.values && categoryColumn.values[i];
4070 var formattedValue = valueFormatter.format(value, formatString);
4071 concatenatedValues[i] = (concatenatedValues[i] === undefined) ? formattedValue : (formattedValue + ' ' + concatenatedValues[i]);
4072 }
4073 }
4074 }
4075 return concatenatedValues;
4076 }
4077 /**
4078 * Returns a new array of elements from columns as they are ordered for the specified roleName in the specified projectionOrdering.
4079 */
4080 function sortColumnsByProjectionOrdering(projectionOrdering, roleName, columns) {
4081 debug.assertAnyValue(projectionOrdering, 'projectionOrdering');
4082 debug.assertValue(roleName, 'roleName');
4083 debug.assertValue(columns, 'columns');
4084 var columnsInProjectionOrdering;
4085 if (projectionOrdering) {
4086 // the numeric values in projectionOrdering correspond to the index property of DataViewMetadataColumn
4087 var columnsByIndex_1 = {};
4088 for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {
4089 var column = columns_1[_i];
4090 if (column.source.roles[roleName]) {
4091 debug.assert(!columnsByIndex_1[column.source.index], 'The specified columns should not contain multiple columns with same index: ' + column.source.index);
4092 columnsByIndex_1[column.source.index] = column;
4093 }
4094 }
4095 var columnIndicesInProjectionOrdering = projectionOrdering[roleName];
4096 columnsInProjectionOrdering = _.chain(columnIndicesInProjectionOrdering)
4097 .map(function (columnIndex) { return columnsByIndex_1[columnIndex]; })
4098 .filter(function (column) { return !!column; })
4099 .value();
4100 }
4101 else {
4102 // If projectionOrder is unspecified, just return the columns for the specified role in their current order
4103 columnsInProjectionOrdering = _.filter(columns, function (column) { return column.source.roles[roleName]; });
4104 }
4105 return columnsInProjectionOrdering;
4106 }
4107 /**
4108 * Creates the column metadata that will back the column with the concatenated values.
4109 */
4110 function createConcatenatedColumnMetadata(roleName, sourceColumnsSortedByProjectionOrdering, queryRefsToIgnore) {
4111 debug.assertValue(roleName, 'roleName');
4112 debug.assertNonEmpty(sourceColumnsSortedByProjectionOrdering, 'sourceColumnsSortedByProjectionOrdering');
4113 debug.assert(_.chain(sourceColumnsSortedByProjectionOrdering).map(function (c) { return c.isMeasure; }).uniq().value().length === 1, 'pre-condition: caller code should not attempt to combine a mix of measure columns and non-measure columns');
4114 var concatenatedDisplayName;
4115 for (var _i = 0, sourceColumnsSortedByProjectionOrdering_1 = sourceColumnsSortedByProjectionOrdering; _i < sourceColumnsSortedByProjectionOrdering_1.length; _i++) {
4116 var columnSource = sourceColumnsSortedByProjectionOrdering_1[_i];
4117 if (!_.contains(queryRefsToIgnore, columnSource.queryName)) {
4118 concatenatedDisplayName = (concatenatedDisplayName == null) ? columnSource.displayName : (columnSource.displayName + ' ' + concatenatedDisplayName);
4119 }
4120 }
4121 var newRoles = {};
4122 newRoles[roleName] = true;
4123 var newColumnMetadata = {
4124 displayName: concatenatedDisplayName,
4125 roles: newRoles,
4126 type: powerbi.ValueType.fromPrimitiveTypeAndCategory(powerbi.PrimitiveType.Text)
4127 };
4128 var columnSourceForCurrentDrillLevel = _.last(sourceColumnsSortedByProjectionOrdering);
4129 if (columnSourceForCurrentDrillLevel.isMeasure !== undefined) {
4130 newColumnMetadata.isMeasure = columnSourceForCurrentDrillLevel.isMeasure;
4131 }
4132 // TODO VSTS 6842046: Investigate whether we should change that property to mandatory or change the Chart visual code.
4133 // If queryName is not set at all, the column chart visual will only render column for the first group instance.
4134 // If queryName is set to any string other than columnForCurrentDrillLevel.source.queryName, then drilldown by group instance is broken (VSTS 6847879).
4135 newColumnMetadata.queryName = columnSourceForCurrentDrillLevel.queryName;
4136 return newColumnMetadata;
4137 }
4138 function addToMetadata(transformedDataView, newColumn) {
4139 debug.assertValue(transformedDataView, 'transformedDataView');
4140 debug.assertValue(newColumn, 'newColumn');
4141 var transformedColumns = inheritSingle(transformedDataView.metadata.columns);
4142 transformedColumns.push(newColumn);
4143 var transformedMetadata = inheritSingle(transformedDataView.metadata);
4144 transformedMetadata.columns = transformedColumns;
4145 transformedDataView.metadata = transformedMetadata;
4146 }
4147 function createConcatenatedCategoryColumn(sourceColumnsSortedByProjectionOrdering, columnMetadata, concatenatedValues) {
4148 debug.assert(sourceColumnsSortedByProjectionOrdering && sourceColumnsSortedByProjectionOrdering.length >= 2, 'sourceColumnsSortedByProjectionOrdering && sourceColumnsSortedByProjectionOrdering.length >= 2');
4149 var newCategoryColumn = {
4150 source: columnMetadata,
4151 values: concatenatedValues
4152 };
4153 // We expect every DataViewCategoryColumn in concatenationSourceColumns to have the same set of identities, always.
4154 // So, we'll just take the identities and identityFields from the first column
4155 var firstColumn = sourceColumnsSortedByProjectionOrdering[0];
4156 if (firstColumn.identity) {
4157 newCategoryColumn.identity = firstColumn.identity;
4158 }
4159 if (firstColumn.identityFields) {
4160 newCategoryColumn.identityFields = firstColumn.identityFields;
4161 }
4162 // It is safe to look at the first column as it is the one that is being set by findSelectedCategoricalColumn
4163 if (firstColumn.objects) {
4164 newCategoryColumn.objects = firstColumn.objects;
4165 }
4166 return newCategoryColumn;
4167 }
4168 })(DataViewConcatenateCategoricalColumns = data.DataViewConcatenateCategoricalColumns || (data.DataViewConcatenateCategoricalColumns = {}));
4169 })(data = powerbi.data || (powerbi.data = {}));
4170})(powerbi || (powerbi = {}));
4171/*
4172 * Power BI Visualizations
4173 *
4174 * Copyright (c) Microsoft Corporation
4175 * All rights reserved.
4176 * MIT License
4177 *
4178 * Permission is hereby granted, free of charge, to any person obtaining a copy
4179 * of this software and associated documentation files (the ""Software""), to deal
4180 * in the Software without restriction, including without limitation the rights
4181 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4182 * copies of the Software, and to permit persons to whom the Software is
4183 * furnished to do so, subject to the following conditions:
4184 *
4185 * The above copyright notice and this permission notice shall be included in
4186 * all copies or substantial portions of the Software.
4187 *
4188 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4189 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4190 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4191 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4192 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4193 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4194 * THE SOFTWARE.
4195 */
4196var powerbi;
4197(function (powerbi) {
4198 var DataViewMapping;
4199 (function (DataViewMapping) {
4200 function visitMapping(mapping, visitor) {
4201 debug.assertValue(mapping, 'mapping');
4202 debug.assertValue(visitor, 'visitor');
4203 var categorical = mapping.categorical;
4204 if (categorical)
4205 visitCategorical(categorical, visitor);
4206 var table = mapping.table;
4207 if (table)
4208 visitTable(table, visitor);
4209 var matrix = mapping.matrix;
4210 if (matrix)
4211 visitMatrix(matrix, visitor);
4212 var tree = mapping.tree;
4213 if (tree)
4214 visitTree(tree, visitor);
4215 var single = mapping.single;
4216 if (single)
4217 visitSingle(single, visitor);
4218 }
4219 DataViewMapping.visitMapping = visitMapping;
4220 function visitCategorical(mapping, visitor) {
4221 debug.assertValue(mapping, 'mapping');
4222 debug.assertValue(visitor, 'visitor');
4223 visitCategoricalCategories(mapping.categories, visitor);
4224 visitCategoricalValues(mapping.values, visitor);
4225 }
4226 DataViewMapping.visitCategorical = visitCategorical;
4227 function visitCategoricalCategories(mapping, visitor) {
4228 debug.assertAnyValue(mapping, 'mapping');
4229 debug.assertValue(visitor, 'visitor');
4230 if (mapping) {
4231 visitBind(mapping, visitor);
4232 visitFor(mapping, visitor);
4233 visitList(mapping, visitor);
4234 visitReduction(mapping, visitor);
4235 }
4236 }
4237 DataViewMapping.visitCategoricalCategories = visitCategoricalCategories;
4238 function visitCategoricalValues(mapping, visitor) {
4239 debug.assertAnyValue(mapping, 'mapping');
4240 debug.assertValue(visitor, 'visitor');
4241 if (mapping) {
4242 visitBind(mapping, visitor, 0 /* CategoricalValue */);
4243 visitFor(mapping, visitor, 0 /* CategoricalValue */);
4244 visitList(mapping, visitor, 0 /* CategoricalValue */);
4245 var groupedRoleMapping = mapping;
4246 visitGrouped(groupedRoleMapping, visitor);
4247 var group = groupedRoleMapping.group;
4248 if (group) {
4249 for (var _i = 0, _a = group.select; _i < _a.length; _i++) {
4250 var item = _a[_i];
4251 visitBind(item, visitor, 1 /* CategoricalValueGroup */);
4252 visitFor(item, visitor, 1 /* CategoricalValueGroup */);
4253 }
4254 }
4255 }
4256 }
4257 DataViewMapping.visitCategoricalValues = visitCategoricalValues;
4258 function visitTable(mapping, visitor) {
4259 debug.assertValue(mapping, 'mapping');
4260 debug.assertValue(visitor, 'visitor');
4261 var rows = mapping.rows;
4262 visitBind(rows, visitor);
4263 visitFor(rows, visitor);
4264 visitList(rows, visitor);
4265 visitReduction(rows, visitor);
4266 }
4267 DataViewMapping.visitTable = visitTable;
4268 function visitMatrix(mapping, visitor) {
4269 debug.assertValue(mapping, 'mapping');
4270 debug.assertValue(visitor, 'visitor');
4271 visitMatrixItems(mapping.rows, visitor);
4272 visitMatrixItems(mapping.columns, visitor);
4273 visitMatrixItems(mapping.values, visitor);
4274 }
4275 /**
4276 * For visiting DataViewMatrixMapping.rows, DataViewMatrixMapping.columns, or DataViewMatrixMapping.values.
4277 *
4278 * @param mapping Can be one of DataViewMatrixMapping.rows, DataViewMatrixMapping.columns, or DataViewMatrixMapping.values.
4279 * @param visitor The visitor.
4280 */
4281 function visitMatrixItems(mapping, visitor) {
4282 debug.assertAnyValue(mapping, 'mapping');
4283 debug.assertValue(visitor, 'visitor');
4284 if (mapping) {
4285 visitFor(mapping, visitor);
4286 visitList(mapping, visitor);
4287 visitReduction(mapping, visitor);
4288 }
4289 }
4290 DataViewMapping.visitMatrixItems = visitMatrixItems;
4291 function visitTree(mapping, visitor) {
4292 debug.assertValue(mapping, 'mapping');
4293 debug.assertValue(visitor, 'visitor');
4294 visitTreeNodes(mapping.nodes, visitor);
4295 visitTreeValues(mapping.values, visitor);
4296 }
4297 function visitTreeNodes(mapping, visitor) {
4298 debug.assertAnyValue(mapping, 'mapping');
4299 debug.assertValue(visitor, 'visitor');
4300 if (mapping) {
4301 visitFor(mapping, visitor);
4302 visitReduction(mapping, visitor);
4303 }
4304 }
4305 DataViewMapping.visitTreeNodes = visitTreeNodes;
4306 function visitTreeValues(mapping, visitor) {
4307 debug.assertAnyValue(mapping, 'mapping');
4308 debug.assertValue(visitor, 'visitor');
4309 if (mapping) {
4310 visitFor(mapping, visitor);
4311 }
4312 }
4313 DataViewMapping.visitTreeValues = visitTreeValues;
4314 function visitBind(mapping, visitor, context) {
4315 debug.assertValue(mapping, 'mapping');
4316 debug.assertValue(visitor, 'visitor');
4317 var bind = mapping.bind;
4318 if (bind) {
4319 if (context != null)
4320 visitor.visitRole(bind.to, context);
4321 else
4322 visitor.visitRole(bind.to);
4323 }
4324 }
4325 function visitFor(mapping, visitor, context) {
4326 debug.assertValue(mapping, 'mapping');
4327 debug.assertValue(visitor, 'visitor');
4328 var forValue = mapping.for;
4329 if (forValue) {
4330 if (context != null)
4331 visitor.visitRole(forValue.in, context);
4332 else
4333 visitor.visitRole(forValue.in);
4334 }
4335 }
4336 function visitList(mapping, visitor, context) {
4337 debug.assertValue(mapping, 'mapping');
4338 debug.assertValue(visitor, 'visitor');
4339 var select = mapping.select;
4340 if (select) {
4341 for (var _i = 0, select_1 = select; _i < select_1.length; _i++) {
4342 var item = select_1[_i];
4343 visitBind(item, visitor, context);
4344 visitFor(item, visitor, context);
4345 }
4346 }
4347 }
4348 function visitGrouped(mapping, visitor) {
4349 debug.assertAnyValue(mapping, 'mapping');
4350 debug.assertValue(visitor, 'visitor');
4351 if (!mapping)
4352 return;
4353 var group = mapping.group;
4354 if (group) {
4355 visitor.visitRole(group.by);
4356 visitReduction(group, visitor);
4357 }
4358 }
4359 DataViewMapping.visitGrouped = visitGrouped;
4360 function visitReduction(mapping, visitor) {
4361 debug.assertValue(mapping, 'mapping');
4362 debug.assertValue(visitor, 'visitor');
4363 if (visitor.visitReduction) {
4364 var reductionAlgorithm = mapping.dataReductionAlgorithm;
4365 if (reductionAlgorithm) {
4366 visitor.visitReduction(reductionAlgorithm);
4367 }
4368 }
4369 }
4370 function visitSingle(mapping, visitor) {
4371 debug.assertValue(mapping, 'mapping');
4372 debug.assertValue(visitor, 'visitor');
4373 visitor.visitRole(mapping.role);
4374 }
4375 })(DataViewMapping = powerbi.DataViewMapping || (powerbi.DataViewMapping = {}));
4376})(powerbi || (powerbi = {}));
4377/*
4378 * Power BI Visualizations
4379 *
4380 * Copyright (c) Microsoft Corporation
4381 * All rights reserved.
4382 * MIT License
4383 *
4384 * Permission is hereby granted, free of charge, to any person obtaining a copy
4385 * of this software and associated documentation files (the ""Software""), to deal
4386 * in the Software without restriction, including without limitation the rights
4387 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4388 * copies of the Software, and to permit persons to whom the Software is
4389 * furnished to do so, subject to the following conditions:
4390 *
4391 * The above copyright notice and this permission notice shall be included in
4392 * all copies or substantial portions of the Software.
4393 *
4394 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4395 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4396 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4397 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4398 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4399 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4400 * THE SOFTWARE.
4401 */
4402var powerbi;
4403(function (powerbi) {
4404 var data;
4405 (function (data) {
4406 var inheritSingle = powerbi.Prototype.inheritSingle;
4407 var DataViewNormalizeValues;
4408 (function (DataViewNormalizeValues) {
4409 function apply(options) {
4410 debug.assertValue(options, 'options');
4411 var rolesToNormalize = _.filter(options.dataRoles, function (role) { return !_.isEmpty(role.requiredTypes); });
4412 filterVariantMeasures(options.dataview, options.dataViewMappings, rolesToNormalize);
4413 }
4414 DataViewNormalizeValues.apply = apply;
4415 function filterVariantMeasures(dataview, dataViewMappings, rolesToNormalize) {
4416 debug.assertValue(dataview, 'dataview');
4417 // Don't perform this unless we actually have dataViewMappings and variant measures to suppress
4418 // When we switch to lazy per-visual DataView creation, we'll be able to remove this check.
4419 if (_.isEmpty(dataViewMappings) || _.isEmpty(rolesToNormalize))
4420 return;
4421 var columnFilter = generateMetadataColumnFilter(dataview.metadata.columns, rolesToNormalize);
4422 var valueFilter = generateValueFilter(dataview.metadata.columns, rolesToNormalize);
4423 var usedMappings = {};
4424 for (var _i = 0, dataViewMappings_1 = dataViewMappings; _i < dataViewMappings_1.length; _i++) {
4425 var dataViewMapping = dataViewMappings_1[_i];
4426 // Get dataview specified in mappings which are also in dataview
4427 for (var dataViewMappingProp in dataViewMapping) {
4428 if (dataview[dataViewMappingProp] != null)
4429 usedMappings[dataViewMappingProp] = true;
4430 }
4431 }
4432 if (usedMappings['categorical'])
4433 filterVariantMeasuresCategorical(dataview.categorical, columnFilter, valueFilter);
4434 if (usedMappings['table'])
4435 filterVariantMeasuresTable(dataview.table, columnFilter, valueFilter);
4436 if (usedMappings['tree'])
4437 filterVariantMeasuresTreeNode(dataview.tree.root, columnFilter, valueFilter);
4438 if (usedMappings['matrix'])
4439 filterVariantMeasuresMatrix(dataview.matrix, columnFilter, valueFilter);
4440 if (usedMappings['single'])
4441 filterVariantMeasuresSingle(dataview, dataViewMappings, rolesToNormalize, valueFilter);
4442 }
4443 DataViewNormalizeValues.filterVariantMeasures = filterVariantMeasures;
4444 function generateMetadataColumnFilter(columns, rolesToNormalize) {
4445 if (!columns || !rolesToNormalize)
4446 return function () { return false; };
4447 var columnsToNormalize = {};
4448 for (var _i = 0, columns_2 = columns; _i < columns_2.length; _i++) {
4449 var column = columns_2[_i];
4450 var roles = column.roles;
4451 if (!roles)
4452 continue;
4453 for (var _a = 0, rolesToNormalize_1 = rolesToNormalize; _a < rolesToNormalize_1.length; _a++) {
4454 var role = rolesToNormalize_1[_a];
4455 if (!roles[role.name])
4456 continue;
4457 columnsToNormalize[column.index] = true;
4458 break;
4459 }
4460 }
4461 return function (columnIndex) {
4462 if (isNaN(columnIndex))
4463 return false;
4464 return !!columnsToNormalize[columnIndex];
4465 };
4466 }
4467 DataViewNormalizeValues.generateMetadataColumnFilter = generateMetadataColumnFilter;
4468 function generateValueFilter(columns, rolesToNormalize) {
4469 if (!columns || !rolesToNormalize)
4470 return function () { return true; };
4471 var columnValueFilters = [];
4472 // Build columnValueFilters based on role requiredTypes
4473 for (var _i = 0, columns_3 = columns; _i < columns_3.length; _i++) {
4474 var column = columns_3[_i];
4475 var columnValueFilter = generateColumnValueFilter(column, rolesToNormalize);
4476 if (columnValueFilter)
4477 columnValueFilters[column.index] = columnValueFilter;
4478 }
4479 return function (columnIndex, value) {
4480 if (columnValueFilters[columnIndex])
4481 return columnValueFilters[columnIndex](value);
4482 return true;
4483 };
4484 }
4485 DataViewNormalizeValues.generateValueFilter = generateValueFilter;
4486 function generateColumnValueFilter(column, rolesToNormalize) {
4487 var requiredTypes = getColumnRequiredTypes(column, rolesToNormalize);
4488 if (_.isEmpty(requiredTypes))
4489 return;
4490 return function (value) {
4491 return doesValueMatchTypes(value, requiredTypes);
4492 };
4493 }
4494 function getColumnRequiredTypes(column, rolesToNormalize) {
4495 var requiredTypes = [];
4496 var columnRoles = column && column.roles;
4497 if (!columnRoles)
4498 return requiredTypes;
4499 for (var _i = 0, rolesToNormalize_2 = rolesToNormalize; _i < rolesToNormalize_2.length; _i++) {
4500 var role = rolesToNormalize_2[_i];
4501 if (!columnRoles[role.name])
4502 continue;
4503 for (var _a = 0, _b = role.requiredTypes; _a < _b.length; _a++) {
4504 var typeDescriptor = _b[_a];
4505 var type = powerbi.ValueType.fromDescriptor(typeDescriptor);
4506 requiredTypes.push(type);
4507 }
4508 }
4509 return requiredTypes;
4510 }
4511 DataViewNormalizeValues.getColumnRequiredTypes = getColumnRequiredTypes;
4512 function filterVariantMeasuresCategorical(dataview, columnFilter, valueFilter) {
4513 var values = dataview && dataview.values;
4514 if (!values)
4515 return;
4516 var valuesGrouped = values.grouped();
4517 if (!valuesGrouped)
4518 return;
4519 for (var _i = 0, valuesGrouped_1 = valuesGrouped; _i < valuesGrouped_1.length; _i++) {
4520 var valueGroup = valuesGrouped_1[_i];
4521 var valuesInGroup = valueGroup.values;
4522 for (var _a = 0, valuesInGroup_1 = valuesInGroup; _a < valuesInGroup_1.length; _a++) {
4523 var valueColumn = valuesInGroup_1[_a];
4524 var columnIndex = valueColumn.source.index;
4525 if (!columnFilter(columnIndex))
4526 continue;
4527 for (var i = 0, ilen = valueColumn.values.length; i < ilen; i++) {
4528 valueColumn.values = normalizeVariant(valueColumn.values, i, columnIndex, valueFilter);
4529 }
4530 }
4531 }
4532 }
4533 function filterVariantMeasuresTable(dataview, columnFilter, valueFilter) {
4534 var columns = dataview && dataview.columns;
4535 if (!columns)
4536 return;
4537 var filteredColumns = [];
4538 for (var _i = 0, columns_4 = columns; _i < columns_4.length; _i++) {
4539 var column = columns_4[_i];
4540 if (columnFilter(column.index))
4541 filteredColumns.push(column.index);
4542 }
4543 var rows = dataview.rows;
4544 for (var i = 0, ilen = rows.length; i < ilen; i++) {
4545 for (var _a = 0, filteredColumns_1 = filteredColumns; _a < filteredColumns_1.length; _a++) {
4546 var index = filteredColumns_1[_a];
4547 rows[i] = normalizeVariant(rows[i], index, index, valueFilter);
4548 }
4549 }
4550 }
4551 function filterVariantMeasuresTreeNode(node, columnFilter, valueFilter) {
4552 if (node.values) {
4553 for (var columnIndex in node.values) {
4554 // In dataView.tree, the keys in node.values correspond to columnIndex of the node value
4555 if (columnFilter(columnIndex)) {
4556 // According to nojorgen, it is possible to have primitive values as values in the node.values dictionary.
4557 if (typeof (node.values[columnIndex]) === 'object' && ('value' in node.values[columnIndex]))
4558 node.values[columnIndex] = normalizeVariant(node.values[columnIndex], 'value', columnIndex, valueFilter);
4559 else
4560 node.values = normalizeVariant(node.values, columnIndex, columnIndex, valueFilter);
4561 }
4562 }
4563 }
4564 else if (node.children) {
4565 for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
4566 var child = _a[_i];
4567 filterVariantMeasuresTreeNode(child, columnFilter, valueFilter);
4568 }
4569 }
4570 }
4571 function filterVariantMeasuresMatrix(dataview, columnFilter, valueFilter) {
4572 var root = dataview && dataview.rows && dataview.rows.root;
4573 if (!root)
4574 return;
4575 // Recurse into rows.children
4576 // e.g. rows.children -> .children -> .children.values
4577 filterVariantMeasuresMatrixRecursive(dataview, root, columnFilter, valueFilter);
4578 }
4579 function filterVariantMeasuresMatrixRecursive(dataviewMatrix, node, columnFilter, valueFilter) {
4580 if (node.values) {
4581 for (var id in node.values) {
4582 // Note related to VSTS 6547124: In dataView.matrix, the keys in node.values are NOT equivalent to value.valueSourceIndex.
4583 var nodeValue = node.values[id];
4584 // the property DataViewMatrixNodeValue.valueSourceIndex will not exist if valueSourceIndex is 0 for that value
4585 var valueSourceIndex = nodeValue.valueSourceIndex || 0;
4586 // index is an optional property on DataViewMetadataColumn, but I am not sure when it will ever be undefined in a matrix' column metadata
4587 var columnIndex = dataviewMatrix.valueSources[valueSourceIndex].index;
4588 if (_.isNumber(columnIndex) && columnFilter(columnIndex)) {
4589 node.values[id] = normalizeVariant(nodeValue, 'value', columnIndex, valueFilter);
4590 }
4591 }
4592 }
4593 else if (node.children) {
4594 for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
4595 var child = _a[_i];
4596 filterVariantMeasuresMatrixRecursive(dataviewMatrix, child, columnFilter, valueFilter);
4597 }
4598 }
4599 }
4600 function filterVariantMeasuresSingle(dataview, dataViewMappings, rolesToNormalize, valueFilter) {
4601 if (!dataview.single)
4602 return;
4603 var roleNames = [];
4604 for (var _i = 0, rolesToNormalize_3 = rolesToNormalize; _i < rolesToNormalize_3.length; _i++) {
4605 var role = rolesToNormalize_3[_i];
4606 if (role.name)
4607 roleNames.push(role.name);
4608 }
4609 var columns = dataview.metadata.columns;
4610 for (var _a = 0, dataViewMappings_2 = dataViewMappings; _a < dataViewMappings_2.length; _a++) {
4611 var dataViewMapping = dataViewMappings_2[_a];
4612 var roleName = dataViewMapping.single.role;
4613 if (roleNames.indexOf(roleName) !== -1) {
4614 var column = firstColumnByRoleName(columns, roleName);
4615 if (column)
4616 dataview.single = normalizeVariant(dataview.single, 'value', column.index, valueFilter);
4617 return;
4618 }
4619 }
4620 }
4621 function normalizeVariant(object, key, columnIndex, valueFilter) {
4622 if (!object)
4623 return;
4624 var value = object[key];
4625 if (value !== null && !valueFilter(columnIndex, value)) {
4626 object = inheritSingle(object);
4627 object[key] = null;
4628 }
4629 return object;
4630 }
4631 DataViewNormalizeValues.normalizeVariant = normalizeVariant;
4632 function doesValueMatchTypes(value, types) {
4633 for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
4634 var type = types_1[_i];
4635 if (type.numeric || type.integer)
4636 return typeof (value) === 'number';
4637 }
4638 return false;
4639 }
4640 function firstColumnByRoleName(columns, roleName) {
4641 for (var _i = 0, columns_5 = columns; _i < columns_5.length; _i++) {
4642 var column = columns_5[_i];
4643 var columnRoles = column && column.roles;
4644 if (columnRoles && columnRoles[roleName])
4645 return column;
4646 }
4647 }
4648 })(DataViewNormalizeValues = data.DataViewNormalizeValues || (data.DataViewNormalizeValues = {}));
4649 })(data = powerbi.data || (powerbi.data = {}));
4650})(powerbi || (powerbi = {}));
4651/*
4652 * Power BI Visualizations
4653 *
4654 * Copyright (c) Microsoft Corporation
4655 * All rights reserved.
4656 * MIT License
4657 *
4658 * Permission is hereby granted, free of charge, to any person obtaining a copy
4659 * of this software and associated documentation files (the ""Software""), to deal
4660 * in the Software without restriction, including without limitation the rights
4661 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4662 * copies of the Software, and to permit persons to whom the Software is
4663 * furnished to do so, subject to the following conditions:
4664 *
4665 * The above copyright notice and this permission notice shall be included in
4666 * all copies or substantial portions of the Software.
4667 *
4668 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4669 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4670 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4671 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4672 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4673 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4674 * THE SOFTWARE.
4675 */
4676var powerbi;
4677(function (powerbi) {
4678 var DataViewObjects;
4679 (function (DataViewObjects) {
4680 /** Gets the value of the given object/property pair. */
4681 function getValue(objects, propertyId, defaultValue) {
4682 debug.assertAnyValue(objects, 'objects');
4683 debug.assertValue(propertyId, 'propertyId');
4684 if (!objects)
4685 return defaultValue;
4686 var objectOrMap = objects[propertyId.objectName];
4687 debug.assert(!isUserDefined(objectOrMap), 'expected DataViewObject');
4688 var object = objectOrMap;
4689 return DataViewObject.getValue(object, propertyId.propertyName, defaultValue);
4690 }
4691 DataViewObjects.getValue = getValue;
4692 /** Gets an object from objects. */
4693 function getObject(objects, objectName, defaultValue) {
4694 if (objects && objects[objectName]) {
4695 var object = objects[objectName];
4696 debug.assert(!isUserDefined(object), 'expected DataViewObject');
4697 return object;
4698 }
4699 else {
4700 return defaultValue;
4701 }
4702 }
4703 DataViewObjects.getObject = getObject;
4704 /** Gets a map of user-defined objects. */
4705 function getUserDefinedObjects(objects, objectName) {
4706 if (objects && objects[objectName]) {
4707 var map = objects[objectName];
4708 debug.assert(isUserDefined(map), 'expected DataViewObjectMap');
4709 return map;
4710 }
4711 }
4712 DataViewObjects.getUserDefinedObjects = getUserDefinedObjects;
4713 /** Gets the solid color from a fill property. */
4714 function getFillColor(objects, propertyId, defaultColor) {
4715 var value = getValue(objects, propertyId);
4716 if (!value || !value.solid)
4717 return defaultColor;
4718 return value.solid.color;
4719 }
4720 DataViewObjects.getFillColor = getFillColor;
4721 /** Returns true if the given object represents a collection of user-defined objects */
4722 function isUserDefined(objectOrMap) {
4723 return _.isArray(objectOrMap);
4724 }
4725 DataViewObjects.isUserDefined = isUserDefined;
4726 })(DataViewObjects = powerbi.DataViewObjects || (powerbi.DataViewObjects = {}));
4727 var DataViewObject;
4728 (function (DataViewObject) {
4729 function getValue(object, propertyName, defaultValue) {
4730 debug.assertAnyValue(object, 'object');
4731 debug.assertValue(propertyName, 'propertyName');
4732 if (!object)
4733 return defaultValue;
4734 var propertyValue = object[propertyName];
4735 if (propertyValue === undefined)
4736 return defaultValue;
4737 return propertyValue;
4738 }
4739 DataViewObject.getValue = getValue;
4740 /** Gets the solid color from a fill property using only a propertyName */
4741 function getFillColorByPropertyName(objects, propertyName, defaultColor) {
4742 var value = DataViewObject.getValue(objects, propertyName);
4743 if (!value || !value.solid)
4744 return defaultColor;
4745 return value.solid.color;
4746 }
4747 DataViewObject.getFillColorByPropertyName = getFillColorByPropertyName;
4748 })(DataViewObject = powerbi.DataViewObject || (powerbi.DataViewObject = {}));
4749})(powerbi || (powerbi = {}));
4750/*
4751 * Power BI Visualizations
4752 *
4753 * Copyright (c) Microsoft Corporation
4754 * All rights reserved.
4755 * MIT License
4756 *
4757 * Permission is hereby granted, free of charge, to any person obtaining a copy
4758 * of this software and associated documentation files (the ""Software""), to deal
4759 * in the Software without restriction, including without limitation the rights
4760 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4761 * copies of the Software, and to permit persons to whom the Software is
4762 * furnished to do so, subject to the following conditions:
4763 *
4764 * The above copyright notice and this permission notice shall be included in
4765 * all copies or substantial portions of the Software.
4766 *
4767 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4768 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4769 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4770 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4771 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4772 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4773 * THE SOFTWARE.
4774 */
4775var powerbi;
4776(function (powerbi) {
4777 var data;
4778 (function (data) {
4779 var JsonComparer = jsCommon.JsonComparer;
4780 var DataViewObjectDefinitions;
4781 (function (DataViewObjectDefinitions) {
4782 /** Creates or reuses a DataViewObjectDefinition for matching the given objectName and selector within the defns. */
4783 function ensure(defns, objectName, selector) {
4784 debug.assertValue(defns, 'defns');
4785 var defnsForObject = defns[objectName];
4786 if (!defnsForObject)
4787 defns[objectName] = defnsForObject = [];
4788 for (var i = 0, len = defnsForObject.length; i < len; i++) {
4789 var defn = defnsForObject[i];
4790 if (data.Selector.equals(defn.selector, selector))
4791 return defn;
4792 }
4793 var newDefn = {
4794 selector: selector,
4795 properties: {},
4796 };
4797 defnsForObject.push(newDefn);
4798 return newDefn;
4799 }
4800 DataViewObjectDefinitions.ensure = ensure;
4801 function deleteProperty(defns, objectName, selector, propertyName) {
4802 debug.assertValue(defns, 'defns');
4803 var defn = getObjectDefinition(defns, objectName, selector);
4804 if (!defn)
4805 return;
4806 DataViewObjectDefinition.deleteSingleProperty(defn, propertyName);
4807 }
4808 DataViewObjectDefinitions.deleteProperty = deleteProperty;
4809 function setValue(defns, propertyId, selector, value) {
4810 debug.assertValue(defns, 'defns');
4811 debug.assertValue(propertyId, 'propertyId');
4812 ensure(defns, propertyId.objectName, selector).properties[propertyId.propertyName] = value;
4813 }
4814 DataViewObjectDefinitions.setValue = setValue;
4815 function getValue(defns, propertyId, selector) {
4816 var properties = getPropertyContainer(defns, propertyId, selector);
4817 if (!properties)
4818 return;
4819 return properties[propertyId.propertyName];
4820 }
4821 DataViewObjectDefinitions.getValue = getValue;
4822 function getPropertyContainer(defns, propertyId, selector) {
4823 var defn = getObjectDefinition(defns, propertyId.objectName, selector);
4824 if (!defn)
4825 return;
4826 return defn.properties;
4827 }
4828 DataViewObjectDefinitions.getPropertyContainer = getPropertyContainer;
4829 function getObjectDefinition(defns, objectName, selector) {
4830 debug.assertAnyValue(defns, 'defns');
4831 debug.assertValue(objectName, 'objectName');
4832 debug.assertAnyValue(selector, 'selector');
4833 if (!defns)
4834 return;
4835 var defnsForObject = defns[objectName];
4836 if (!defnsForObject)
4837 return;
4838 for (var i = 0, len = defnsForObject.length; i < len; i++) {
4839 var defn = defnsForObject[i];
4840 if (data.Selector.equals(defn.selector, selector))
4841 return defn;
4842 }
4843 }
4844 DataViewObjectDefinitions.getObjectDefinition = getObjectDefinition;
4845 function propertiesAreEqual(a, b) {
4846 if (a instanceof data.SemanticFilter && b instanceof data.SemanticFilter) {
4847 return data.SemanticFilter.isSameFilter(a, b);
4848 }
4849 return JsonComparer.equals(a, b);
4850 }
4851 DataViewObjectDefinitions.propertiesAreEqual = propertiesAreEqual;
4852 function allPropertiesAreEqual(a, b) {
4853 debug.assertValue(a, 'a');
4854 debug.assertValue(b, 'b');
4855 if (Object.keys(a).length !== Object.keys(b).length)
4856 return false;
4857 for (var property in a) {
4858 if (!propertiesAreEqual(a[property], b[property]))
4859 return false;
4860 }
4861 return true;
4862 }
4863 DataViewObjectDefinitions.allPropertiesAreEqual = allPropertiesAreEqual;
4864 function encodePropertyValue(value, valueTypeDescriptor) {
4865 debug.assertAnyValue(value, 'value');
4866 debug.assertValue(valueTypeDescriptor, 'valueTypeDescriptor');
4867 if (valueTypeDescriptor.bool) {
4868 if (typeof (value) !== 'boolean')
4869 value = false; // This is fallback, which doesn't really belong here.
4870 return data.SQExprBuilder.boolean(value);
4871 }
4872 else if (valueTypeDescriptor.text || (valueTypeDescriptor.scripting && valueTypeDescriptor.scripting.source)) {
4873 return data.SQExprBuilder.text(value);
4874 }
4875 else if (valueTypeDescriptor.numeric) {
4876 if ($.isNumeric(value))
4877 return data.SQExprBuilder.double(+value);
4878 }
4879 else if (valueTypeDescriptor.fill) {
4880 if (value) {
4881 return {
4882 solid: { color: data.SQExprBuilder.text(value) }
4883 };
4884 }
4885 }
4886 else if (valueTypeDescriptor.formatting) {
4887 if (valueTypeDescriptor.formatting.labelDisplayUnits) {
4888 return data.SQExprBuilder.double(+value);
4889 }
4890 else {
4891 return data.SQExprBuilder.text(value);
4892 }
4893 }
4894 else if (valueTypeDescriptor.enumeration) {
4895 if ($.isNumeric(value))
4896 return data.SQExprBuilder.double(+value);
4897 else
4898 return data.SQExprBuilder.text(value);
4899 }
4900 else if (valueTypeDescriptor.misc) {
4901 if (value) {
4902 value = data.SQExprBuilder.text(value);
4903 }
4904 else {
4905 value = null;
4906 }
4907 }
4908 else if (valueTypeDescriptor.image) {
4909 if (value) {
4910 var imageValue = value;
4911 var imageDefinition = {
4912 name: data.SQExprBuilder.text(imageValue.name),
4913 url: data.SQExprBuilder.text(imageValue.url),
4914 };
4915 if (imageValue.scaling)
4916 imageDefinition.scaling = data.SQExprBuilder.text(imageValue.scaling);
4917 return imageDefinition;
4918 }
4919 }
4920 return value;
4921 }
4922 DataViewObjectDefinitions.encodePropertyValue = encodePropertyValue;
4923 function clone(original) {
4924 debug.assertValue(original, 'original');
4925 var cloned = {};
4926 for (var objectName in original) {
4927 var originalDefns = original[objectName];
4928 if (_.isEmpty(originalDefns))
4929 continue;
4930 var clonedDefns = [];
4931 for (var _i = 0, originalDefns_1 = originalDefns; _i < originalDefns_1.length; _i++) {
4932 var originalDefn = originalDefns_1[_i];
4933 clonedDefns.push({
4934 properties: cloneProperties(originalDefn.properties),
4935 selector: originalDefn.selector,
4936 });
4937 }
4938 cloned[objectName] = clonedDefns;
4939 }
4940 return cloned;
4941 }
4942 DataViewObjectDefinitions.clone = clone;
4943 function cloneProperties(original) {
4944 debug.assertValue(original, 'original');
4945 // NOTE: properties are considered atomic, so a shallow clone is appropriate here.
4946 return _.clone(original);
4947 }
4948 })(DataViewObjectDefinitions = data.DataViewObjectDefinitions || (data.DataViewObjectDefinitions = {}));
4949 var DataViewObjectDefinition;
4950 (function (DataViewObjectDefinition) {
4951 function deleteSingleProperty(defn, propertyName) {
4952 //note: We decided that delete is acceptable here and that we don't need optimization here
4953 delete defn.properties[propertyName];
4954 }
4955 DataViewObjectDefinition.deleteSingleProperty = deleteSingleProperty;
4956 })(DataViewObjectDefinition = data.DataViewObjectDefinition || (data.DataViewObjectDefinition = {}));
4957 })(data = powerbi.data || (powerbi.data = {}));
4958})(powerbi || (powerbi = {}));
4959/*
4960 * Power BI Visualizations
4961 *
4962 * Copyright (c) Microsoft Corporation
4963 * All rights reserved.
4964 * MIT License
4965 *
4966 * Permission is hereby granted, free of charge, to any person obtaining a copy
4967 * of this software and associated documentation files (the ""Software""), to deal
4968 * in the Software without restriction, including without limitation the rights
4969 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4970 * copies of the Software, and to permit persons to whom the Software is
4971 * furnished to do so, subject to the following conditions:
4972 *
4973 * The above copyright notice and this permission notice shall be included in
4974 * all copies or substantial portions of the Software.
4975 *
4976 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4977 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4978 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4979 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4980 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4981 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4982 * THE SOFTWARE.
4983 */
4984var powerbi;
4985(function (powerbi) {
4986 var data;
4987 (function (data) {
4988 var DataViewObjectDescriptors;
4989 (function (DataViewObjectDescriptors) {
4990 /** Attempts to find the format string property. This can be useful for upgrade and conversion. */
4991 function findFormatString(descriptors) {
4992 return findProperty(descriptors, function (propDesc) {
4993 var formattingTypeDesc = powerbi.ValueType.fromDescriptor(propDesc.type).formatting;
4994 return formattingTypeDesc && formattingTypeDesc.formatString;
4995 });
4996 }
4997 DataViewObjectDescriptors.findFormatString = findFormatString;
4998 /** Attempts to find the filter property. This can be useful for propagating filters from one visual to others. */
4999 function findFilterOutput(descriptors) {
5000 return findProperty(descriptors, function (propDesc) {
5001 var propType = propDesc.type;
5002 return propType && !!propType.filter;
5003 });
5004 }
5005 DataViewObjectDescriptors.findFilterOutput = findFilterOutput;
5006 /** Attempts to find the default value property. This can be useful for propagating schema default value. */
5007 function findDefaultValue(descriptors) {
5008 return findProperty(descriptors, function (propDesc) {
5009 var propType = propDesc.type;
5010 return propType && !!propType.expression && propType.expression.defaultValue;
5011 });
5012 }
5013 DataViewObjectDescriptors.findDefaultValue = findDefaultValue;
5014 function findProperty(descriptors, propPredicate) {
5015 debug.assertAnyValue(descriptors, 'descriptors');
5016 debug.assertAnyValue(propPredicate, 'propPredicate');
5017 if (!descriptors)
5018 return;
5019 for (var objectName in descriptors) {
5020 var objPropDescs = descriptors[objectName].properties;
5021 for (var propertyName in objPropDescs) {
5022 if (propPredicate(objPropDescs[propertyName])) {
5023 return {
5024 objectName: objectName,
5025 propertyName: propertyName,
5026 };
5027 }
5028 }
5029 }
5030 }
5031 })(DataViewObjectDescriptors = data.DataViewObjectDescriptors || (data.DataViewObjectDescriptors = {}));
5032 })(data = powerbi.data || (powerbi.data = {}));
5033})(powerbi || (powerbi = {}));
5034/*
5035* Power BI Visualizations
5036*
5037* Copyright (c) Microsoft Corporation
5038* All rights reserved.
5039 * MIT License
5040*
5041* Permission is hereby granted, free of charge, to any person obtaining a copy
5042* of this software and associated documentation files (the ""Software""), to deal
5043* in the Software without restriction, including without limitation the rights
5044* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5045* copies of the Software, and to permit persons to whom the Software is
5046* furnished to do so, subject to the following conditions:
5047*
5048 * The above copyright notice and this permission notice shall be included in
5049 * all copies or substantial portions of the Software.
5050*
5051 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5052 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5053 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5054 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5055 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5056* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5057* THE SOFTWARE.
5058*/
5059var powerbi;
5060(function (powerbi) {
5061 var data;
5062 (function (data) {
5063 var DataViewObjectEvaluationUtils;
5064 (function (DataViewObjectEvaluationUtils) {
5065 function evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns) {
5066 debug.assertValue(evalContext, 'evalContext');
5067 debug.assertValue(objectDescriptors, 'objectDescriptors');
5068 debug.assertValue(objectDefns, 'objectDefns');
5069 var objects;
5070 for (var j = 0, jlen = objectDefns.length; j < jlen; j++) {
5071 var objectDefinition = objectDefns[j], objectName = objectDefinition.name;
5072 var evaluatedObject = data.DataViewObjectEvaluator.run(evalContext, objectDescriptors[objectName], objectDefinition.properties);
5073 if (!evaluatedObject)
5074 continue;
5075 if (!objects)
5076 objects = {};
5077 // NOTE: this currently has last-object-wins semantics.
5078 objects[objectName] = evaluatedObject;
5079 }
5080 return objects;
5081 }
5082 DataViewObjectEvaluationUtils.evaluateDataViewObjects = evaluateDataViewObjects;
5083 function groupObjectsBySelector(objectDefinitions) {
5084 debug.assertAnyValue(objectDefinitions, 'objectDefinitions');
5085 var grouped = {
5086 data: [],
5087 };
5088 if (objectDefinitions) {
5089 for (var objectName in objectDefinitions) {
5090 var objectDefnList = objectDefinitions[objectName];
5091 for (var i = 0, len = objectDefnList.length; i < len; i++) {
5092 var objectDefn = objectDefnList[i];
5093 ensureDefinitionListForSelector(grouped, objectDefn.selector).objects.push({
5094 name: objectName,
5095 properties: objectDefn.properties,
5096 });
5097 }
5098 }
5099 }
5100 return grouped;
5101 }
5102 DataViewObjectEvaluationUtils.groupObjectsBySelector = groupObjectsBySelector;
5103 function ensureDefinitionListForSelector(grouped, selector) {
5104 debug.assertValue(grouped, 'grouped');
5105 debug.assertAnyValue(selector, 'selector');
5106 if (!selector) {
5107 if (!grouped.metadataOnce)
5108 grouped.metadataOnce = { objects: [] };
5109 return grouped.metadataOnce;
5110 }
5111 var groupedObjects;
5112 if (selector.data) {
5113 groupedObjects = grouped.data;
5114 }
5115 else if (selector.metadata) {
5116 if (!grouped.metadata)
5117 grouped.metadata = [];
5118 groupedObjects = grouped.metadata;
5119 }
5120 else if (selector.id) {
5121 if (!grouped.userDefined)
5122 grouped.userDefined = [];
5123 groupedObjects = grouped.userDefined;
5124 }
5125 debug.assert(!!groupedObjects, 'GroupedObjects is not defined. Indicates malformed selector.');
5126 for (var _i = 0, groupedObjects_1 = groupedObjects; _i < groupedObjects_1.length; _i++) {
5127 var item_1 = groupedObjects_1[_i];
5128 if (data.Selector.equals(selector, item_1.selector))
5129 return item_1;
5130 }
5131 var item = {
5132 selector: selector,
5133 objects: [],
5134 };
5135 groupedObjects.push(item);
5136 return item;
5137 }
5138 function addImplicitObjects(objectsForAllSelectors, objectDescriptors, columns, selectTransforms) {
5139 debug.assertValue(objectsForAllSelectors, 'objectsForAllSelectors');
5140 debug.assertValue(objectDescriptors, 'objectDescriptors');
5141 debug.assertValue(columns, 'columns');
5142 debug.assertAnyValue(selectTransforms, 'selectTransforms');
5143 if (selectTransforms) {
5144 addDefaultFormatString(objectsForAllSelectors, objectDescriptors, columns, selectTransforms);
5145 addDefaultValue(objectsForAllSelectors, objectDescriptors, columns, selectTransforms);
5146 }
5147 }
5148 DataViewObjectEvaluationUtils.addImplicitObjects = addImplicitObjects;
5149 function addDefaultFormatString(objectsForAllSelectors, objectDescriptors, columns, selectTransforms) {
5150 debug.assertValue(objectsForAllSelectors, 'objectsForAllSelectors');
5151 debug.assertValue(objectDescriptors, 'objectDescriptors');
5152 debug.assertValue(columns, 'columns');
5153 debug.assertValue(selectTransforms, 'selectTransforms');
5154 var formatStringProp = data.DataViewObjectDescriptors.findFormatString(objectDescriptors);
5155 if (!formatStringProp)
5156 return;
5157 for (var selectIdx = 0, selectLen = selectTransforms.length; selectIdx < selectLen; selectIdx++) {
5158 var selectTransform = selectTransforms[selectIdx];
5159 if (!selectTransform)
5160 continue;
5161 debug.assertValue(selectTransform.queryName, 'selectTransform.queryName');
5162 applyFormatString(objectsForAllSelectors, formatStringProp, selectTransform.queryName, selectTransform.format || getColumnFormatForIndex(columns, selectIdx));
5163 }
5164 }
5165 /** Registers properties for default value, if the properties are not explicitly provided. */
5166 function addDefaultValue(objectsForAllSelectors, objectDescriptors, columns, selectTransforms) {
5167 debug.assertValue(objectsForAllSelectors, 'objectsForAllSelectors');
5168 debug.assertValue(objectDescriptors, 'objectDescriptors');
5169 debug.assertValue(columns, 'columns');
5170 debug.assertValue(selectTransforms, 'selectTransforms');
5171 var defaultValueProp = data.DataViewObjectDescriptors.findDefaultValue(objectDescriptors);
5172 if (!defaultValueProp)
5173 return;
5174 for (var _i = 0, selectTransforms_1 = selectTransforms; _i < selectTransforms_1.length; _i++) {
5175 var selectTransform = selectTransforms_1[_i];
5176 if (!selectTransform)
5177 continue;
5178 debug.assertValue(selectTransform.queryName, 'selectTransform.queryName');
5179 applyDefaultValue(objectsForAllSelectors, defaultValueProp, selectTransform.queryName, selectTransform.defaultValue);
5180 }
5181 }
5182 function getColumnFormatForIndex(columns, selectIdx) {
5183 for (var columnIdx = 0, columnLen = columns.length; columnIdx < columnLen; columnIdx++) {
5184 var column = columns[columnIdx];
5185 if (!column || column.index !== selectIdx)
5186 continue;
5187 return column.format;
5188 }
5189 }
5190 function applyFormatString(objectsForAllSelectors, formatStringProp, queryName, formatStringValue) {
5191 if (!formatStringValue)
5192 return;
5193 // There is a format string specified -- apply it as an object property, if there is not already one specified.
5194 applyMetadataProperty(objectsForAllSelectors, formatStringProp, { metadata: queryName }, data.SQExprBuilder.text(formatStringValue));
5195 }
5196 function applyDefaultValue(objectsForAllSelectors, defaultValueProp, queryName, defaultValue) {
5197 if (!defaultValue)
5198 return;
5199 // There is a default value specified -- apply it as an object property, if there is not already one specified.
5200 applyMetadataProperty(objectsForAllSelectors, defaultValueProp, { metadata: queryName }, defaultValue);
5201 }
5202 function applyMetadataProperty(objectsForAllSelectors, propertyId, selector, value) {
5203 var objectDefns;
5204 if (selector) {
5205 var metadataObjects = objectsForAllSelectors.metadata;
5206 if (!metadataObjects)
5207 metadataObjects = objectsForAllSelectors.metadata = [];
5208 objectDefns = metadataObjects;
5209 }
5210 else {
5211 var metadataOnce = objectsForAllSelectors.metadataOnce;
5212 if (!metadataOnce)
5213 metadataOnce = objectsForAllSelectors.metadataOnce = { selector: selector, objects: [] };
5214 objectDefns = [metadataOnce];
5215 }
5216 var targetMetadataObject = findWithMatchingSelector(objectDefns, selector);
5217 var targetObjectDefn;
5218 if (targetMetadataObject) {
5219 var targetObjectDefns = targetMetadataObject.objects;
5220 targetObjectDefn = findExistingObject(targetObjectDefns, propertyId.objectName);
5221 if (targetObjectDefn) {
5222 if (targetObjectDefn.properties[propertyId.propertyName])
5223 return;
5224 }
5225 else {
5226 targetObjectDefn = {
5227 name: propertyId.objectName,
5228 properties: {},
5229 };
5230 targetObjectDefns.push(targetObjectDefn);
5231 }
5232 }
5233 else {
5234 targetObjectDefn = {
5235 name: propertyId.objectName,
5236 properties: {}
5237 };
5238 objectDefns.push({
5239 selector: selector,
5240 objects: [targetObjectDefn],
5241 });
5242 }
5243 targetObjectDefn.properties[propertyId.propertyName] = value;
5244 }
5245 function findWithMatchingSelector(objects, selector) {
5246 debug.assertValue(objects, 'objects');
5247 debug.assertAnyValue(selector, 'selector');
5248 for (var i = 0, len = objects.length; i < len; i++) {
5249 var object = objects[i];
5250 if (data.Selector.equals(object.selector, selector))
5251 return object;
5252 }
5253 }
5254 function findExistingObject(objectDefns, objectName) {
5255 debug.assertValue(objectDefns, 'objectDefns');
5256 debug.assertValue(objectName, 'objectName');
5257 for (var i = 0, len = objectDefns.length; i < len; i++) {
5258 var objectDefn = objectDefns[i];
5259 if (objectDefn.name === objectName)
5260 return objectDefn;
5261 }
5262 }
5263 })(DataViewObjectEvaluationUtils = data.DataViewObjectEvaluationUtils || (data.DataViewObjectEvaluationUtils = {}));
5264 })(data = powerbi.data || (powerbi.data = {}));
5265})(powerbi || (powerbi = {}));
5266/*
5267 * Power BI Visualizations
5268 *
5269 * Copyright (c) Microsoft Corporation
5270 * All rights reserved.
5271 * MIT License
5272 *
5273 * Permission is hereby granted, free of charge, to any person obtaining a copy
5274 * of this software and associated documentation files (the ""Software""), to deal
5275 * in the Software without restriction, including without limitation the rights
5276 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5277 * copies of the Software, and to permit persons to whom the Software is
5278 * furnished to do so, subject to the following conditions:
5279 *
5280 * The above copyright notice and this permission notice shall be included in
5281 * all copies or substantial portions of the Software.
5282 *
5283 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5284 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5285 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5286 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5287 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5288 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5289 * THE SOFTWARE.
5290 */
5291var powerbi;
5292(function (powerbi) {
5293 var data;
5294 (function (data) {
5295 /** Responsible for evaluating object property expressions to be applied at various scopes in a DataView. */
5296 var DataViewObjectEvaluator;
5297 (function (DataViewObjectEvaluator) {
5298 var colorValueType = powerbi.ValueType.fromDescriptor({ formatting: { color: true } });
5299 var numericType = powerbi.ValueType.fromDescriptor({ numeric: true });
5300 var textType = powerbi.ValueType.fromDescriptor({ text: true });
5301 function run(evalContext, objectDescriptor, propertyDefinitions) {
5302 debug.assertValue(evalContext, 'evalContext');
5303 debug.assertAnyValue(objectDescriptor, 'objectDescriptor');
5304 debug.assertValue(propertyDefinitions, 'propertyDefinitions');
5305 if (!objectDescriptor)
5306 return;
5307 var object, propertyDescriptors = objectDescriptor.properties;
5308 for (var propertyName in propertyDefinitions) {
5309 var propertyDefinition = propertyDefinitions[propertyName], propertyDescriptor = propertyDescriptors[propertyName];
5310 if (!propertyDescriptor)
5311 continue;
5312 var propertyValue = evaluateProperty(evalContext, propertyDescriptor, propertyDefinition);
5313 if (propertyValue === undefined)
5314 continue;
5315 if (!object)
5316 object = {};
5317 object[propertyName] = propertyValue;
5318 }
5319 return object;
5320 }
5321 DataViewObjectEvaluator.run = run;
5322 /** Note: Exported for testability */
5323 function evaluateProperty(evalContext, propertyDescriptor, propertyDefinition) {
5324 debug.assertValue(evalContext, 'evalContext');
5325 debug.assertValue(propertyDescriptor, 'propertyDescriptor');
5326 debug.assertValue(propertyDefinition, 'propertyDefinition');
5327 var structuralType = propertyDescriptor.type;
5328 if (structuralType && structuralType.expression)
5329 return propertyDefinition;
5330 var value = evaluateValue(evalContext, propertyDefinition, powerbi.ValueType.fromDescriptor(propertyDescriptor.type));
5331 if (value !== undefined || (propertyDefinition instanceof data.RuleEvaluation))
5332 return value;
5333 return evaluateFill(evalContext, propertyDefinition, structuralType)
5334 || evaluateFillRule(evalContext, propertyDefinition, structuralType)
5335 || evaluateImage(evalContext, propertyDefinition, structuralType)
5336 || evaluateParagraphs(evalContext, propertyDefinition, structuralType)
5337 || propertyDefinition;
5338 }
5339 DataViewObjectEvaluator.evaluateProperty = evaluateProperty;
5340 function evaluateFill(evalContext, fillDefn, type) {
5341 var fillType = type.fill;
5342 if (!fillType)
5343 return;
5344 if (fillType && fillType.solid && fillType.solid.color && fillDefn.solid) {
5345 return {
5346 solid: {
5347 color: evaluateValue(evalContext, fillDefn.solid.color, powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Color)),
5348 }
5349 };
5350 }
5351 }
5352 function evaluateFillRule(evalContext, fillRuleDefn, type) {
5353 if (!type.fillRule)
5354 return;
5355 if (fillRuleDefn.linearGradient2) {
5356 var linearGradient2 = fillRuleDefn.linearGradient2;
5357 return {
5358 linearGradient2: {
5359 min: evaluateColorStop(evalContext, linearGradient2.min),
5360 max: evaluateColorStop(evalContext, linearGradient2.max),
5361 }
5362 };
5363 }
5364 if (fillRuleDefn.linearGradient3) {
5365 var linearGradient3 = fillRuleDefn.linearGradient3;
5366 return {
5367 linearGradient3: {
5368 min: evaluateColorStop(evalContext, linearGradient3.min),
5369 mid: evaluateColorStop(evalContext, linearGradient3.mid),
5370 max: evaluateColorStop(evalContext, linearGradient3.max),
5371 }
5372 };
5373 }
5374 }
5375 function evaluateColorStop(evalContext, colorStop) {
5376 debug.assertValue(evalContext, 'evalContext');
5377 debug.assertValue(colorStop, 'colorStop');
5378 var step = {
5379 color: evaluateValue(evalContext, colorStop.color, colorValueType),
5380 };
5381 var value = evaluateValue(evalContext, colorStop.value, numericType);
5382 if (value != null)
5383 step.value = value;
5384 return step;
5385 }
5386 function evaluateImage(evalContext, definition, type) {
5387 debug.assertValue(evalContext, 'evalContext');
5388 debug.assertAnyValue(definition, 'definition');
5389 debug.assertValue(type, 'type');
5390 if (!type.image || !definition)
5391 return;
5392 var value = {
5393 name: evaluateValue(evalContext, definition.name, textType),
5394 url: evaluateValue(evalContext, definition.url, powerbi.ValueType.fromDescriptor(powerbi.ImageDefinition.urlType)),
5395 };
5396 if (definition.scaling)
5397 value.scaling = evaluateValue(evalContext, definition.scaling, textType);
5398 return value;
5399 }
5400 function evaluateParagraphs(evalContext, definition, type) {
5401 debug.assertValue(evalContext, 'evalContext');
5402 debug.assertAnyValue(definition, 'definition');
5403 debug.assertValue(type, 'type');
5404 if (!type.paragraphs || !definition)
5405 return;
5406 return evaluateArrayCopyOnChange(evalContext, definition, evaluateParagraph);
5407 }
5408 function evaluateParagraph(evalContext, definition) {
5409 debug.assertValue(evalContext, 'evalContext');
5410 debug.assertValue(definition, 'definition');
5411 var evaluated;
5412 var definitionTextRuns = definition.textRuns;
5413 var evaluatedTextRuns = evaluateArrayCopyOnChange(evalContext, definitionTextRuns, evaluateTextRun);
5414 if (definitionTextRuns !== evaluatedTextRuns) {
5415 evaluated = _.clone(definition);
5416 evaluated.textRuns = evaluatedTextRuns;
5417 }
5418 return evaluated || definition;
5419 }
5420 function evaluateTextRun(evalContext, definition) {
5421 debug.assertValue(evalContext, 'evalContext');
5422 debug.assertValue(definition, 'definition');
5423 var evaluated;
5424 var definitionValue = definition.value;
5425 var evaluatedValue = evaluateValue(evalContext, definitionValue, textType);
5426 if (evaluatedValue !== undefined) {
5427 evaluated = _.clone(definition);
5428 evaluated.value = evaluatedValue;
5429 }
5430 return evaluated || definition;
5431 }
5432 /**
5433 * Evaluates an array, and lazily copies on write whenever the evaluator function returns something
5434 * other than the input to it.
5435 */
5436 function evaluateArrayCopyOnChange(evalContext, definitions, evaluator) {
5437 debug.assertValue(evalContext, 'evalContext');
5438 debug.assertValue(definitions, 'definitions');
5439 debug.assertValue(evaluator, 'evaluator');
5440 var evaluatedValues;
5441 for (var i = 0, len = definitions.length; i < len; i++) {
5442 var definition = definitions[i];
5443 var evaluated = evaluator(evalContext, definition);
5444 // NOTE: the any casts here are necessary due to the compiler not knowing the relationship
5445 // between TEvaluated & TDefinition
5446 if (!evaluatedValues && definition !== evaluated) {
5447 evaluatedValues = _.take(definitions, i);
5448 }
5449 if (evaluatedValues) {
5450 evaluatedValues.push(evaluated);
5451 }
5452 }
5453 return evaluatedValues || definitions;
5454 }
5455 function evaluateValue(evalContext, definition, valueType) {
5456 if (definition instanceof data.SQExpr)
5457 return ExpressionEvaluator.evaluate(definition, evalContext);
5458 if (definition instanceof data.RuleEvaluation)
5459 return definition.evaluate(evalContext);
5460 }
5461 /** Responsible for evaluating SQExprs into values. */
5462 var ExpressionEvaluator = (function (_super) {
5463 __extends(ExpressionEvaluator, _super);
5464 function ExpressionEvaluator() {
5465 _super.apply(this, arguments);
5466 }
5467 ExpressionEvaluator.evaluate = function (expr, evalContext) {
5468 if (expr == null)
5469 return;
5470 return expr.accept(ExpressionEvaluator.instance, evalContext);
5471 };
5472 ExpressionEvaluator.prototype.visitColumnRef = function (expr, evalContext) {
5473 return evalContext.getExprValue(expr);
5474 };
5475 ExpressionEvaluator.prototype.visitConstant = function (expr, evalContext) {
5476 return expr.value;
5477 };
5478 ExpressionEvaluator.prototype.visitMeasureRef = function (expr, evalContext) {
5479 return evalContext.getExprValue(expr);
5480 };
5481 ExpressionEvaluator.prototype.visitAggr = function (expr, evalContext) {
5482 return evalContext.getExprValue(expr);
5483 };
5484 ExpressionEvaluator.prototype.visitFillRule = function (expr, evalContext) {
5485 var inputValue = expr.input.accept(this, evalContext);
5486 if (inputValue !== undefined) {
5487 var colorAllocator = evalContext.getColorAllocator(expr);
5488 if (colorAllocator) {
5489 return colorAllocator.color(inputValue);
5490 }
5491 }
5492 };
5493 ExpressionEvaluator.prototype.visitSelectRef = function (expr, evalContext) {
5494 return evalContext.getExprValue(expr);
5495 };
5496 ExpressionEvaluator.instance = new ExpressionEvaluator();
5497 return ExpressionEvaluator;
5498 }(data.DefaultSQExprVisitorWithArg));
5499 })(DataViewObjectEvaluator = data.DataViewObjectEvaluator || (data.DataViewObjectEvaluator = {}));
5500 })(data = powerbi.data || (powerbi.data = {}));
5501})(powerbi || (powerbi = {}));
5502/*
5503 * Power BI Visualizations
5504 *
5505 * Copyright (c) Microsoft Corporation
5506 * All rights reserved.
5507 * MIT License
5508 *
5509 * Permission is hereby granted, free of charge, to any person obtaining a copy
5510 * of this software and associated documentation files (the ""Software""), to deal
5511 * in the Software without restriction, including without limitation the rights
5512 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5513 * copies of the Software, and to permit persons to whom the Software is
5514 * furnished to do so, subject to the following conditions:
5515 *
5516 * The above copyright notice and this permission notice shall be included in
5517 * all copies or substantial portions of the Software.
5518 *
5519 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5520 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5521 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5522 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5523 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5524 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5525 * THE SOFTWARE.
5526 */
5527var powerbi;
5528(function (powerbi) {
5529 var data;
5530 (function (data) {
5531 var inherit = powerbi.Prototype.inherit;
5532 var DataViewPivotCategorical;
5533 (function (DataViewPivotCategorical) {
5534 /**
5535 * Pivots categories in a categorical DataView into valueGroupings.
5536 * This is akin to a mathematical matrix transpose.
5537 */
5538 function apply(dataView) {
5539 debug.assertValue(dataView, 'dataView');
5540 var categorical = dataView.categorical;
5541 if (!categorical)
5542 return null;
5543 var categories = categorical.categories;
5544 if (!categories || categories.length !== 1)
5545 return null;
5546 var values = categorical.values;
5547 if (_.isEmpty(values) || values.source)
5548 return null;
5549 var category = categories[0], categoryIdentities = category.identity, categoryValues = category.values, pivotedColumns = [], pivotedValues = [];
5550 for (var rowIdx = 0, rowCount = categoryValues.length; rowIdx < rowCount; rowIdx++) {
5551 var categoryValue = categoryValues[rowIdx], categoryIdentity = categoryIdentities[rowIdx];
5552 for (var colIdx = 0, colCount = values.length; colIdx < colCount; colIdx++) {
5553 var value = values[colIdx], pivotedColumn = inherit(value.source);
5554 // A value has a series group, which is not implemented for pivoting -- just give up.
5555 if (value.identity)
5556 return null;
5557 pivotedColumn.groupName = categoryValue;
5558 var pivotedValue = {
5559 source: pivotedColumn,
5560 values: [value.values[rowIdx]],
5561 identity: categoryIdentity,
5562 min: value.min,
5563 max: value.max,
5564 subtotal: value.subtotal
5565 };
5566 var highlights = value.highlights;
5567 if (highlights) {
5568 pivotedValue.highlights = [highlights[rowIdx]];
5569 }
5570 pivotedColumns.push(pivotedColumn);
5571 pivotedValues.push(pivotedValue);
5572 }
5573 }
5574 var pivotedMetadata = inherit(dataView.metadata);
5575 pivotedMetadata.columns = pivotedColumns;
5576 values = data.DataViewTransform.createValueColumns(pivotedValues, category.identityFields, category.source);
5577 return {
5578 metadata: pivotedMetadata,
5579 categorical: {
5580 values: values,
5581 },
5582 matrix: dataView.matrix
5583 };
5584 }
5585 DataViewPivotCategorical.apply = apply;
5586 })(DataViewPivotCategorical = data.DataViewPivotCategorical || (data.DataViewPivotCategorical = {}));
5587 })(data = powerbi.data || (powerbi.data = {}));
5588})(powerbi || (powerbi = {}));
5589/*
5590 * Power BI Visualizations
5591 *
5592 * Copyright (c) Microsoft Corporation
5593 * All rights reserved.
5594 * MIT License
5595 *
5596 * Permission is hereby granted, free of charge, to any person obtaining a copy
5597 * of this software and associated documentation files (the ""Software""), to deal
5598 * in the Software without restriction, including without limitation the rights
5599 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5600 * copies of the Software, and to permit persons to whom the Software is
5601 * furnished to do so, subject to the following conditions:
5602 *
5603 * The above copyright notice and this permission notice shall be included in
5604 * all copies or substantial portions of the Software.
5605 *
5606 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5607 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5608 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5609 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5610 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5611 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5612 * THE SOFTWARE.
5613 */
5614var powerbi;
5615(function (powerbi) {
5616 var data;
5617 (function (data) {
5618 var DataViewPivotMatrix;
5619 (function (DataViewPivotMatrix) {
5620 /** Pivots row hierarchy members in a matrix DataView into column hierarchy. */
5621 function apply(dataViewMatrix, context) {
5622 debug.assertValue(dataViewMatrix, 'dataViewMatrix');
5623 if (!context.columnHierarchyRewritten)
5624 dataViewMatrix.columns = powerbi.Prototype.inherit(dataViewMatrix.columns);
5625 var columns = dataViewMatrix.columns;
5626 if (!context.rowHierarchyRewritten)
5627 dataViewMatrix.rows = powerbi.Prototype.inherit(dataViewMatrix.rows);
5628 var rows = dataViewMatrix.rows;
5629 if (columns.levels.length > 1)
5630 return;
5631 var pivotedRowNode = {
5632 level: 0
5633 };
5634 var columnLeafNodes = columns.root.children;
5635 var measureCount = columnLeafNodes.length;
5636 // Notes related to VSTS 6999369: The level value of Measure Header nodes is not necessarily its parent node's level + 1.
5637 // In particular, the Measure Header column nodes directly under the Grand Total node at level 0 (i.e. _.last(pivotResultMatrix.columns.root.children))
5638 // will have level === (pivotResultMatrix.columns.levels.length - 1), which will be greater than the Grand Total node's 'level + 1'
5639 // in a matrix with 2+ column fields and 2+ measure fields.
5640 // In this code, all row levels will get pivoted over to the columns hierarchy, hence the level of any Measure Header nodes in the pivot result
5641 // is just (1 + the level of the deepest row node's level), which === rows.levels.length.
5642 var pivotResultMeasureHeaderLevel = rows.levels.length;
5643 if (measureCount > 0) {
5644 var index_1 = 0;
5645 var callback = function (node) {
5646 // Collect values and remove them from row leaves
5647 if (node.values) {
5648 if (!pivotedRowNode.values)
5649 pivotedRowNode.values = {};
5650 for (var i = 0; i < measureCount; i++)
5651 pivotedRowNode.values[index_1++] = node.values[i];
5652 delete node.values;
5653 }
5654 // Create measure headers if there are more than one measures
5655 if (measureCount > 1) {
5656 if (!node.children)
5657 node.children = [];
5658 for (var j = 0; j < measureCount; j++) {
5659 var measureHeaderLeaf = { level: pivotResultMeasureHeaderLevel };
5660 // Copy levelSourceIndex from columnLeafNodes (as they might have been reordered)
5661 var columnLeafNode = columnLeafNodes[j];
5662 measureHeaderLeaf.levelSourceIndex = columnLeafNode.levelSourceIndex;
5663 if (node.isSubtotal)
5664 measureHeaderLeaf.isSubtotal = true;
5665 node.children.push(measureHeaderLeaf);
5666 }
5667 }
5668 };
5669 if (context.hierarchyTreesRewritten) {
5670 forEachLeaf(rows.root, callback);
5671 }
5672 else {
5673 dataViewMatrix.columns.root = cloneTreeExecuteOnLeaf(rows.root, callback);
5674 }
5675 }
5676 else {
5677 if (!context.hierarchyTreesRewritten) {
5678 dataViewMatrix.columns.root = cloneTree(rows.root);
5679 }
5680 }
5681 if (measureCount > 1) {
5682 // Keep measure headers, but move them to the innermost level
5683 var level = { sources: columns.levels[0].sources };
5684 rows.levels.push(level);
5685 columns.levels.length = 0;
5686 }
5687 if (context.hierarchyTreesRewritten) {
5688 dataViewMatrix.columns.root = rows.root;
5689 dataViewMatrix.rows.root = {
5690 children: [pivotedRowNode]
5691 };
5692 }
5693 else {
5694 var updatedRowRoot = powerbi.Prototype.inherit(dataViewMatrix.rows.root);
5695 updatedRowRoot.children = [pivotedRowNode];
5696 dataViewMatrix.rows.root = updatedRowRoot;
5697 }
5698 dataViewMatrix.columns.levels = rows.levels;
5699 dataViewMatrix.rows.levels = [];
5700 }
5701 DataViewPivotMatrix.apply = apply;
5702 function forEachLeaf(root, callback) {
5703 var children = root.children;
5704 if (children && children.length > 0) {
5705 for (var i = 0, ilen = children.length; i < ilen; i++)
5706 forEachLeaf(children[i], callback);
5707 return;
5708 }
5709 callback(root);
5710 }
5711 function cloneTree(node) {
5712 return cloneTreeExecuteOnLeaf(node);
5713 }
5714 DataViewPivotMatrix.cloneTree = cloneTree;
5715 function cloneTreeExecuteOnLeaf(node, callback) {
5716 var updatedNode = powerbi.Prototype.inherit(node);
5717 var children = node.children;
5718 if (children && children.length > 0) {
5719 var newChildren = [];
5720 for (var i = 0, ilen = children.length; i < ilen; i++) {
5721 var updatedChild = cloneTreeExecuteOnLeaf(children[i], callback);
5722 newChildren.push(updatedChild);
5723 }
5724 updatedNode.children = newChildren;
5725 }
5726 else {
5727 if (callback)
5728 callback(updatedNode);
5729 }
5730 return updatedNode;
5731 }
5732 DataViewPivotMatrix.cloneTreeExecuteOnLeaf = cloneTreeExecuteOnLeaf;
5733 })(DataViewPivotMatrix = data.DataViewPivotMatrix || (data.DataViewPivotMatrix = {}));
5734 })(data = powerbi.data || (powerbi.data = {}));
5735})(powerbi || (powerbi = {}));
5736/*
5737 * Power BI Visualizations
5738 *
5739 * Copyright (c) Microsoft Corporation
5740 * All rights reserved.
5741 * MIT License
5742 *
5743 * Permission is hereby granted, free of charge, to any person obtaining a copy
5744 * of this software and associated documentation files (the ""Software""), to deal
5745 * in the Software without restriction, including without limitation the rights
5746 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5747 * copies of the Software, and to permit persons to whom the Software is
5748 * furnished to do so, subject to the following conditions:
5749 *
5750 * The above copyright notice and this permission notice shall be included in
5751 * all copies or substantial portions of the Software.
5752 *
5753 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5754 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5755 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5756 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5757 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5758 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5759 * THE SOFTWARE.
5760 */
5761var powerbi;
5762(function (powerbi) {
5763 var data;
5764 (function (data) {
5765 var DataViewSelfCrossJoin;
5766 (function (DataViewSelfCrossJoin) {
5767 /**
5768 * Returns a new DataView based on the original, with a single DataViewCategorical category that is "cross joined"
5769 * to itself as a value grouping.
5770 * This is the mathematical equivalent of taking an array and turning it into an identity matrix.
5771 */
5772 function apply(dataView) {
5773 debug.assertValue(dataView, 'dataView');
5774 if (!dataView.categorical)
5775 return;
5776 var dataViewCategorical = dataView.categorical;
5777 if (!dataViewCategorical.categories || dataViewCategorical.categories.length !== 1)
5778 return;
5779 if (dataViewCategorical.values && dataViewCategorical.values.source)
5780 return;
5781 return applyCategorical(dataView.metadata, dataViewCategorical);
5782 }
5783 DataViewSelfCrossJoin.apply = apply;
5784 function applyCategorical(dataViewMetadata, dataViewCategorical) {
5785 debug.assertValue(dataViewMetadata, 'dataViewMetadata');
5786 debug.assertValue(dataViewCategorical, 'dataViewCategorical');
5787 debug.assertValue(dataViewCategorical.categories, 'dataViewCategorical.categories');
5788 var category = dataViewCategorical.categories[0], categoryValues = category.values, categoryLength = categoryValues.length;
5789 if (categoryLength === 0)
5790 return;
5791 var valuesArray = dataViewCategorical.values
5792 ? dataViewCategorical.values.grouped()[0].values
5793 : [];
5794 var transformedDataView = data.createCategoricalDataViewBuilder()
5795 .withCategories(dataViewCategorical.categories)
5796 .withGroupedValues(createGroupedValues(category, categoryValues, categoryLength, valuesArray))
5797 .build();
5798 dataViewMetadata = powerbi.Prototype.inherit(dataViewMetadata);
5799 dataViewMetadata.columns = transformedDataView.metadata.columns;
5800 return {
5801 metadata: dataViewMetadata,
5802 categorical: transformedDataView.categorical,
5803 };
5804 }
5805 function createGroupedValues(category, categoryValues, categoryLength, valuesArray) {
5806 debug.assertValue(category, 'category');
5807 debug.assertValue(categoryValues, 'categoryValues');
5808 debug.assertValue(categoryLength, 'categoryLength');
5809 debug.assertValue(valuesArray, 'valuesArray');
5810 var nullValuesArray = createNullValues(categoryLength), valuesArrayLen = valuesArray.length, seriesData = [];
5811 for (var i = 0; i < categoryLength; i++) {
5812 var seriesDataItem = [];
5813 for (var j = 0; j < valuesArrayLen; j++) {
5814 var originalValueColumn = valuesArray[j], originalHighlightValues = originalValueColumn.highlights;
5815 var seriesDataItemCategory = {
5816 values: inheritArrayWithValue(nullValuesArray, originalValueColumn.values, i),
5817 };
5818 if (originalHighlightValues)
5819 seriesDataItemCategory.highlights = inheritArrayWithValue(nullValuesArray, originalHighlightValues, i);
5820 seriesDataItem.push(seriesDataItemCategory);
5821 }
5822 seriesData.push(seriesDataItem);
5823 }
5824 return {
5825 groupColumn: {
5826 source: category.source,
5827 identityFrom: { fields: category.identityFields, identities: category.identity },
5828 values: category.values,
5829 },
5830 valueColumns: _.map(valuesArray, function (v) { return { source: v.source }; }),
5831 data: seriesData,
5832 };
5833 }
5834 })(DataViewSelfCrossJoin = data.DataViewSelfCrossJoin || (data.DataViewSelfCrossJoin = {}));
5835 function createNullValues(length) {
5836 debug.assertValue(length, 'length');
5837 var array = new Array(length);
5838 for (var i = 0; i < length; i++)
5839 array[i] = null;
5840 return array;
5841 }
5842 function inheritArrayWithValue(nullValues, original, index) {
5843 var inherited = powerbi.Prototype.inherit(nullValues);
5844 inherited[index] = original[index];
5845 return inherited;
5846 }
5847 })(data = powerbi.data || (powerbi.data = {}));
5848})(powerbi || (powerbi = {}));
5849/*
5850 * Power BI Visualizations
5851 *
5852 * Copyright (c) Microsoft Corporation
5853 * All rights reserved.
5854 * MIT License
5855 *
5856 * Permission is hereby granted, free of charge, to any person obtaining a copy
5857 * of this software and associated documentation files (the ""Software""), to deal
5858 * in the Software without restriction, including without limitation the rights
5859 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5860 * copies of the Software, and to permit persons to whom the Software is
5861 * furnished to do so, subject to the following conditions:
5862 *
5863 * The above copyright notice and this permission notice shall be included in
5864 * all copies or substantial portions of the Software.
5865 *
5866 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5867 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5868 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5869 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5870 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5871 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5872 * THE SOFTWARE.
5873 */
5874var powerbi;
5875(function (powerbi) {
5876 var data;
5877 (function (data) {
5878 var ArrayExtensions = jsCommon.ArrayExtensions;
5879 var DataShapeBindingDataReduction = powerbi.data.DataShapeBindingDataReduction;
5880 var inheritSingle = powerbi.Prototype.inheritSingle;
5881 var DataViewPivotCategoricalToPrimaryGroups;
5882 (function (DataViewPivotCategoricalToPrimaryGroups) {
5883 /**
5884 * If mapping requests cross axis data reduction and the binding has secondary grouping, mutates the binding to
5885 * pivot the secondary before the primary.
5886 */
5887 function pivotBinding(binding, allMappings, finalMapping, defaultDataVolume) {
5888 // unpivot is inferred from result in DataViewTransform.apply but it does not have the
5889 // compiled mappings available, let alone the merged mapping, only the original
5890 // DataViewMappings. to keep that inference easy, only apply pivot when there's
5891 // only one matching mapping
5892 if (!allMappings || allMappings.length !== 1)
5893 return;
5894 if (!finalMapping.categorical || !finalMapping.categorical.dataReductionAlgorithm)
5895 return;
5896 if (!binding)
5897 return;
5898 if (!canPivotCategorical(binding, finalMapping))
5899 return;
5900 // pivot secondary onto front of primary
5901 binding.Primary.Groupings = [binding.Secondary.Groupings[0], binding.Primary.Groupings[0]];
5902 binding.Secondary = undefined;
5903 // set primary to pivot reduction
5904 binding.DataReduction = {
5905 Primary: DataShapeBindingDataReduction.createFrom(finalMapping.categorical.dataReductionAlgorithm),
5906 DataVolume: finalMapping.categorical.dataVolume || defaultDataVolume,
5907 };
5908 }
5909 DataViewPivotCategoricalToPrimaryGroups.pivotBinding = pivotBinding;
5910 /** narrowly targets scatter chart scenario for now to keep code simple */
5911 function isPivotableAxis(axis) {
5912 return axis
5913 && axis.Groupings
5914 && axis.Groupings.length === 1
5915 && !_.isEmpty(axis.Groupings[0].Projections)
5916 && !axis.Groupings[0].Subtotal
5917 && _.isEmpty(axis.Groupings[0].SuppressedProjections);
5918 }
5919 function canPivotCategorical(binding, mapping) {
5920 if (!isPivotableAxis(binding.Primary))
5921 return false;
5922 if (!isPivotableAxis(binding.Secondary) || binding.Secondary.Groupings[0].Projections.length !== 1)
5923 return false;
5924 // don't pivot if either axis has a data reduction
5925 if (binding.DataReduction && (binding.DataReduction.Primary || binding.DataReduction.Secondary))
5926 return false;
5927 return true;
5928 }
5929 function unpivotResult(oldDataView, selects, dataViewMappings, projectionActiveItems) {
5930 if (!inferUnpivotTransform(selects, dataViewMappings, oldDataView, projectionActiveItems))
5931 return oldDataView;
5932 // This returns a subsetted version of the DataView rather than using prototypal inheritance because
5933 // any dataviews in the old one (including ones invented after this code is written) will correspond
5934 // to a pivoted query result and therefore will be in the wrong shape for the unpivoted query the
5935 // querying code made.
5936 var newDataView = {
5937 metadata: {
5938 columns: ArrayExtensions.copy(oldDataView.metadata.columns),
5939 },
5940 };
5941 // preserve view types that aren't affected by pivoting
5942 if (oldDataView.single)
5943 newDataView.single = oldDataView.single;
5944 if (oldDataView.table)
5945 newDataView.table = oldDataView.table;
5946 // other views are derived from matrix
5947 if (oldDataView.matrix) {
5948 var newDataViewMatrix = unpivotMatrix(oldDataView.matrix);
5949 // categorical only if there's data
5950 if (!_.isEmpty(newDataViewMatrix.valueSources)) {
5951 // Guard against a DataViewMatrix with composite grouping in columns, because composite group in Series is
5952 // not yet expressible in the current version of DataViewValueColumns and DataViewValueColumnGroup interfaces.
5953 // this.canPivotCategorical() would have returned false in the first place for this query.
5954 var hasCompositeGroupInSeries = data.utils.DataViewMatrixUtils.containsCompositeGroup(newDataViewMatrix.columns);
5955 if (!hasCompositeGroupInSeries) {
5956 newDataView.categorical = categoricalFromUnpivotedMatrix(newDataViewMatrix, newDataView.metadata.columns);
5957 }
5958 }
5959 }
5960 return newDataView;
5961 }
5962 DataViewPivotCategoricalToPrimaryGroups.unpivotResult = unpivotResult;
5963 /**
5964 * Infer from the query result and the visual mappings whether the query was pivoted.
5965 * Narrowly targets scatter chart scenario for now to keep code simple
5966 */
5967 function inferUnpivotTransform(selects, dataViewMappings, dataView, projectionActiveItems) {
5968 if (_.isEmpty(selects) || _.isEmpty(dataViewMappings) || !dataView)
5969 return false;
5970 // select applicable mappings based on select roles
5971 var roleKinds = data.DataViewSelectTransform.createRoleKindFromMetadata(selects, dataView.metadata);
5972 var projections = data.DataViewSelectTransform.projectionsFromSelects(selects, projectionActiveItems);
5973 var supportedDataViewMappings = powerbi.DataViewAnalysis.chooseDataViewMappings(projections, dataViewMappings, roleKinds).supportedMappings;
5974 // NOTE: limiting to simple situation that handles scatter for now - see the other side in canPivotCategorical
5975 if (!supportedDataViewMappings || supportedDataViewMappings.length !== 1)
5976 return false;
5977 var categoricalMapping = supportedDataViewMappings[0].categorical;
5978 if (!categoricalMapping)
5979 return false;
5980 // pivoted query will have produced a matrix
5981 var matrixDataview = dataView.matrix;
5982 if (!matrixDataview)
5983 return false;
5984 // matrix must have two levels of grouping
5985 if (!matrixDataview.rows || !matrixDataview.rows.levels || matrixDataview.rows.levels.length !== 2)
5986 return false;
5987 // get category and value grouping roles
5988 var categoryGroups = [];
5989 var valueGroups = [];
5990 var addGroupingRole = function (roleName, groups) {
5991 var roleProjections = projections[roleName];
5992 if (!roleProjections)
5993 return;
5994 for (var _i = 0, _a = roleProjections.all(); _i < _a.length; _i++) {
5995 var roleProjection = _a[_i];
5996 if (roleKinds[roleProjection.queryRef] === powerbi.VisualDataRoleKind.Grouping)
5997 groups.push(roleProjection.queryRef);
5998 }
5999 };
6000 powerbi.DataViewMapping.visitCategoricalCategories(categoricalMapping.categories, {
6001 visitRole: function (roleName) { addGroupingRole(roleName, categoryGroups); }
6002 });
6003 powerbi.DataViewMapping.visitCategoricalValues(categoricalMapping.values, {
6004 visitRole: function (roleName) { addGroupingRole(roleName, valueGroups); }
6005 });
6006 // need both for pivot to have been done
6007 if (_.isEmpty(categoryGroups) || _.isEmpty(valueGroups))
6008 return false;
6009 // if there was a pivot, there won't be any measures left in the columns
6010 for (var _i = 0, _a = matrixDataview.columns.levels; _i < _a.length; _i++) {
6011 var level = _a[_i];
6012 for (var _b = 0, _c = level.sources; _b < _c.length; _b++) {
6013 var source = _c[_b];
6014 if (!source.isMeasure)
6015 return false;
6016 }
6017 }
6018 return true;
6019 }
6020 /**
6021 * matrix will have two groupings in the rows, outer (series) and inner (categories), and none in the columns.
6022 * this function changes that so that the categories become the rows and the series the columns.
6023 */
6024 function unpivotMatrix(oldMatrix) {
6025 var oldRows = oldMatrix.rows;
6026 var oldRoot = oldRows.root;
6027 var oldChildren = oldRoot.children;
6028 // series are the outer grouping
6029 var series = [];
6030 var seriesIdLevel = oldRows.levels[0];
6031 var seriesIdFields = oldRoot.childIdentityFields;
6032 // categories are the inner grouping.
6033 var categoryIndex = {};
6034 var categories = [];
6035 var categoryIdLevel = oldRows.levels[1];
6036 var categoryIdFields = _.isEmpty(oldChildren) ? undefined : oldChildren[0].childIdentityFields;
6037 var measureCount = oldMatrix.valueSources.length;
6038 // within each series value, the category list may not be complete so cannot simply use the inner loop index
6039 // to reference it.
6040 var findCategory = function (identity) {
6041 var index = categoryIndex[identity.key];
6042 debug.assert(index !== undefined, "findcat() !== undefined");
6043 return index;
6044 };
6045 // collect series and categories from the row hierarchy
6046 if (oldChildren) {
6047 var addCategory = function (categoryNode) {
6048 var key = categoryNode.identity.key;
6049 var index = categoryIndex[key];
6050 if (index === undefined) {
6051 index = categories.length;
6052 categoryIndex[key] = index;
6053 categories.push(categoryNode);
6054 }
6055 };
6056 for (var _i = 0, oldChildren_1 = oldChildren; _i < oldChildren_1.length; _i++) {
6057 var seriesNode = oldChildren_1[_i];
6058 series.push(seriesNode);
6059 for (var _a = 0, _b = seriesNode.children; _a < _b.length; _a++) {
6060 var categoryNode = _b[_a];
6061 addCategory(categoryNode);
6062 }
6063 }
6064 }
6065 // extract intersection values from pivoted matrix
6066 // values will be indexed by categories then series
6067 var matrixValues = new Array(categories.length);
6068 for (var j = 0; j < series.length; ++j) {
6069 var seriesNode = oldChildren[j];
6070 for (var _c = 0, _d = seriesNode.children; _c < _d.length; _c++) {
6071 var categoryNode = _d[_c];
6072 var i = findCategory(categoryNode.identity); // must lookup actual category index
6073 if (!matrixValues[i])
6074 matrixValues[i] = new Array(series.length);
6075 matrixValues[i][j] = categoryNode.values;
6076 }
6077 }
6078 // columns of the unpivoted matrix are the series
6079 var newColumns = {
6080 root: {
6081 children: _.map(series, function (s) {
6082 var inheritedNode = inheritSingle(s);
6083 inheritedNode.level = 0; // s.level should already be 0, but just in case...
6084 inheritedNode.children = undefined; // if Measure Headers exist in oldMatrix.columns, newColumns.root.children will get populated later in this function
6085 inheritedNode.childIdentityFields = undefined;
6086 return inheritedNode;
6087 }),
6088 childIdentityFields: seriesIdFields,
6089 },
6090 levels: [
6091 seriesIdLevel,
6092 ],
6093 };
6094 // Re-add any Measure Headers from oldMatrix.columns as leaf nodes under newColumns
6095 if (measureCount > 0) {
6096 var newColChildren = _.map(oldMatrix.columns.root.children, function (srcnode) {
6097 var dstnode = { level: 1 };
6098 if (srcnode.levelSourceIndex)
6099 dstnode.levelSourceIndex = srcnode.levelSourceIndex;
6100 return dstnode;
6101 });
6102 for (var i = 0; i < newColumns.root.children.length; ++i)
6103 newColumns.root.children[i].children = newColChildren;
6104 newColumns.levels.push(oldMatrix.columns.levels[0]);
6105 }
6106 // rows of the unpivoted matrix are the categories
6107 var newRows = {
6108 root: {
6109 children: _.map(categories, function (c) {
6110 var inheritedNode = inheritSingle(c);
6111 inheritedNode.level = 0;
6112 inheritedNode.children = undefined; // c.children should already be undefined, but just in case...
6113 inheritedNode.childIdentityFields = undefined; // c.children should already be undefined, but just in case...
6114 return inheritedNode;
6115 }),
6116 childIdentityFields: categoryIdFields,
6117 },
6118 levels: [
6119 categoryIdLevel,
6120 ],
6121 };
6122 // put values into rows
6123 if (measureCount > 0) {
6124 for (var i = 0; i < categories.length; ++i) {
6125 var row = newRows.root.children[i];
6126 var rowValues = {};
6127 for (var j = 0; j < series.length; ++j) {
6128 var mvalues = matrixValues[i] && matrixValues[i][j];
6129 for (var k = 0; k < measureCount; ++k) {
6130 var l = j * measureCount + k;
6131 rowValues[l] = !mvalues
6132 ? (k === 0 ? { value: null } : { value: null, valueSourceIndex: k })
6133 : mvalues[k];
6134 }
6135 }
6136 row.values = rowValues;
6137 }
6138 }
6139 var newMatrix = {
6140 rows: newRows,
6141 columns: newColumns,
6142 valueSources: oldMatrix.valueSources,
6143 };
6144 return newMatrix;
6145 }
6146 /** build a categorical data view from an unpivoted matrix. */
6147 function categoricalFromUnpivotedMatrix(matrix, columnMetadata) {
6148 var seriesCount = matrix.columns.root.children.length;
6149 var measureMetadata = matrix.valueSources;
6150 var measureCount = measureMetadata.length;
6151 var categories = createCategoryColumnsFromUnpivotedMatrix(matrix);
6152 // create grouped values
6153 var groups = [];
6154 for (var j = 0; j < seriesCount; ++j) {
6155 var seriesColumn = matrix.columns.root.children[j];
6156 var group = {
6157 values: [],
6158 identity: seriesColumn.identity,
6159 name: seriesColumn.value || null,
6160 };
6161 groups.push(group);
6162 for (var k = 0; k < measureCount; ++k) {
6163 var valueColumnMetadataSrc = measureMetadata[k];
6164 var valueColumnMetadataDst = {};
6165 for (var key in valueColumnMetadataSrc)
6166 valueColumnMetadataDst[key] = valueColumnMetadataSrc[key];
6167 valueColumnMetadataDst.groupName = group.name;
6168 columnMetadata.push(valueColumnMetadataDst);
6169 var valueColumn = {
6170 source: valueColumnMetadataDst,
6171 values: [],
6172 identity: group.identity,
6173 };
6174 group.values.push(valueColumn);
6175 // grab measure values in the group from across rows of matrix
6176 var index = k + j * measureCount;
6177 for (var _i = 0, _a = matrix.rows.root.children; _i < _a.length; _i++) {
6178 var categoryNode = _a[_i];
6179 var value = categoryNode.values[index].value;
6180 valueColumn.values.push(value);
6181 }
6182 }
6183 }
6184 // and now ungrouped
6185 var values = [];
6186 for (var _b = 0, groups_1 = groups; _b < groups_1.length; _b++) {
6187 var group = groups_1[_b];
6188 for (var k = 0; k < measureCount; ++k) {
6189 values.push(group.values[k]);
6190 }
6191 }
6192 values.grouped = function () { return groups; };
6193 values.identityFields = matrix.columns.root.childIdentityFields;
6194 values.source = matrix.columns.levels[0].sources[0];
6195 // final assembly
6196 var categorical = {
6197 categories: categories,
6198 values: values,
6199 };
6200 return categorical;
6201 }
6202 function createCategoryColumnsFromUnpivotedMatrix(unpivotedMatrix) {
6203 debug.assertValue(unpivotedMatrix, 'unpivotedMatrix');
6204 debug.assert(unpivotedMatrix && unpivotedMatrix.rows && unpivotedMatrix.rows.levels && (unpivotedMatrix.rows.levels.length === 1), 'pre-condition: unpivotedMatrix should have exactly one level in row hierarchy');
6205 // Create categories from rows. If matrix.rows.levels[0].sources represents a composite group, expand each column in the
6206 // composite group into a separate DataViewCategoryColumn. The identity and childIdentityFields properties will be the
6207 // same amongst the resulting DataViewCategoryColumns.
6208 var categoryIdentity = _.map(unpivotedMatrix.rows.root.children, function (x) { return x.identity; });
6209 var categoryIdentityFields = unpivotedMatrix.rows.root.childIdentityFields;
6210 var categorySourceColumns = unpivotedMatrix.rows.levels[0].sources;
6211 var categories = [];
6212 for (var i = 0, ilen = categorySourceColumns.length; i < ilen; i++) {
6213 var groupLevelValues = _.map(unpivotedMatrix.rows.root.children, function (categoryNode) {
6214 var levelValues = categoryNode.levelValues;
6215 // Please refer to the interface comments on when this is undefined... But in today's code
6216 // I believe we will not see undefined levelValues in the rows of any unpivotedMatrix.
6217 if (levelValues !== undefined) {
6218 debug.assert(levelValues[i] && (levelValues[i].levelSourceIndex === i), 'pre-condition: DataViewMatrixNode.levelValues is expected to have one DataViewMatrixGroupValue node per level source column, sorted by levelSourceIndex.');
6219 return levelValues[i].value;
6220 }
6221 });
6222 categories.push({
6223 source: categorySourceColumns[i],
6224 values: groupLevelValues,
6225 identity: categoryIdentity,
6226 identityFields: categoryIdentityFields,
6227 });
6228 }
6229 return categories;
6230 }
6231 })(DataViewPivotCategoricalToPrimaryGroups = data.DataViewPivotCategoricalToPrimaryGroups || (data.DataViewPivotCategoricalToPrimaryGroups = {}));
6232 })(data = powerbi.data || (powerbi.data = {}));
6233})(powerbi || (powerbi = {}));
6234/*
6235 * Power BI Visualizations
6236 *
6237 * Copyright (c) Microsoft Corporation
6238 * All rights reserved.
6239 * MIT License
6240 *
6241 * Permission is hereby granted, free of charge, to any person obtaining a copy
6242 * of this software and associated documentation files (the ""Software""), to deal
6243 * in the Software without restriction, including without limitation the rights
6244 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6245 * copies of the Software, and to permit persons to whom the Software is
6246 * furnished to do so, subject to the following conditions:
6247 *
6248 * The above copyright notice and this permission notice shall be included in
6249 * all copies or substantial portions of the Software.
6250 *
6251 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6252 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6253 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6254 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6255 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6256 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
6257 * THE SOFTWARE.
6258 */
6259var powerbi;
6260(function (powerbi) {
6261 var data;
6262 (function (data) {
6263 var inherit = powerbi.Prototype.inherit;
6264 var inheritSingle = powerbi.Prototype.inheritSingle;
6265 var ArrayExtensions = jsCommon.ArrayExtensions;
6266 var EnumExtensions = jsCommon.EnumExtensions;
6267 // TODO: refactor & focus DataViewTransform into a service with well-defined dependencies.
6268 var DataViewTransform;
6269 (function (DataViewTransform) {
6270 var fillRulePropertyDescriptor = { type: { fillRule: {} } };
6271 function apply(options) {
6272 debug.assertValue(options, 'options');
6273 // TODO: Flow a context object through to capture errors/warnings about what happens here for better diagnosability.
6274 var prototype = options.prototype, objectDescriptors = options.objectDescriptors, dataViewMappings = options.dataViewMappings, transforms = options.transforms, projectionActiveItems = transforms && transforms.roles && transforms.roles.activeItems, colorAllocatorFactory = options.colorAllocatorFactory, dataRoles = options.dataRoles;
6275 if (!prototype)
6276 return transformEmptyDataView(objectDescriptors, transforms, colorAllocatorFactory);
6277 if (!transforms)
6278 return [prototype];
6279 // Transform Query DataView
6280 prototype = data.DataViewPivotCategoricalToPrimaryGroups.unpivotResult(prototype, transforms.selects, dataViewMappings, projectionActiveItems);
6281 var visualDataViews = transformQueryToVisualDataView(prototype, transforms, objectDescriptors, dataViewMappings, colorAllocatorFactory, dataRoles);
6282 // Transform and generate derived visual DataViews
6283 visualDataViews = data.DataViewRegression.run({
6284 dataViewMappings: dataViewMappings,
6285 visualDataViews: visualDataViews,
6286 dataRoles: dataRoles,
6287 objectDescriptors: objectDescriptors,
6288 objectDefinitions: transforms.objects,
6289 colorAllocatorFactory: colorAllocatorFactory,
6290 transformSelects: transforms.selects,
6291 metadata: prototype.metadata,
6292 projectionActiveItems: projectionActiveItems,
6293 });
6294 return visualDataViews;
6295 }
6296 DataViewTransform.apply = apply;
6297 function transformQueryToVisualDataView(prototype, transforms, objectDescriptors, dataViewMappings, colorAllocatorFactory, dataRoles) {
6298 var transformedDataViews = [];
6299 var splits = transforms.splits;
6300 if (_.isEmpty(splits)) {
6301 transformedDataViews.push(transformDataView(prototype, objectDescriptors, dataViewMappings, transforms, colorAllocatorFactory, dataRoles));
6302 }
6303 else {
6304 for (var _i = 0, splits_1 = splits; _i < splits_1.length; _i++) {
6305 var split = splits_1[_i];
6306 var transformed = transformDataView(prototype, objectDescriptors, dataViewMappings, transforms, colorAllocatorFactory, dataRoles, split.selects);
6307 transformedDataViews.push(transformed);
6308 }
6309 }
6310 return transformedDataViews;
6311 }
6312 function transformEmptyDataView(objectDescriptors, transforms, colorAllocatorFactory) {
6313 if (transforms && transforms.objects) {
6314 var emptyDataView = {
6315 metadata: {
6316 columns: [],
6317 }
6318 };
6319 transformObjects(emptyDataView, 0 /* None */, objectDescriptors, transforms.objects, transforms.selects, colorAllocatorFactory);
6320 return [emptyDataView];
6321 }
6322 return [];
6323 }
6324 function transformDataView(prototype, objectDescriptors, roleMappings, transforms, colorAllocatorFactory, dataRoles, selectsToInclude) {
6325 debug.assertValue(prototype, 'prototype');
6326 debug.assertValue(transforms, 'transforms');
6327 debug.assert(!selectsToInclude ||
6328 _.filter(Object.keys(selectsToInclude), function (selectIndex) { return selectsToInclude[selectIndex] && (!transforms.selects || !transforms.selects[selectIndex]); })
6329 .length === 0, // asserts that the number of select indices in selectsToInclude without a corresponding Select Transform === 0
6330 'If selectsToInclude is specified, every Select Index in it must have a corresponding Select Transform.');
6331 var targetKinds = getTargetKinds(roleMappings);
6332 var transformed = inherit(prototype);
6333 transformed.metadata = inherit(prototype.metadata);
6334 var projectionOrdering = transforms.roles && transforms.roles.ordering;
6335 var projectionActiveItems = transforms.roles && transforms.roles.activeItems;
6336 transformed = transformSelects(transformed, targetKinds, roleMappings, transforms.selects, projectionOrdering, selectsToInclude);
6337 transformObjects(transformed, targetKinds, objectDescriptors, transforms.objects, transforms.selects, colorAllocatorFactory);
6338 // Note: Do this step after transformObjects() so that metadata columns in 'transformed' have roles and objects.general.formatString populated
6339 transformed = data.DataViewConcatenateCategoricalColumns.detectAndApply(transformed, objectDescriptors, roleMappings, projectionOrdering, transforms.selects, projectionActiveItems);
6340 data.DataViewNormalizeValues.apply({
6341 dataview: transformed,
6342 dataViewMappings: roleMappings,
6343 dataRoles: dataRoles,
6344 });
6345 return transformed;
6346 }
6347 function getTargetKinds(roleMappings) {
6348 debug.assertAnyValue(roleMappings, 'roleMappings');
6349 if (!roleMappings)
6350 return 0 /* None */;
6351 var result = 0 /* None */;
6352 for (var _i = 0, roleMappings_1 = roleMappings; _i < roleMappings_1.length; _i++) {
6353 var roleMapping = roleMappings_1[_i];
6354 if (roleMapping.categorical)
6355 result |= 1 /* Categorical */;
6356 if (roleMapping.matrix)
6357 result |= 2 /* Matrix */;
6358 if (roleMapping.single)
6359 result |= 4 /* Single */;
6360 if (roleMapping.table)
6361 result |= 8 /* Table */;
6362 if (roleMapping.tree)
6363 result |= 16 /* Tree */;
6364 }
6365 return result;
6366 }
6367 function transformSelects(dataView, targetDataViewKinds, roleMappings, selectTransforms, projectionOrdering, selectsToInclude) {
6368 var columnRewrites = [];
6369 if (selectTransforms) {
6370 dataView.metadata.columns = applyTransformsToColumns(dataView.metadata.columns, selectTransforms, columnRewrites);
6371 }
6372 // NOTE: no rewrites necessary for Tree (it doesn't reference the columns)
6373 if (dataView.categorical && EnumExtensions.hasFlag(targetDataViewKinds, 1 /* Categorical */)) {
6374 dataView.categorical = applyRewritesToCategorical(dataView.categorical, columnRewrites, selectsToInclude);
6375 // TODO VSTS 7024199: separate out structural transformations from dataViewTransform.transformSelects(...)
6376 // NOTE: This is slightly DSR-specific.
6377 dataView = pivotIfNecessary(dataView, roleMappings);
6378 }
6379 // Don't perform this potentially expensive transform unless we actually have a matrix.
6380 // When we switch to lazy per-visual DataView creation, we'll be able to remove this check.
6381 if (dataView.matrix && EnumExtensions.hasFlag(targetDataViewKinds, 2 /* Matrix */)) {
6382 var matrixTransformationContext = {
6383 rowHierarchyRewritten: false,
6384 columnHierarchyRewritten: false,
6385 hierarchyTreesRewritten: false
6386 };
6387 dataView.matrix = applyRewritesToMatrix(dataView.matrix, columnRewrites, roleMappings, projectionOrdering, matrixTransformationContext);
6388 // TODO VSTS 7024199: separate out structural transformations from dataViewTransform.transformSelects(...)
6389 if (shouldPivotMatrix(dataView.matrix, roleMappings))
6390 data.DataViewPivotMatrix.apply(dataView.matrix, matrixTransformationContext);
6391 }
6392 // Don't perform this potentially expensive transform unless we actually have a table.
6393 // When we switch to lazy per-visual DataView creation, we'll be able to remove this check.
6394 if (dataView.table && EnumExtensions.hasFlag(targetDataViewKinds, 8 /* Table */)) {
6395 dataView.table = applyRewritesToTable(dataView.table, columnRewrites, projectionOrdering);
6396 }
6397 return dataView;
6398 }
6399 function applyTransformsToColumns(prototypeColumns, selects, rewrites) {
6400 debug.assertValue(prototypeColumns, 'columns');
6401 if (!selects)
6402 return prototypeColumns;
6403 //column may contain undefined entries
6404 var columns = inherit(prototypeColumns);
6405 for (var i = 0, len = prototypeColumns.length; i < len; i++) {
6406 var prototypeColumn = prototypeColumns[i];
6407 var select = selects[prototypeColumn.index];
6408 if (!select)
6409 continue;
6410 var column = columns[i] = inherit(prototypeColumn);
6411 if (select.roles)
6412 column.roles = select.roles;
6413 if (select.type)
6414 column.type = select.type;
6415 column.format = getFormatForColumn(select, column);
6416 if (select.displayName)
6417 column.displayName = select.displayName;
6418 if (select.queryName)
6419 column.queryName = select.queryName;
6420 if (select.kpi)
6421 column.kpi = select.kpi;
6422 if (select.sort)
6423 column.sort = select.sort;
6424 if (select.discourageAggregationAcrossGroups)
6425 column.discourageAggregationAcrossGroups = select.discourageAggregationAcrossGroups;
6426 rewrites.push({
6427 from: prototypeColumn,
6428 to: column,
6429 });
6430 }
6431 return columns;
6432 }
6433 /**
6434 * Get the column format. Order of precendence is:
6435 * 1. Select format
6436 * 2. Column format
6437 */
6438 function getFormatForColumn(select, column) {
6439 // TODO: we already copied the select.Format to column.format, we probably don't need this check
6440 return select.format || column.format;
6441 }
6442 function applyRewritesToCategorical(prototype, columnRewrites, selectsToInclude) {
6443 debug.assertValue(prototype, 'prototype');
6444 debug.assertValue(columnRewrites, 'columnRewrites');
6445 var categorical = inherit(prototype);
6446 function override(value) {
6447 var rewrittenSource = findOverride(value.source, columnRewrites);
6448 if (rewrittenSource) {
6449 var rewritten = inherit(value);
6450 rewritten.source = rewrittenSource;
6451 return rewritten;
6452 }
6453 }
6454 var categories = powerbi.Prototype.overrideArray(prototype.categories, override);
6455 if (categories)
6456 categorical.categories = categories;
6457 var valuesOverride = powerbi.Prototype.overrideArray(prototype.values, override);
6458 var valueColumns = valuesOverride || prototype.values;
6459 if (valueColumns) {
6460 if (valueColumns.source) {
6461 if (selectsToInclude && !selectsToInclude[valueColumns.source.index]) {
6462 // if processing a split and this is the split without series...
6463 valueColumns.source = undefined;
6464 }
6465 else {
6466 var rewrittenValuesSource = findOverride(valueColumns.source, columnRewrites);
6467 if (rewrittenValuesSource)
6468 valueColumns.source = rewrittenValuesSource;
6469 }
6470 }
6471 if (selectsToInclude) {
6472 // Apply selectsToInclude to values by removing value columns not included
6473 for (var i = valueColumns.length - 1; i >= 0; i--) {
6474 if (!selectsToInclude[valueColumns[i].source.index]) {
6475 valueColumns.splice(i, 1);
6476 }
6477 }
6478 }
6479 var isDynamicSeries_1 = !!valueColumns.source;
6480 debug.assert(_.every(valueColumns, function (valueColumn) { return isDynamicSeries_1 === !!valueColumn.identity; }), 'After applying selectsToInclude, all remaining DataViewValueColumn objects should have a consistent scope type (static vs. dynamic) with the parent DataViewValueColumns object.');
6481 // Dynamic or not, always update the return values of grouped() to have the rewritten 'source' property
6482 var seriesGroups_1;
6483 if (isDynamicSeries_1) {
6484 // We have a dynamic series, so update the return value of grouped() to have the DataViewValueColumn objects with rewritten 'source'.
6485 // Also, exclude any column that belongs to a static series.
6486 seriesGroups_1 = inherit(valueColumns.grouped());
6487 // The following assert is not a rule that's set in stone. If it becomes false someday, update the code below to remove static series from seriesGroups.
6488 debug.assert(_.every(seriesGroups_1, function (group) { return !!group.identity; }), 'If the categorical has a dynamic series, query DataView is expected to have a grouped() function that returns only dynamic series groups, even when there is any column that belongs to a static group (in the case of combo chart and splits). If this assertion becomes false someday, update the code below to remove static series from seriesGroups.');
6489 var nextSeriesGroupIndex = 0;
6490 var currentSeriesGroup = void 0;
6491 for (var i = 0, ilen = valueColumns.length; i < ilen; i++) {
6492 var currentValueColumn = valueColumns[i];
6493 if (!currentSeriesGroup || (currentValueColumn.identity !== currentSeriesGroup.identity)) {
6494 currentSeriesGroup = inherit(seriesGroups_1[nextSeriesGroupIndex]);
6495 seriesGroups_1[nextSeriesGroupIndex] = currentSeriesGroup;
6496 currentSeriesGroup.values = [];
6497 nextSeriesGroupIndex++;
6498 debug.assert(currentValueColumn.identity === currentSeriesGroup.identity, 'expecting the value columns are sequenced by series groups');
6499 }
6500 currentSeriesGroup.values.push(currentValueColumn);
6501 }
6502 }
6503 else {
6504 // We are in a static series, so we should throw away the grouped and recreate it using the static values
6505 // which have already been filtered
6506 seriesGroups_1 = [{ values: valueColumns }];
6507 }
6508 valueColumns.grouped = function () { return seriesGroups_1; };
6509 categorical.values = valueColumns;
6510 }
6511 return categorical;
6512 }
6513 function applyRewritesToTable(prototype, columnRewrites, projectionOrdering) {
6514 debug.assertValue(prototype, 'prototype');
6515 debug.assertValue(columnRewrites, 'columnRewrites');
6516 var table = inherit(prototype);
6517 // Copy the rewritten columns into the table view
6518 var override = function (metadata) { return findOverride(metadata, columnRewrites); };
6519 var columns = powerbi.Prototype.overrideArray(prototype.columns, override);
6520 if (columns)
6521 table.columns = columns;
6522 if (!projectionOrdering)
6523 return table;
6524 var newToOldPositions = createTableColumnPositionMapping(projectionOrdering, columnRewrites);
6525 if (!newToOldPositions)
6526 return table;
6527 // Reorder the columns
6528 var columnsClone = columns.slice(0);
6529 var keys = Object.keys(newToOldPositions);
6530 for (var i = 0, len = keys.length; i < len; i++) {
6531 var sourceColumn = columnsClone[newToOldPositions[keys[i]]];
6532 // In the case we've hit the end of our columns array, but still have position reordering keys,
6533 // there is a duplicate column so we will need to add a new column for the duplicate data
6534 if (i === columns.length)
6535 columns.push(sourceColumn);
6536 else {
6537 debug.assert(i < columns.length, 'The column index is out of range for reordering.');
6538 columns[i] = sourceColumn;
6539 }
6540 }
6541 // Reorder the rows
6542 var rows = powerbi.Prototype.overrideArray(table.rows, function (row) {
6543 var newRow = [];
6544 for (var i = 0, len = keys.length; i < len; ++i)
6545 newRow[i] = row[newToOldPositions[keys[i]]];
6546 return newRow;
6547 });
6548 if (rows)
6549 table.rows = rows;
6550 return table;
6551 }
6552 /** Creates a mapping of new position to original position. */
6553 function createTableColumnPositionMapping(projectionOrdering, columnRewrites) {
6554 var roles = Object.keys(projectionOrdering);
6555 // If we have more than one role then the ordering of columns between roles is ambiguous, so don't reorder anything.
6556 if (roles.length !== 1)
6557 return;
6558 var role = roles[0], originalOrder = _.map(columnRewrites, function (rewrite) { return rewrite.from.index; }), newOrder = projectionOrdering[role];
6559 return createOrderMapping(originalOrder, newOrder);
6560 }
6561 function applyRewritesToMatrix(prototype, columnRewrites, roleMappings, projectionOrdering, context) {
6562 debug.assertValue(prototype, 'prototype');
6563 debug.assertValue(columnRewrites, 'columnRewrites');
6564 debug.assertValue(roleMappings, 'roleMappings');
6565 var firstRoleMappingWithMatrix = _.find(roleMappings, function (roleMapping) { return !!roleMapping.matrix; });
6566 debug.assertValue(firstRoleMappingWithMatrix, 'roleMappings - at least one role mapping is expected to target DataViewMatrix');
6567 var matrixMapping = firstRoleMappingWithMatrix.matrix;
6568 var matrix = inherit(prototype);
6569 function override(metadata) {
6570 return findOverride(metadata, columnRewrites);
6571 }
6572 function overrideHierarchy(hierarchy) {
6573 var rewrittenHierarchy = null;
6574 var newLevels = powerbi.Prototype.overrideArray(hierarchy.levels, function (level) {
6575 var newLevel = null;
6576 var levelSources = powerbi.Prototype.overrideArray(level.sources, override);
6577 if (levelSources)
6578 newLevel = ensureRewritten(newLevel, level, function (h) { return h.sources = levelSources; });
6579 return newLevel;
6580 });
6581 if (newLevels)
6582 rewrittenHierarchy = ensureRewritten(rewrittenHierarchy, hierarchy, function (r) { return r.levels = newLevels; });
6583 return rewrittenHierarchy;
6584 }
6585 var rows = overrideHierarchy(matrix.rows);
6586 if (rows) {
6587 matrix.rows = rows;
6588 context.rowHierarchyRewritten = true;
6589 }
6590 var columns = overrideHierarchy(matrix.columns);
6591 if (columns) {
6592 matrix.columns = columns;
6593 context.columnHierarchyRewritten = true;
6594 }
6595 var valueSources = powerbi.Prototype.overrideArray(matrix.valueSources, override);
6596 if (valueSources) {
6597 matrix.valueSources = valueSources;
6598 // Only need to reorder if we have more than one value source, and they are all bound to the same role
6599 var matrixValues = matrixMapping.values;
6600 if (projectionOrdering && valueSources.length > 1 && matrixValues && matrixValues.for) {
6601 var columnLevels = columns.levels.length;
6602 if (columnLevels > 0) {
6603 var newToOldPositions_1 = createMatrixValuesPositionMapping(matrixValues, projectionOrdering, valueSources, columnRewrites);
6604 if (newToOldPositions_1) {
6605 var keys_1 = Object.keys(newToOldPositions_1);
6606 var numKeys_1 = keys_1.length;
6607 // Reorder the value columns
6608 columns.root = data.DataViewPivotMatrix.cloneTree(columns.root);
6609 if (columnLevels === 1)
6610 reorderChildNodes(columns.root, newToOldPositions_1);
6611 else
6612 forEachNodeAtLevel(columns.root, columnLevels - 2, function (node) { return reorderChildNodes(node, newToOldPositions_1); });
6613 // Reorder the value rows
6614 matrix.rows.root = data.DataViewPivotMatrix.cloneTreeExecuteOnLeaf(matrix.rows.root, function (node) {
6615 if (!node.values)
6616 return;
6617 var newValues = {};
6618 var iterations = Object.keys(node.values).length / numKeys_1;
6619 for (var i = 0, len = iterations; i < len; i++) {
6620 var offset = i * numKeys_1;
6621 for (var keysIndex = 0; keysIndex < numKeys_1; keysIndex++)
6622 newValues[offset + keysIndex] = node.values[offset + newToOldPositions_1[keys_1[keysIndex]]];
6623 }
6624 node.values = newValues;
6625 });
6626 context.hierarchyTreesRewritten = true;
6627 }
6628 }
6629 }
6630 }
6631 reorderMatrixCompositeGroups(matrix, matrixMapping, projectionOrdering);
6632 return matrix;
6633 }
6634 function reorderChildNodes(node, newToOldPositions) {
6635 var keys = Object.keys(newToOldPositions);
6636 var numKeys = keys.length;
6637 var children = node.children;
6638 var childrenClone = children.slice(0);
6639 for (var i = 0, len = numKeys; i < len; i++) {
6640 var sourceColumn = childrenClone[newToOldPositions[keys[i]]];
6641 // In the case we've hit the end of our columns array, but still have position reordering keys,
6642 // there is a duplicate column so we will need to add a new column for the duplicate data
6643 if (i === children.length)
6644 children.push(sourceColumn);
6645 else {
6646 debug.assert(i < children.length, 'The column index is out of range for reordering.');
6647 children[i] = sourceColumn;
6648 }
6649 }
6650 }
6651 /**
6652 * Returns a inheritSingle() version of the specified prototype DataViewMatrix with any composite group levels
6653 * and values re-ordered by projection ordering.
6654 * Returns undefined if no re-ordering under the specified prototype is necessary.
6655 */
6656 function reorderMatrixCompositeGroups(prototype, supportedDataViewMapping, projection) {
6657 var transformedDataView;
6658 if (prototype && supportedDataViewMapping && projection) {
6659 // reorder levelValues in any composite groups in rows hierarchy
6660 var transformedRowsHierarchy_1;
6661 powerbi.DataViewMapping.visitMatrixItems(supportedDataViewMapping.rows, {
6662 visitRole: function (role, context) {
6663 transformedRowsHierarchy_1 = reorderMatrixHierarchyCompositeGroups(transformedRowsHierarchy_1 || prototype.rows, role, projection);
6664 }
6665 });
6666 // reorder levelValues in any composite groups in columns hierarchy
6667 var transformedColumnsHierarchy_1;
6668 powerbi.DataViewMapping.visitMatrixItems(supportedDataViewMapping.columns, {
6669 visitRole: function (role, context) {
6670 transformedColumnsHierarchy_1 = reorderMatrixHierarchyCompositeGroups(transformedColumnsHierarchy_1 || prototype.columns, role, projection);
6671 }
6672 });
6673 if (transformedRowsHierarchy_1 || transformedColumnsHierarchy_1) {
6674 transformedDataView = inheritSingle(prototype);
6675 transformedDataView.rows = transformedRowsHierarchy_1 || transformedDataView.rows;
6676 transformedDataView.columns = transformedColumnsHierarchy_1 || transformedDataView.columns;
6677 }
6678 }
6679 return transformedDataView;
6680 }
6681 /**
6682 * Returns a inheritSingle() version of the specified matrixHierarchy with any composite group levels and
6683 * values re-ordered by projection ordering.
6684 * Returns undefined if no re-ordering under the specified matrixHierarchy is necessary.
6685 */
6686 function reorderMatrixHierarchyCompositeGroups(matrixHierarchy, hierarchyRole, projection) {
6687 debug.assertValue(matrixHierarchy, 'matrixHierarchy');
6688 debug.assertValue(hierarchyRole, 'hierarchyRole');
6689 debug.assertValue(projection, 'projection');
6690 var transformedHierarchy;
6691 var selectIndicesInProjectionOrder = projection[hierarchyRole];
6692 // reordering needs to happen only if there are multiple columns for the hierarchy's role in the projection
6693 var hasMultipleColumnsInProjection = selectIndicesInProjectionOrder && selectIndicesInProjectionOrder.length >= 2;
6694 if (hasMultipleColumnsInProjection && !_.isEmpty(matrixHierarchy.levels)) {
6695 for (var i = matrixHierarchy.levels.length - 1; i >= 0; i--) {
6696 var hierarchyLevel = matrixHierarchy.levels[i];
6697 // compute a mapping for any necessary reordering of columns at this given level, based on projection ordering
6698 var newToOldLevelSourceIndicesMapping = createMatrixHierarchyLevelSourcesPositionMapping(hierarchyLevel, hierarchyRole, projection);
6699 if (newToOldLevelSourceIndicesMapping) {
6700 if (_.isUndefined(transformedHierarchy)) {
6701 // Because we start inspecting the hierarchy from the deepest level and work backwards to the root,
6702 // the current hierarchyLevel is therefore the inner-most level that needs re-ordering of composite group values...
6703 transformedHierarchy = inheritSingle(matrixHierarchy);
6704 transformedHierarchy.levels = inheritSingle(matrixHierarchy.levels);
6705 // Because the current hierarchyLevel is the inner-most level that needs re-ordering of composite group values,
6706 // inheriting all nodes from root down to this level will also prepare the nodes for any transform that needs to
6707 // happen in other hierarchy levels in the later iterations of this for-loop.
6708 transformedHierarchy.root = data.utils.DataViewMatrixUtils.inheritMatrixNodeHierarchy(matrixHierarchy.root, i, true);
6709 }
6710 // reorder the metadata columns in the sources array at that level
6711 var transformingHierarchyLevel = inheritSingle(matrixHierarchy.levels[i]); // inherit at most once during the whole dataViewTransform for this obj...
6712 transformedHierarchy.levels[i] = reorderMatrixHierarchyLevelColumnSources(transformingHierarchyLevel, newToOldLevelSourceIndicesMapping);
6713 // reorder the level values in the composite group nodes at the current hierarchy level
6714 reorderMatrixHierarchyLevelValues(transformedHierarchy.root, i, newToOldLevelSourceIndicesMapping);
6715 }
6716 }
6717 }
6718 return transformedHierarchy;
6719 }
6720 /**
6721 * If reordering is needed on the level's metadata column sources (i.e. hierarchyLevel.sources),
6722 * returns the mapping from the target LevelSourceIndex (based on projection order) to original LevelSourceIndex.
6723 *
6724 * The returned value maps level source indices from the new target order (calculated from projection order)
6725 * back to the original order as they appear in the specified hierarchyLevel's sources.
6726 * Please refer to comments on the createOrderMapping() function for more explanation on the mappings in the return value.
6727 *
6728 * Note: The return value is the mapping from new index to old index, for consistency with existing and similar functions in this module.
6729 *
6730 * @param hierarchyLevel The hierarchy level that contains the metadata column sources.
6731 * @param hierarchyRoleName The role name for the hierarchy where the specified hierarchyLevel belongs.
6732 * @param projection The projection ordering that includes an ordering for the specified hierarchyRoleName.
6733 */
6734 function createMatrixHierarchyLevelSourcesPositionMapping(hierarchyLevel, hierarchyRole, projection) {
6735 debug.assertValue(hierarchyLevel, 'hierarchyLevel');
6736 debug.assertValue(hierarchyRole, 'hierarchyRole');
6737 debug.assertValue(projection, 'projection');
6738 debug.assertValue(projection[hierarchyRole], 'pre-condition: The specified projection must contain an ordering for the specified hierarchyRoleName.');
6739 var newToOldLevelSourceIndicesMapping;
6740 var levelSourceColumns = hierarchyLevel.sources;
6741 if (levelSourceColumns && levelSourceColumns.length >= 2) {
6742 // The hierarchy level has multiple columns, so it is possible to have composite group, go on to check other conditions...
6743 var columnsForHierarchyRoleOrderedByLevelSourceIndex = data.utils.DataViewMetadataColumnUtils.joinMetadataColumnsAndProjectionOrder(levelSourceColumns, projection, hierarchyRole);
6744 if (columnsForHierarchyRoleOrderedByLevelSourceIndex && columnsForHierarchyRoleOrderedByLevelSourceIndex.length >= 2) {
6745 // The hierarchy level has multiple columns for the hierarchy's role, go on to calculate newToOldLevelSourceIndicesMapping...
6746 var columnsForHierarchyRoleOrderedByProjection = _.sortBy(columnsForHierarchyRoleOrderedByLevelSourceIndex, function (columnInfo) { return columnInfo.projectionOrderIndex; });
6747 newToOldLevelSourceIndicesMapping = createOrderMapping(_.map(columnsForHierarchyRoleOrderedByLevelSourceIndex, function (columnInfo) { return columnInfo.sourceIndex; }), _.map(columnsForHierarchyRoleOrderedByProjection, function (columnInfo) { return columnInfo.sourceIndex; }));
6748 }
6749 }
6750 return newToOldLevelSourceIndicesMapping;
6751 }
6752 /**
6753 * Applies re-ordering on the specified transformingHierarchyLevel's sources.
6754 * Returns the same object as the specified transformingHierarchyLevel.
6755 */
6756 function reorderMatrixHierarchyLevelColumnSources(transformingHierarchyLevel, newToOldLevelSourceIndicesMapping) {
6757 debug.assertValue(transformingHierarchyLevel, 'transformingHierarchyLevel');
6758 debug.assertValue(newToOldLevelSourceIndicesMapping, 'newToOldLevelSourceIndicesMapping');
6759 var originalLevelSources = transformingHierarchyLevel.sources;
6760 transformingHierarchyLevel.sources = originalLevelSources.slice(0); // make a clone of the array before modifying it, because the for-loop depends on the origin array.
6761 var newLevelSourceIndices = Object.keys(newToOldLevelSourceIndicesMapping);
6762 for (var i = 0, ilen = newLevelSourceIndices.length; i < ilen; i++) {
6763 var newLevelSourceIndex = newLevelSourceIndices[i];
6764 var oldLevelSourceIndex = newToOldLevelSourceIndicesMapping[newLevelSourceIndex];
6765 debug.assert(oldLevelSourceIndex < originalLevelSources.length, 'pre-condition: The value in every mapping in the specified levelSourceIndicesReorderingMap must be a valid index to the specified hierarchyLevel.sources array property');
6766 transformingHierarchyLevel.sources[newLevelSourceIndex] = originalLevelSources[oldLevelSourceIndex];
6767 }
6768 return transformingHierarchyLevel;
6769 }
6770 /**
6771 * Reorders the elements in levelValues in each node under transformingHierarchyRootNode at the specified hierarchyLevel,
6772 * and updates their DataViewMatrixGroupValue.levelSourceIndex property.
6773 *
6774 * Returns the same object as the specified transformingHierarchyRootNode.
6775 */
6776 function reorderMatrixHierarchyLevelValues(transformingHierarchyRootNode, transformingHierarchyLevelIndex, newToOldLevelSourceIndicesMapping) {
6777 debug.assertValue(transformingHierarchyRootNode, 'transformingHierarchyRootNode');
6778 debug.assertValue(newToOldLevelSourceIndicesMapping, 'newToOldLevelSourceIndicesMapping');
6779 var oldToNewLevelSourceIndicesMapping = createReversedMapping(newToOldLevelSourceIndicesMapping);
6780 forEachNodeAtLevel(transformingHierarchyRootNode, transformingHierarchyLevelIndex, function (transformingMatrixNode) {
6781 var originalLevelValues = transformingMatrixNode.levelValues;
6782 // Note: Technically this function is incorrect, because the driving source of the new LevelValues is really
6783 // the "projection for this composite group", a concept that isn't yet implemented in DataViewProjectionOrdering.
6784 // The following code isn't correct in the special case where a column is projected twice in this composite group,
6785 // in which case the DSR will not have the duplicate columns; DataViewTransform is supposed to expand the duplicates.
6786 // Until we fully implement composite group projection, though, we'll just sort what we have in transformingMatrixNode.levelValues.
6787 if (!_.isEmpty(originalLevelValues)) {
6788 // First, re-order the elements in transformingMatrixNode.levelValues by the new levelSourceIndex order.
6789 // _.sortBy() also creates a new array, which we want to do for all nodes (including when levelValues.length === 1)
6790 // because we don't want to accidentally modify the array AND its value references in Query DataView
6791 var newlyOrderedLevelValues = _.sortBy(originalLevelValues, function (levelValue) { return oldToNewLevelSourceIndicesMapping[levelValue.levelSourceIndex]; });
6792 for (var i = 0, ilen = newlyOrderedLevelValues.length; i < ilen; i++) {
6793 var transformingLevelValue = inheritSingle(newlyOrderedLevelValues[i]);
6794 transformingLevelValue.levelSourceIndex = oldToNewLevelSourceIndicesMapping[transformingLevelValue.levelSourceIndex];
6795 newlyOrderedLevelValues[i] = transformingLevelValue;
6796 }
6797 transformingMatrixNode.levelValues = newlyOrderedLevelValues;
6798 // For consistency with how DataViewTreeNode.value works, and for a bit of backward compatibility,
6799 // copy the last value from DataViewMatrixNode.levelValues to DataViewMatrixNode.value.
6800 var newlyOrderedLastLevelValue = _.last(newlyOrderedLevelValues);
6801 if (transformingMatrixNode.value !== newlyOrderedLastLevelValue.value) {
6802 transformingMatrixNode.value = newlyOrderedLastLevelValue.value;
6803 }
6804 if ((transformingMatrixNode.levelSourceIndex || 0) !== newlyOrderedLastLevelValue.levelSourceIndex) {
6805 transformingMatrixNode.levelSourceIndex = newlyOrderedLastLevelValue.levelSourceIndex;
6806 }
6807 }
6808 });
6809 return transformingHierarchyRootNode;
6810 }
6811 /**
6812 * Creates a mapping of new position to original position.
6813 *
6814 * The return value is a mapping where each key-value pair represent the order mapping of a particular column:
6815 * - the key in the key-value pair is the index of the particular column in the new order (e.g. projection order)
6816 * - the value in the key-value pair is the index of the particular column in the original order
6817 */
6818 function createMatrixValuesPositionMapping(matrixValues, projectionOrdering, valueSources, columnRewrites) {
6819 var role = matrixValues.for.in;
6820 var newOrder = projectionOrdering[role];
6821 var originalOrder = _.chain(columnRewrites)
6822 .filter(function (rewrite) { return _.contains(valueSources, rewrite.to); })
6823 .map(function (rewrite) { return rewrite.from.index; })
6824 .value();
6825 return createOrderMapping(originalOrder, newOrder);
6826 }
6827 /**
6828 * Creates a mapping of indices, from indices to the specified newOrder array, back to indices to the specified
6829 * originalOrder array.
6830 * Each of the number value in originalOrder and newOrder is actually the unique key of a column (unqiue
6831 * under the context of the caller code), e.g. the Select Index in projection ordering array.
6832 * Also, the specified originalOrder must contain every value that exists in newOrder.
6833 *
6834 * If the specified originalOrder and newOrder are different in sequence order, then this function returns a collection of
6835 * key-value pair, each of which represents the new and old indices of a particular column:
6836 * - the key in each key-value pair is the index of the particular column key as it exists in the specified newOrder array
6837 * - the value in each key-value pair is the index of the particular column key as it exists in the specified originalOrder array
6838 *
6839 * For example on how the return value is consumed, see functions such as reorderMatrixHierarchyLevelColumnSources(...).
6840 *
6841 * If the specified originalOrder and newOrder are same, then this function returns undefined.
6842 *
6843 * @param originalOrder E.g. an array of metadata column "select indices", in the original order as they exist in Query DataView.
6844 * @param newOrder E.g. an array of metadata column "select indices", in rojection ordering.
6845 */
6846 function createOrderMapping(originalOrder, newOrder) {
6847 // Optimization: avoid rewriting if the current order is correct
6848 if (ArrayExtensions.sequenceEqual(originalOrder, newOrder, function (x, y) { return x === y; }))
6849 return;
6850 var mapping = {};
6851 for (var i = 0, len = newOrder.length; i < len; ++i) {
6852 var newPosition = newOrder[i];
6853 mapping[i] = originalOrder.indexOf(newPosition);
6854 }
6855 return mapping;
6856 }
6857 function createReversedMapping(mapping) {
6858 debug.assertValue(mapping, 'mapping');
6859 var reversed = {};
6860 for (var key in mapping) {
6861 // Note: key is a string after we get it out from mapping, thus we need to parse it
6862 // back into a number before putting it as the value in the reversed mapping
6863 var value = mapping[key];
6864 var keyAsNumber = parseInt(key, 10);
6865 reversed[value] = keyAsNumber;
6866 }
6867 debug.assertValue(Object.keys(mapping).length === Object.keys(reversed).length, 'pre-condition: The specified mapping must not contain any duplicate value because duplicate values are obmitted from the reversed mapping.');
6868 return reversed;
6869 }
6870 function forEachNodeAtLevel(node, targetLevel, callback) {
6871 debug.assertValue(node, 'node');
6872 debug.assert(targetLevel >= 0, 'argetLevel >= 0');
6873 debug.assertValue(callback, 'callback');
6874 if (node.level === targetLevel) {
6875 callback(node);
6876 return;
6877 }
6878 var children = node.children;
6879 if (children && children.length > 0) {
6880 for (var i = 0, ilen = children.length; i < ilen; i++)
6881 forEachNodeAtLevel(children[i], targetLevel, callback);
6882 }
6883 }
6884 DataViewTransform.forEachNodeAtLevel = forEachNodeAtLevel;
6885 function findOverride(source, columnRewrites) {
6886 for (var i = 0, len = columnRewrites.length; i < len; i++) {
6887 var columnRewrite = columnRewrites[i];
6888 if (columnRewrite.from === source)
6889 return columnRewrite.to;
6890 }
6891 }
6892 function ensureRewritten(rewritten, prototype, callback) {
6893 if (!rewritten)
6894 rewritten = inherit(prototype);
6895 if (callback)
6896 callback(rewritten);
6897 return rewritten;
6898 }
6899 function transformObjects(dataView, targetDataViewKinds, objectDescriptors, objectDefinitions, selectTransforms, colorAllocatorFactory) {
6900 debug.assertValue(dataView, 'dataView');
6901 debug.assertValue(targetDataViewKinds, 'targetDataViewKinds');
6902 debug.assertAnyValue(objectDescriptors, 'objectDescriptors');
6903 debug.assertAnyValue(objectDefinitions, 'objectDefinitions');
6904 debug.assertAnyValue(selectTransforms, 'selectTransforms');
6905 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
6906 if (!objectDescriptors)
6907 return;
6908 var objectsForAllSelectors = data.DataViewObjectEvaluationUtils.groupObjectsBySelector(objectDefinitions);
6909 data.DataViewObjectEvaluationUtils.addImplicitObjects(objectsForAllSelectors, objectDescriptors, dataView.metadata.columns, selectTransforms);
6910 var metadataOnce = objectsForAllSelectors.metadataOnce;
6911 var dataObjects = objectsForAllSelectors.data;
6912 if (metadataOnce)
6913 evaluateMetadataObjects(dataView, selectTransforms, objectDescriptors, metadataOnce.objects, dataObjects, colorAllocatorFactory);
6914 var metadataObjects = objectsForAllSelectors.metadata;
6915 if (metadataObjects) {
6916 for (var i = 0, len = metadataObjects.length; i < len; i++) {
6917 var metadataObject = metadataObjects[i];
6918 var objectDefns = metadataObject.objects;
6919 var colorAllocatorCache = populateColorAllocatorCache(dataView, selectTransforms, objectDefns, colorAllocatorFactory);
6920 evaluateMetadataRepetition(dataView, selectTransforms, objectDescriptors, metadataObject.selector, objectDefns, colorAllocatorCache);
6921 }
6922 }
6923 for (var i = 0, len = dataObjects.length; i < len; i++) {
6924 var dataObject = dataObjects[i];
6925 var objectDefns = dataObject.objects;
6926 var colorAllocatorCache = populateColorAllocatorCache(dataView, selectTransforms, objectDefns, colorAllocatorFactory);
6927 evaluateDataRepetition(dataView, targetDataViewKinds, selectTransforms, objectDescriptors, dataObject.selector, dataObject.rules, objectDefns, colorAllocatorCache);
6928 }
6929 var userDefined = objectsForAllSelectors.userDefined;
6930 if (userDefined) {
6931 // TODO: We only handle user defined objects at the metadata level, but should be able to support them with arbitrary repetition.
6932 evaluateUserDefinedObjects(dataView, selectTransforms, objectDescriptors, userDefined, colorAllocatorFactory);
6933 }
6934 }
6935 DataViewTransform.transformObjects = transformObjects;
6936 function evaluateUserDefinedObjects(dataView, selectTransforms, objectDescriptors, objectDefns, colorAllocatorFactory) {
6937 debug.assertValue(dataView, 'dataView');
6938 debug.assertAnyValue(selectTransforms, 'selectTransforms');
6939 debug.assertValue(objectDescriptors, 'objectDescriptors');
6940 debug.assertValue(objectDefns, 'objectDefns');
6941 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
6942 var dataViewObjects = dataView.metadata.objects;
6943 if (!dataViewObjects) {
6944 dataViewObjects = dataView.metadata.objects = {};
6945 }
6946 for (var _i = 0, objectDefns_1 = objectDefns; _i < objectDefns_1.length; _i++) {
6947 var objectDefn = objectDefns_1[_i];
6948 var id = objectDefn.selector.id;
6949 var colorAllocatorCache = populateColorAllocatorCache(dataView, selectTransforms, objectDefn.objects, colorAllocatorFactory);
6950 var evalContext = data.createStaticEvalContext(colorAllocatorCache, dataView, selectTransforms);
6951 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefn.objects);
6952 for (var objectName in objects) {
6953 var object = objects[objectName];
6954 var map = dataViewObjects[objectName];
6955 if (!map)
6956 map = dataViewObjects[objectName] = [];
6957 debug.assert(powerbi.DataViewObjects.isUserDefined(map), 'expected DataViewObjectMap');
6958 // NOTE: We do not check for duplicate ids.
6959 map.push({ id: id, object: object });
6960 }
6961 }
6962 }
6963 /** Evaluates and sets properties on the DataView metadata. */
6964 function evaluateMetadataObjects(dataView, selectTransforms, objectDescriptors, objectDefns, dataObjects, colorAllocatorFactory) {
6965 debug.assertValue(dataView, 'dataView');
6966 debug.assertAnyValue(selectTransforms, 'selectTransforms');
6967 debug.assertValue(objectDescriptors, 'objectDescriptors');
6968 debug.assertValue(objectDefns, 'objectDefns');
6969 debug.assertValue(dataObjects, 'dataObjects');
6970 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
6971 var colorAllocatorCache = populateColorAllocatorCache(dataView, selectTransforms, objectDefns, colorAllocatorFactory);
6972 var evalContext = data.createStaticEvalContext(colorAllocatorCache, dataView, selectTransforms);
6973 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns);
6974 if (objects) {
6975 dataView.metadata.objects = objects;
6976 for (var objectName in objects) {
6977 var object = objects[objectName], objectDesc = objectDescriptors[objectName];
6978 for (var propertyName in object) {
6979 var propertyDesc = objectDesc.properties[propertyName], ruleDesc = propertyDesc.rule;
6980 if (!ruleDesc)
6981 continue;
6982 var definition = createRuleEvaluationInstance(dataView, colorAllocatorFactory, ruleDesc, objectName, object[propertyName], propertyDesc.type);
6983 if (!definition)
6984 continue;
6985 dataObjects.push(definition);
6986 }
6987 }
6988 }
6989 }
6990 function createRuleEvaluationInstance(dataView, colorAllocatorFactory, ruleDesc, objectName, propertyValue, ruleType) {
6991 debug.assertValue(dataView, 'dataView');
6992 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
6993 debug.assertValue(ruleDesc, 'ruleDesc');
6994 debug.assertValue(propertyValue, 'propertyValue');
6995 debug.assertValue(ruleType, 'ruleType');
6996 var ruleOutput = ruleDesc.output;
6997 if (!ruleOutput)
6998 return;
6999 var selectorToCreate = findSelectorForRuleInput(dataView, ruleOutput.selector);
7000 if (!selectorToCreate)
7001 return;
7002 if (ruleType.fillRule) {
7003 return createRuleEvaluationInstanceFillRule(dataView, colorAllocatorFactory, ruleDesc, selectorToCreate, objectName, propertyValue);
7004 }
7005 }
7006 function createRuleEvaluationInstanceFillRule(dataView, colorAllocatorFactory, ruleDesc, selectorToCreate, objectName, propertyValue) {
7007 debug.assertValue(dataView, 'dataView');
7008 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
7009 debug.assertValue(ruleDesc, 'ruleDesc');
7010 debug.assertValue(selectorToCreate, 'selectorToCreate');
7011 debug.assertValue(propertyValue, 'propertyValue');
7012 var colorAllocator = tryCreateColorAllocatorForFillRule(dataView, colorAllocatorFactory, ruleDesc.inputRole, 1 /* Role */, propertyValue);
7013 if (!colorAllocator)
7014 return;
7015 var rule = new data.ColorRuleEvaluation(ruleDesc.inputRole, colorAllocator);
7016 var fillRuleProperties = {};
7017 fillRuleProperties[ruleDesc.output.property] = {
7018 solid: { color: rule }
7019 };
7020 return {
7021 selector: selectorToCreate,
7022 rules: [rule],
7023 objects: [{
7024 name: objectName,
7025 properties: fillRuleProperties,
7026 }]
7027 };
7028 }
7029 function tryCreateColorAllocatorForFillRule(dataView, colorAllocatorFactory, identifier, identifierKind, propertyValue) {
7030 debug.assertValue(dataView, 'dataView');
7031 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
7032 debug.assertValue(identifier, 'identifier');
7033 debug.assertValue(identifierKind, 'identifierKind');
7034 debug.assertValue(propertyValue, 'propertyValue');
7035 if (propertyValue.linearGradient2)
7036 return createColorAllocatorLinearGradient2(dataView, colorAllocatorFactory, identifier, identifierKind, propertyValue, propertyValue.linearGradient2);
7037 if (propertyValue.linearGradient3)
7038 return createColorAllocatorLinearGradient3(dataView, colorAllocatorFactory, identifier, identifierKind, propertyValue, propertyValue.linearGradient3);
7039 }
7040 function createColorAllocatorLinearGradient2(dataView, colorAllocatorFactory, identifier, identifierKind, propertyValueFillRule, linearGradient2) {
7041 debug.assertValue(dataView, 'dataView');
7042 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
7043 debug.assertValue(identifier, 'identifier');
7044 debug.assertValue(identifierKind, 'identifierKind');
7045 debug.assertValue(linearGradient2, 'linearGradient2');
7046 linearGradient2 = propertyValueFillRule.linearGradient2;
7047 if (linearGradient2.min.value === undefined ||
7048 linearGradient2.max.value === undefined) {
7049 var inputRange = findRuleInputColumnNumberRange(dataView, identifier, identifierKind);
7050 if (!inputRange)
7051 return;
7052 if (linearGradient2.min.value === undefined)
7053 linearGradient2.min.value = inputRange.min;
7054 if (linearGradient2.max.value === undefined)
7055 linearGradient2.max.value = inputRange.max;
7056 }
7057 return colorAllocatorFactory.linearGradient2(propertyValueFillRule.linearGradient2);
7058 }
7059 function createColorAllocatorLinearGradient3(dataView, colorAllocatorFactory, identifier, identifierKind, propertyValueFillRule, linearGradient3) {
7060 debug.assertValue(dataView, 'dataView');
7061 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
7062 debug.assertValue(identifier, 'identifier');
7063 debug.assertValue(identifierKind, 'identifierKind');
7064 debug.assertValue(linearGradient3, 'linearGradient3');
7065 var splitScales;
7066 linearGradient3 = propertyValueFillRule.linearGradient3;
7067 if (linearGradient3.min.value === undefined ||
7068 linearGradient3.mid.value === undefined ||
7069 linearGradient3.max.value === undefined) {
7070 var inputRange = findRuleInputColumnNumberRange(dataView, identifier, identifierKind);
7071 if (!inputRange)
7072 return;
7073 splitScales =
7074 linearGradient3.min.value === undefined &&
7075 linearGradient3.max.value === undefined &&
7076 linearGradient3.mid.value !== undefined;
7077 if (linearGradient3.min.value === undefined) {
7078 linearGradient3.min.value = inputRange.min;
7079 }
7080 if (linearGradient3.max.value === undefined) {
7081 linearGradient3.max.value = inputRange.max;
7082 }
7083 if (linearGradient3.mid.value === undefined) {
7084 var midValue = (linearGradient3.max.value + linearGradient3.min.value) / 2;
7085 linearGradient3.mid.value = midValue;
7086 }
7087 }
7088 return colorAllocatorFactory.linearGradient3(propertyValueFillRule.linearGradient3, splitScales);
7089 }
7090 function populateColorAllocatorCache(dataView, selectTransforms, objectDefns, colorAllocatorFactory) {
7091 debug.assertValue(dataView, 'dataView');
7092 debug.assertAnyValue(selectTransforms, 'selectTransforms');
7093 debug.assertValue(objectDefns, 'objectDefns');
7094 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
7095 var cache = data.createColorAllocatorCache();
7096 var staticEvalContext = data.createStaticEvalContext();
7097 for (var i = 0, len = objectDefns.length; i < len; i++) {
7098 var objectDefnProperties = objectDefns[i].properties;
7099 for (var propertyName in objectDefnProperties) {
7100 var fillProperty = objectDefnProperties[propertyName];
7101 if (fillProperty &&
7102 fillProperty.solid &&
7103 fillProperty.solid.color &&
7104 fillProperty.solid.color.kind === 23 /* FillRule */) {
7105 var fillRuleExpr = fillProperty.solid.color;
7106 var inputExprQueryName = findFirstQueryNameForExpr(selectTransforms, fillRuleExpr.input);
7107 if (!inputExprQueryName)
7108 continue;
7109 var fillRule = data.DataViewObjectEvaluator.evaluateProperty(staticEvalContext, fillRulePropertyDescriptor, fillRuleExpr.rule);
7110 var colorAllocator = tryCreateColorAllocatorForFillRule(dataView, colorAllocatorFactory, inputExprQueryName, 0 /* QueryName */, fillRule);
7111 if (colorAllocator)
7112 cache.register(fillRuleExpr, colorAllocator);
7113 }
7114 }
7115 }
7116 return cache;
7117 }
7118 function evaluateDataRepetition(dataView, targetDataViewKinds, selectTransforms, objectDescriptors, selector, rules, objectDefns, colorAllocatorCache) {
7119 debug.assertValue(dataView, 'dataView');
7120 debug.assertValue(targetDataViewKinds, 'targetDataViewKinds');
7121 debug.assertAnyValue(selectTransforms, 'selectTransforms');
7122 debug.assertValue(objectDescriptors, 'objectDescriptors');
7123 debug.assertValue(selector, 'selector');
7124 debug.assertAnyValue(rules, 'rules');
7125 debug.assertValue(objectDefns, 'objectDefns');
7126 debug.assertValue(colorAllocatorCache, 'colorAllocatorFactory');
7127 var containsWildcard = data.Selector.containsWildcard(selector);
7128 var dataViewCategorical = dataView.categorical;
7129 if (dataViewCategorical && EnumExtensions.hasFlag(targetDataViewKinds, 1 /* Categorical */)) {
7130 // 1) Match against categories
7131 evaluateDataRepetitionCategoricalCategory(dataViewCategorical, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache);
7132 // 2) Match against valueGrouping
7133 evaluateDataRepetitionCategoricalValueGrouping(dataViewCategorical, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache);
7134 }
7135 var dataViewMatrix = dataView.matrix;
7136 if (dataViewMatrix && EnumExtensions.hasFlag(targetDataViewKinds, 2 /* Matrix */)) {
7137 var rewrittenMatrix = evaluateDataRepetitionMatrix(dataViewMatrix, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache);
7138 if (rewrittenMatrix) {
7139 // TODO: This mutates the DataView -- the assumption is that prototypal inheritance has already occurred. We should
7140 // revisit this, likely when we do lazy evaluation of DataView.
7141 dataView.matrix = rewrittenMatrix;
7142 }
7143 }
7144 var dataViewTable = dataView.table;
7145 if (dataViewTable && EnumExtensions.hasFlag(targetDataViewKinds, 8 /* Table */)) {
7146 var rewrittenSelector = rewriteTableRoleSelector(dataViewTable, selector);
7147 var rewrittenTable = evaluateDataRepetitionTable(dataViewTable, selectTransforms, objectDescriptors, rewrittenSelector, rules, containsWildcard, objectDefns, colorAllocatorCache);
7148 if (rewrittenTable) {
7149 // TODO: This mutates the DataView -- the assumption is that prototypal inheritance has already occurred. We should
7150 // revisit this, likely when we do lazy evaluation of DataView.
7151 dataView.table = rewrittenTable;
7152 }
7153 }
7154 }
7155 function rewriteTableRoleSelector(dataViewTable, selector) {
7156 if (data.Selector.hasRoleWildcard(selector)) {
7157 selector = findSelectorForRoleWildcard(dataViewTable, selector);
7158 }
7159 return selector;
7160 }
7161 function findSelectorForRoleWildcard(dataViewTable, selector) {
7162 var resultingSelector = {
7163 data: [],
7164 id: selector.id,
7165 metadata: selector.metadata
7166 };
7167 for (var _i = 0, _a = selector.data; _i < _a.length; _i++) {
7168 var dataSelector = _a[_i];
7169 if (data.Selector.isRoleWildcard(dataSelector)) {
7170 var selectorRoles = dataSelector.roles;
7171 var allColumnsBelongToSelectorRole = allColumnsBelongToRole(dataViewTable.columns, selectorRoles);
7172 var exprs = dataViewTable.identityFields;
7173 if (allColumnsBelongToSelectorRole && exprs) {
7174 resultingSelector.data.push(data.DataViewScopeWildcard.fromExprs(exprs));
7175 continue;
7176 }
7177 }
7178 if (isUniqueDataSelector(resultingSelector.data, dataSelector)) {
7179 resultingSelector.data.push(dataSelector);
7180 }
7181 }
7182 return resultingSelector;
7183 }
7184 function isUniqueDataSelector(dataSelectors, newSelector) {
7185 if (_.isEmpty(dataSelectors))
7186 return true;
7187 return !_.any(dataSelectors, function (dataSelector) { return dataSelector.key === newSelector.key; });
7188 }
7189 function allColumnsBelongToRole(columns, selectorRoles) {
7190 for (var _i = 0, columns_6 = columns; _i < columns_6.length; _i++) {
7191 var column = columns_6[_i];
7192 var roles = column.roles;
7193 if (!roles || !_.any(selectorRoles, function (selectorRole) { return roles[selectorRole]; }))
7194 return false;
7195 }
7196 return true;
7197 }
7198 function evaluateDataRepetitionCategoricalCategory(dataViewCategorical, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache) {
7199 debug.assertValue(dataViewCategorical, 'dataViewCategorical');
7200 debug.assertValue(objectDescriptors, 'objectDescriptors');
7201 debug.assertValue(selector, 'selector');
7202 debug.assertAnyValue(rules, 'rules');
7203 debug.assertValue(containsWildcard, 'containsWildcard');
7204 debug.assertValue(objectDefns, 'objectDefns');
7205 debug.assertValue(colorAllocatorCache, 'colorAllocatorCache');
7206 if (!dataViewCategorical.categories || dataViewCategorical.categories.length === 0)
7207 return;
7208 var targetColumn = findSelectedCategoricalColumn(dataViewCategorical, selector);
7209 if (!targetColumn)
7210 return;
7211 var identities = targetColumn.identities, foundMatch, evalContext = data.createCategoricalEvalContext(colorAllocatorCache, dataViewCategorical);
7212 if (!identities)
7213 return;
7214 debug.assert(targetColumn.column.values.length === identities.length, 'Column length mismatch');
7215 for (var i = 0, len = identities.length; i < len; i++) {
7216 var identity = identities[i];
7217 if (containsWildcard || data.Selector.matchesData(selector, [identity])) {
7218 evalContext.setCurrentRowIndex(i);
7219 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns);
7220 if (objects) {
7221 // TODO: This mutates the DataView -- the assumption is that prototypal inheritance has already occurred. We should
7222 // revisit this, likely when we do lazy evaluation of DataView.
7223 if (!targetColumn.column.objects) {
7224 targetColumn.column.objects = [];
7225 targetColumn.column.objects.length = len;
7226 }
7227 targetColumn.column.objects[i] = objects;
7228 }
7229 if (!containsWildcard)
7230 return true;
7231 foundMatch = true;
7232 }
7233 }
7234 return foundMatch;
7235 }
7236 function evaluateDataRepetitionCategoricalValueGrouping(dataViewCategorical, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache) {
7237 debug.assertValue(dataViewCategorical, 'dataViewCategorical');
7238 debug.assertValue(objectDescriptors, 'objectDescriptors');
7239 debug.assertValue(selector, 'selector');
7240 debug.assertAnyValue(rules, 'rules');
7241 debug.assertValue(containsWildcard, 'containsWildcard');
7242 debug.assertValue(objectDefns, 'objectDefns');
7243 debug.assertValue(colorAllocatorCache, 'colorAllocatorCache');
7244 var dataViewCategoricalValues = dataViewCategorical.values;
7245 if (!dataViewCategoricalValues || !dataViewCategoricalValues.identityFields)
7246 return;
7247 if (!data.Selector.matchesKeys(selector, [dataViewCategoricalValues.identityFields]))
7248 return;
7249 var valuesGrouped = dataViewCategoricalValues.grouped();
7250 if (!valuesGrouped)
7251 return;
7252 // NOTE: We do not set the evalContext row index below because iteration is over value groups (i.e., columns, no rows).
7253 // This should be enhanced in the future.
7254 var evalContext = data.createCategoricalEvalContext(colorAllocatorCache, dataViewCategorical);
7255 var foundMatch;
7256 for (var i = 0, len = valuesGrouped.length; i < len; i++) {
7257 var valueGroup = valuesGrouped[i];
7258 var selectorMetadata = selector.metadata;
7259 var valuesInGroup = valueGroup.values;
7260 if (containsWildcard || data.Selector.matchesData(selector, [valueGroup.identity])) {
7261 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns);
7262 if (objects) {
7263 // TODO: This mutates the DataView -- the assumption is that prototypal inheritance has already occurred. We should
7264 // revisit this, likely when we do lazy evaluation of DataView.
7265 if (selectorMetadata) {
7266 for (var j = 0, jlen = valuesInGroup.length; j < jlen; j++) {
7267 var valueColumn = valuesInGroup[j], valueSource = valueColumn.source;
7268 if (valueSource.queryName === selectorMetadata) {
7269 var valueSourceOverwrite = powerbi.Prototype.inherit(valueSource);
7270 valueSourceOverwrite.objects = objects;
7271 valueColumn.source = valueSourceOverwrite;
7272 foundMatch = true;
7273 break;
7274 }
7275 }
7276 }
7277 else {
7278 valueGroup.objects = objects;
7279 setGrouped(dataViewCategoricalValues, valuesGrouped);
7280 foundMatch = true;
7281 }
7282 }
7283 if (!containsWildcard)
7284 return true;
7285 }
7286 }
7287 return foundMatch;
7288 }
7289 function evaluateDataRepetitionMatrix(dataViewMatrix, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache) {
7290 var evalContext = data.createMatrixEvalContext(colorAllocatorCache, dataViewMatrix);
7291 var rewrittenRows = evaluateDataRepetitionMatrixHierarchy(evalContext, dataViewMatrix.rows, objectDescriptors, selector, rules, containsWildcard, objectDefns);
7292 var rewrittenCols = evaluateDataRepetitionMatrixHierarchy(evalContext, dataViewMatrix.columns, objectDescriptors, selector, rules, containsWildcard, objectDefns);
7293 if (rewrittenRows || rewrittenCols) {
7294 var rewrittenMatrix = inheritSingle(dataViewMatrix);
7295 if (rewrittenRows)
7296 rewrittenMatrix.rows = rewrittenRows;
7297 if (rewrittenCols)
7298 rewrittenMatrix.columns = rewrittenCols;
7299 return rewrittenMatrix;
7300 }
7301 }
7302 function evaluateDataRepetitionMatrixHierarchy(evalContext, dataViewMatrixHierarchy, objectDescriptors, selector, rules, containsWildcard, objectDefns) {
7303 debug.assertAnyValue(dataViewMatrixHierarchy, 'dataViewMatrixHierarchy');
7304 debug.assertValue(objectDescriptors, 'objectDescriptors');
7305 debug.assertValue(selector, 'selector');
7306 debug.assertAnyValue(rules, 'rules');
7307 debug.assertValue(objectDefns, 'objectDefns');
7308 if (!dataViewMatrixHierarchy)
7309 return;
7310 var root = dataViewMatrixHierarchy.root;
7311 if (!root)
7312 return;
7313 var rewrittenRoot = evaluateDataRepetitionMatrixNode(evalContext, root, objectDescriptors, selector, rules, containsWildcard, objectDefns);
7314 if (rewrittenRoot) {
7315 var rewrittenHierarchy = inheritSingle(dataViewMatrixHierarchy);
7316 rewrittenHierarchy.root = rewrittenRoot;
7317 return rewrittenHierarchy;
7318 }
7319 }
7320 function evaluateDataRepetitionMatrixNode(evalContext, dataViewNode, objectDescriptors, selector, rules, containsWildcard, objectDefns) {
7321 debug.assertValue(evalContext, 'evalContext');
7322 debug.assertValue(dataViewNode, 'dataViewNode');
7323 debug.assertValue(objectDescriptors, 'objectDescriptors');
7324 debug.assertValue(selector, 'selector');
7325 debug.assertAnyValue(rules, 'rules');
7326 debug.assertValue(objectDefns, 'objectDefns');
7327 var childNodes = dataViewNode.children;
7328 if (!childNodes)
7329 return;
7330 var rewrittenNode;
7331 var shouldSearchChildren;
7332 var childIdentityFields = dataViewNode.childIdentityFields;
7333 if (childIdentityFields) {
7334 // NOTE: selector matching in matrix currently only considers the current node, and does not consider parents as part of the match.
7335 shouldSearchChildren = data.Selector.matchesKeys(selector, [childIdentityFields]);
7336 }
7337 for (var i = 0, len = childNodes.length; i < len; i++) {
7338 var childNode = childNodes[i], identity = childNode.identity, rewrittenChildNode = null;
7339 if (shouldSearchChildren) {
7340 if (containsWildcard || data.Selector.matchesData(selector, [identity])) {
7341 // TODO: Need to initialize context for rule-based properties. Rule-based properties
7342 // (such as fillRule/gradients) are not currently implemented.
7343 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns);
7344 if (objects) {
7345 rewrittenChildNode = inheritSingle(childNode);
7346 rewrittenChildNode.objects = objects;
7347 }
7348 }
7349 }
7350 else {
7351 rewrittenChildNode = evaluateDataRepetitionMatrixNode(evalContext, childNode, objectDescriptors, selector, rules, containsWildcard, objectDefns);
7352 }
7353 if (rewrittenChildNode) {
7354 if (!rewrittenNode)
7355 rewrittenNode = inheritNodeAndChildren(dataViewNode);
7356 rewrittenNode.children[i] = rewrittenChildNode;
7357 if (!containsWildcard) {
7358 // NOTE: once we find a match for a non-wildcard selector, stop looking.
7359 break;
7360 }
7361 }
7362 }
7363 return rewrittenNode;
7364 }
7365 function inheritNodeAndChildren(node) {
7366 if (Object.getPrototypeOf(node) !== Object.prototype) {
7367 return node;
7368 }
7369 var inherited = inheritSingle(node);
7370 inherited.children = inherit(node.children);
7371 return inherited;
7372 }
7373 function evaluateDataRepetitionTable(dataViewTable, selectTransforms, objectDescriptors, selector, rules, containsWildcard, objectDefns, colorAllocatorCache) {
7374 debug.assertValue(dataViewTable, 'dataViewTable');
7375 debug.assertAnyValue(selectTransforms, 'selectTransforms');
7376 debug.assertValue(objectDescriptors, 'objectDescriptors');
7377 debug.assertValue(selector, 'selector');
7378 debug.assertAnyValue(rules, 'rules');
7379 debug.assertValue(objectDefns, 'objectDefns');
7380 debug.assertValue(colorAllocatorCache, 'colorAllocatorCache');
7381 var evalContext = data.createTableEvalContext(colorAllocatorCache, dataViewTable, selectTransforms);
7382 var rewrittenRows = evaluateDataRepetitionTableRows(evalContext, dataViewTable.columns, dataViewTable.rows, dataViewTable.identity, dataViewTable.identityFields, objectDescriptors, selector, rules, containsWildcard, objectDefns);
7383 if (rewrittenRows) {
7384 var rewrittenTable = inheritSingle(dataViewTable);
7385 rewrittenTable.rows = rewrittenRows;
7386 return rewrittenTable;
7387 }
7388 }
7389 function evaluateDataRepetitionTableRows(evalContext, columns, rows, identities, identityFields, objectDescriptors, selector, rules, containsWildcard, objectDefns) {
7390 debug.assertValue(evalContext, 'evalContext');
7391 debug.assertValue(columns, 'columns');
7392 debug.assertValue(rows, 'rows');
7393 debug.assertAnyValue(identities, 'identities');
7394 debug.assertAnyValue(identityFields, 'identityFields');
7395 debug.assertValue(objectDescriptors, 'objectDescriptors');
7396 debug.assertValue(selector, 'selector');
7397 debug.assertAnyValue(rules, 'rules');
7398 debug.assertValue(objectDefns, 'objectDefns');
7399 if (_.isEmpty(identities) || _.isEmpty(identityFields))
7400 return;
7401 if (!selector.metadata ||
7402 !data.Selector.matchesKeys(selector, [identityFields]))
7403 return;
7404 var colIdx = _.findIndex(columns, function (col) { return col.queryName === selector.metadata; });
7405 if (colIdx < 0)
7406 return;
7407 debug.assert(rows.length === identities.length, 'row length mismatch');
7408 var colLen = columns.length;
7409 var inheritedRows;
7410 for (var rowIdx = 0, rowLen = identities.length; rowIdx < rowLen; rowIdx++) {
7411 var identity = identities[rowIdx];
7412 if (containsWildcard || data.Selector.matchesData(selector, [identity])) {
7413 evalContext.setCurrentRowIndex(rowIdx);
7414 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns);
7415 if (objects) {
7416 if (!inheritedRows)
7417 inheritedRows = inheritSingle(rows);
7418 var inheritedRow = inheritedRows[rowIdx] = inheritSingle(inheritedRows[rowIdx]);
7419 var objectsForColumns = inheritedRow.objects;
7420 if (!objectsForColumns)
7421 inheritedRow.objects = objectsForColumns = new Array(colLen);
7422 objectsForColumns[colIdx] = objects;
7423 }
7424 if (!containsWildcard)
7425 break;
7426 }
7427 }
7428 return inheritedRows;
7429 }
7430 function evaluateMetadataRepetition(dataView, selectTransforms, objectDescriptors, selector, objectDefns, colorAllocatorCache) {
7431 debug.assertValue(dataView, 'dataView');
7432 debug.assertAnyValue(selectTransforms, 'selectTransforms');
7433 debug.assertValue(objectDescriptors, 'objectDescriptors');
7434 debug.assertValue(selector, 'selector');
7435 debug.assertValue(objectDefns, 'objectDefns');
7436 debug.assertValue(colorAllocatorCache, 'colorAllocatorCache');
7437 // TODO: This mutates the DataView -- the assumption is that prototypal inheritance has already occurred. We should
7438 // revisit this, likely when we do lazy evaluation of DataView.
7439 var columns = dataView.metadata.columns, metadataId = selector.metadata, evalContext = data.createStaticEvalContext(colorAllocatorCache, dataView, selectTransforms);
7440 for (var i = 0, len = columns.length; i < len; i++) {
7441 var column = columns[i];
7442 if (column.queryName === metadataId) {
7443 var objects = data.DataViewObjectEvaluationUtils.evaluateDataViewObjects(evalContext, objectDescriptors, objectDefns);
7444 if (objects)
7445 column.objects = objects;
7446 }
7447 }
7448 }
7449 /** Attempts to find a column that can possibly match the selector. */
7450 function findSelectedCategoricalColumn(dataViewCategorical, selector) {
7451 debug.assertValue(dataViewCategorical.categories[0], 'dataViewCategorical.categories[0]');
7452 var categoricalColumn = dataViewCategorical.categories[0];
7453 if (!categoricalColumn.identityFields)
7454 return;
7455 if (!data.Selector.matchesKeys(selector, [categoricalColumn.identityFields]))
7456 return;
7457 var identities = categoricalColumn.identity, targetColumn = categoricalColumn;
7458 var selectedMetadataId = selector.metadata;
7459 if (selectedMetadataId) {
7460 var valueColumns = dataViewCategorical.values;
7461 if (valueColumns) {
7462 for (var i = 0, len = valueColumns.length; i < len; i++) {
7463 var valueColumn = valueColumns[i];
7464 if (valueColumn.source.queryName === selectedMetadataId) {
7465 targetColumn = valueColumn;
7466 break;
7467 }
7468 }
7469 }
7470 }
7471 return {
7472 column: targetColumn,
7473 identities: identities,
7474 };
7475 }
7476 function findSelectorForRuleInput(dataView, selectorRoles) {
7477 debug.assertValue(dataView, 'dataView');
7478 debug.assertValue(selectorRoles, 'selectorRoles');
7479 if (selectorRoles.length !== 1)
7480 return;
7481 var dataViewCategorical = dataView.categorical;
7482 if (!dataViewCategorical)
7483 return;
7484 var categories = dataViewCategorical.categories;
7485 if (!categories || categories.length !== 1)
7486 return;
7487 var categoryColumn = categories[0], categoryRoles = categoryColumn.source.roles, categoryIdentityFields = categoryColumn.identityFields;
7488 if (!categoryRoles || !categoryIdentityFields || !categoryRoles[selectorRoles[0]])
7489 return;
7490 return { data: [data.DataViewScopeWildcard.fromExprs(categoryIdentityFields)] };
7491 }
7492 function findFirstQueryNameForExpr(selectTransforms, expr) {
7493 debug.assertAnyValue(selectTransforms, 'selectTransforms');
7494 debug.assertValue(expr, 'expr');
7495 if (data.SQExpr.isSelectRef(expr))
7496 return expr.expressionName;
7497 if (!selectTransforms)
7498 return;
7499 for (var i = 0, len = selectTransforms.length; i < len; i++) {
7500 var select = selectTransforms[i], columnExpr = select.expr;
7501 if (!columnExpr || !data.SQExpr.equals(expr, select.expr))
7502 continue;
7503 return select.queryName;
7504 }
7505 }
7506 /** Attempts to find the value range for the single column with the given identifier/identifierKind. */
7507 function findRuleInputColumnNumberRange(dataView, identifier, identifierKind) {
7508 debug.assertValue(dataView, 'dataView');
7509 debug.assertValue(identifier, 'identifier');
7510 debug.assertValue(identifierKind, 'identifierKind');
7511 var columns = dataView.metadata.columns;
7512 for (var i = 0, len = columns.length; i < len; i++) {
7513 var column = columns[i];
7514 if (identifierKind === 1 /* Role */) {
7515 var valueColRoles = column.roles;
7516 if (!valueColRoles || !valueColRoles[identifier])
7517 continue;
7518 }
7519 else {
7520 debug.assert(identifierKind === 0 /* QueryName */, 'identifierKind === ColumnIdentifierKind.QueryName');
7521 if (column.queryName !== identifier)
7522 continue;
7523 }
7524 var aggregates = column.aggregates;
7525 if (!aggregates)
7526 continue;
7527 var min = aggregates.min;
7528 if (min === undefined)
7529 min = aggregates.minLocal;
7530 if (min === undefined)
7531 continue;
7532 var max = aggregates.max;
7533 if (max === undefined)
7534 max = aggregates.maxLocal;
7535 if (max === undefined)
7536 continue;
7537 return { min: min, max: max };
7538 }
7539 }
7540 // TODO: refactor this, setGrouped, and groupValues to a test helper to stop using it in the product
7541 function createValueColumns(values, valueIdentityFields, source) {
7542 if (values === void 0) { values = []; }
7543 var result = values;
7544 setGrouped(values);
7545 if (valueIdentityFields)
7546 result.identityFields = valueIdentityFields;
7547 if (source)
7548 result.source = source;
7549 return result;
7550 }
7551 DataViewTransform.createValueColumns = createValueColumns;
7552 function setGrouped(values, groupedResult) {
7553 values.grouped = groupedResult
7554 ? function () { return groupedResult; }
7555 : function () { return groupValues(values); };
7556 }
7557 DataViewTransform.setGrouped = setGrouped;
7558 /** Group together the values with a common identity. */
7559 function groupValues(values) {
7560 debug.assertValue(values, 'values');
7561 var groups = [], currentGroup;
7562 for (var i = 0, len = values.length; i < len; i++) {
7563 var value = values[i];
7564 if (!currentGroup || currentGroup.identity !== value.identity) {
7565 currentGroup = {
7566 values: []
7567 };
7568 if (value.identity) {
7569 currentGroup.identity = value.identity;
7570 var source = value.source;
7571 // allow null, which will be formatted as (Blank).
7572 if (source.groupName !== undefined)
7573 currentGroup.name = source.groupName;
7574 else if (source.displayName)
7575 currentGroup.name = source.displayName;
7576 }
7577 groups.push(currentGroup);
7578 }
7579 currentGroup.values.push(value);
7580 }
7581 return groups;
7582 }
7583 function pivotIfNecessary(dataView, dataViewMappings) {
7584 debug.assertValue(dataView, 'dataView');
7585 var transformedDataView;
7586 switch (determineCategoricalTransformation(dataView.categorical, dataViewMappings)) {
7587 case 1 /* Pivot */:
7588 transformedDataView = data.DataViewPivotCategorical.apply(dataView);
7589 break;
7590 case 2 /* SelfCrossJoin */:
7591 transformedDataView = data.DataViewSelfCrossJoin.apply(dataView);
7592 break;
7593 }
7594 return transformedDataView || dataView;
7595 }
7596 function determineCategoricalTransformation(categorical, dataViewMappings) {
7597 if (!categorical || _.isEmpty(dataViewMappings))
7598 return;
7599 var categories = categorical.categories;
7600 if (!categories || categories.length !== 1)
7601 return;
7602 var values = categorical.values;
7603 if (_.isEmpty(values))
7604 return;
7605 if (values.grouped().some(function (vg) { return !!vg.identity; }))
7606 return;
7607 // If we made it here, the DataView has a single category and no valueGrouping.
7608 var categoryRoles = categories[0].source.roles;
7609 for (var i = 0, len = dataViewMappings.length; i < len; i++) {
7610 var roleMappingCategorical = dataViewMappings[i].categorical;
7611 if (!roleMappingCategorical)
7612 continue;
7613 if (!hasRolesGrouped(categoryRoles, roleMappingCategorical.values))
7614 continue;
7615 // If we made it here, the DataView's single category has the value grouping role.
7616 var categoriesMapping = roleMappingCategorical.categories;
7617 var hasCategoryRole = hasRolesBind(categoryRoles, categoriesMapping) ||
7618 hasRolesFor(categoryRoles, categoriesMapping);
7619 if (hasCategoryRole)
7620 return 2 /* SelfCrossJoin */;
7621 return 1 /* Pivot */;
7622 }
7623 }
7624 function shouldPivotMatrix(matrix, dataViewMappings) {
7625 if (!matrix || _.isEmpty(dataViewMappings))
7626 return;
7627 var rowLevels = matrix.rows.levels;
7628 if (rowLevels.length < 1)
7629 return;
7630 var rows = matrix.rows.root.children;
7631 if (!rows || rows.length === 0)
7632 return;
7633 var rowRoles = rowLevels[0].sources[0].roles;
7634 for (var i = 0, len = dataViewMappings.length; i < len; i++) {
7635 var roleMappingMatrix = dataViewMappings[i].matrix;
7636 if (!roleMappingMatrix)
7637 continue;
7638 if (!hasRolesFor(rowRoles, roleMappingMatrix.rows) &&
7639 hasRolesFor(rowRoles, roleMappingMatrix.columns)) {
7640 return true;
7641 }
7642 }
7643 }
7644 function hasRolesBind(roles, roleMapping) {
7645 if (roles && roleMapping && roleMapping.bind)
7646 return roles[roleMapping.bind.to];
7647 }
7648 function hasRolesFor(roles, roleMapping) {
7649 if (roles && roleMapping && roleMapping.for)
7650 return roles[roleMapping.for.in];
7651 }
7652 function hasRolesGrouped(roles, roleMapping) {
7653 if (roles && roleMapping && roleMapping.group)
7654 return roles[roleMapping.group.by];
7655 }
7656 })(DataViewTransform = data.DataViewTransform || (data.DataViewTransform = {}));
7657 })(data = powerbi.data || (powerbi.data = {}));
7658})(powerbi || (powerbi = {}));
7659/*
7660 * Power BI Visualizations
7661 *
7662 * Copyright (c) Microsoft Corporation
7663 * All rights reserved.
7664 * MIT License
7665 *
7666 * Permission is hereby granted, free of charge, to any person obtaining a copy
7667 * of this software and associated documentation files (the ""Software""), to deal
7668 * in the Software without restriction, including without limitation the rights
7669 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7670 * copies of the Software, and to permit persons to whom the Software is
7671 * furnished to do so, subject to the following conditions:
7672 *
7673 * The above copyright notice and this permission notice shall be included in
7674 * all copies or substantial portions of the Software.
7675 *
7676 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7677 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7678 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7679 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7680 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7681 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7682 * THE SOFTWARE.
7683 */
7684var powerbi;
7685(function (powerbi) {
7686 var data;
7687 (function (data) {
7688 function createDisplayNameGetter(displayNameKey) {
7689 return function (resourceProvider) { return resourceProvider.get(displayNameKey); };
7690 }
7691 data.createDisplayNameGetter = createDisplayNameGetter;
7692 function getDisplayName(displayNameGetter, resourceProvider) {
7693 if (typeof displayNameGetter === 'function')
7694 return displayNameGetter(resourceProvider);
7695 if (typeof displayNameGetter === 'string')
7696 return displayNameGetter;
7697 }
7698 data.getDisplayName = getDisplayName;
7699 })(data = powerbi.data || (powerbi.data = {}));
7700})(powerbi || (powerbi = {}));
7701/*
7702 * Power BI Visualizations
7703 *
7704 * Copyright (c) Microsoft Corporation
7705 * All rights reserved.
7706 * MIT License
7707 *
7708 * Permission is hereby granted, free of charge, to any person obtaining a copy
7709 * of this software and associated documentation files (the ""Software""), to deal
7710 * in the Software without restriction, including without limitation the rights
7711 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7712 * copies of the Software, and to permit persons to whom the Software is
7713 * furnished to do so, subject to the following conditions:
7714 *
7715 * The above copyright notice and this permission notice shall be included in
7716 * all copies or substantial portions of the Software.
7717 *
7718 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7719 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7720 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7721 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7722 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7723 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7724 * THE SOFTWARE.
7725 */
7726/*
7727 * Power BI Visualizations
7728 *
7729 * Copyright (c) Microsoft Corporation
7730 * All rights reserved.
7731 * MIT License
7732 *
7733 * Permission is hereby granted, free of charge, to any person obtaining a copy
7734 * of this software and associated documentation files (the ""Software""), to deal
7735 * in the Software without restriction, including without limitation the rights
7736 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7737 * copies of the Software, and to permit persons to whom the Software is
7738 * furnished to do so, subject to the following conditions:
7739 *
7740 * The above copyright notice and this permission notice shall be included in
7741 * all copies or substantial portions of the Software.
7742 *
7743 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7744 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7745 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7746 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7747 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7748 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7749 * THE SOFTWARE.
7750 */
7751var powerbi;
7752(function (powerbi) {
7753 /** Enumeration of DateTimeUnits */
7754 (function (DateTimeUnit) {
7755 DateTimeUnit[DateTimeUnit["Year"] = 0] = "Year";
7756 DateTimeUnit[DateTimeUnit["Month"] = 1] = "Month";
7757 DateTimeUnit[DateTimeUnit["Week"] = 2] = "Week";
7758 DateTimeUnit[DateTimeUnit["Day"] = 3] = "Day";
7759 DateTimeUnit[DateTimeUnit["Hour"] = 4] = "Hour";
7760 DateTimeUnit[DateTimeUnit["Minute"] = 5] = "Minute";
7761 DateTimeUnit[DateTimeUnit["Second"] = 6] = "Second";
7762 DateTimeUnit[DateTimeUnit["Millisecond"] = 7] = "Millisecond";
7763 })(powerbi.DateTimeUnit || (powerbi.DateTimeUnit = {}));
7764 var DateTimeUnit = powerbi.DateTimeUnit;
7765})(powerbi || (powerbi = {}));
7766/*
7767 * Power BI Visualizations
7768 *
7769 * Copyright (c) Microsoft Corporation
7770 * All rights reserved.
7771 * MIT License
7772 *
7773 * Permission is hereby granted, free of charge, to any person obtaining a copy
7774 * of this software and associated documentation files (the ""Software""), to deal
7775 * in the Software without restriction, including without limitation the rights
7776 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7777 * copies of the Software, and to permit persons to whom the Software is
7778 * furnished to do so, subject to the following conditions:
7779 *
7780 * The above copyright notice and this permission notice shall be included in
7781 * all copies or substantial portions of the Software.
7782 *
7783 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7784 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7785 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7786 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7787 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7788 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7789 * THE SOFTWARE.
7790 */
7791var powerbi;
7792(function (powerbi) {
7793 var data;
7794 (function (data) {
7795 var SQExprBuilder;
7796 (function (SQExprBuilder) {
7797 function fieldExpr(fieldExpr) {
7798 var sqExpr = FieldExprPattern.visit(fieldExpr, FieldExprToSQExprVisitor.instance);
7799 debug.assertValue(sqExpr, 'Failed to convert FieldExprPattern into SQExpr');
7800 return sqExpr;
7801 }
7802 SQExprBuilder.fieldExpr = fieldExpr;
7803 function fromColumnAggr(columnAggr) {
7804 return SQExprBuilder.aggregate(fromColumn(columnAggr), columnAggr.aggregate);
7805 }
7806 SQExprBuilder.fromColumnAggr = fromColumnAggr;
7807 function fromColumn(column) {
7808 return SQExprBuilder.columnRef(fromEntity(column), column.name);
7809 }
7810 SQExprBuilder.fromColumn = fromColumn;
7811 function fromEntity(entityPattern) {
7812 return SQExprBuilder.entity(entityPattern.schema, entityPattern.entity, entityPattern.entityVar);
7813 }
7814 SQExprBuilder.fromEntity = fromEntity;
7815 function fromEntityAggr(entityAggr) {
7816 return SQExprBuilder.aggregate(fromEntity(entityAggr), entityAggr.aggregate);
7817 }
7818 SQExprBuilder.fromEntityAggr = fromEntityAggr;
7819 function fromHierarchyLevelAggr(hierarchyLevelAggr) {
7820 return SQExprBuilder.aggregate(fromHierarchyLevel(hierarchyLevelAggr), hierarchyLevelAggr.aggregate);
7821 }
7822 SQExprBuilder.fromHierarchyLevelAggr = fromHierarchyLevelAggr;
7823 function fromHierarchyLevel(hierarchyLevelPattern) {
7824 return SQExprBuilder.hierarchyLevel(fromHierarchy(hierarchyLevelPattern), hierarchyLevelPattern.level);
7825 }
7826 SQExprBuilder.fromHierarchyLevel = fromHierarchyLevel;
7827 function fromHierarchy(hierarchyPattern) {
7828 return SQExprBuilder.hierarchy(fromEntity(hierarchyPattern), hierarchyPattern.name);
7829 }
7830 SQExprBuilder.fromHierarchy = fromHierarchy;
7831 var FieldExprToSQExprVisitor = (function () {
7832 function FieldExprToSQExprVisitor() {
7833 }
7834 FieldExprToSQExprVisitor.prototype.visitColumn = function (column) {
7835 return fromColumn(column);
7836 };
7837 FieldExprToSQExprVisitor.prototype.visitColumnAggr = function (columnAggr) {
7838 return fromColumnAggr(columnAggr);
7839 };
7840 FieldExprToSQExprVisitor.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariationPattern) {
7841 return SQExprBuilder.propertyVariationSource(this.visitEntity(columnHierarchyLevelVariationPattern.source), columnHierarchyLevelVariationPattern.source.name, columnHierarchyLevelVariationPattern.level.name);
7842 };
7843 FieldExprToSQExprVisitor.prototype.visitEntity = function (entityPattern) {
7844 return fromEntity(entityPattern);
7845 };
7846 FieldExprToSQExprVisitor.prototype.visitEntityAggr = function (entityAggr) {
7847 return fromEntityAggr(entityAggr);
7848 };
7849 FieldExprToSQExprVisitor.prototype.visitHierarchy = function (hierarchyPattern) {
7850 return fromHierarchy(hierarchyPattern);
7851 };
7852 FieldExprToSQExprVisitor.prototype.visitHierarchyLevel = function (level) {
7853 return fromHierarchyLevel(level);
7854 };
7855 FieldExprToSQExprVisitor.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
7856 return fromHierarchyLevelAggr(hierarchyLevelAggr);
7857 };
7858 FieldExprToSQExprVisitor.prototype.visitMeasure = function (measure) {
7859 return SQExprBuilder.measureRef(this.visitEntity(measure), measure.name);
7860 };
7861 FieldExprToSQExprVisitor.prototype.visitPercentile = function (percentile) {
7862 var arg = SQExprBuilder.fieldExpr(percentile.arg);
7863 return SQExprBuilder.percentile(arg, percentile.k, percentile.exclusive);
7864 };
7865 FieldExprToSQExprVisitor.prototype.visitPercentOfGrandTotal = function (percentOfGrandTotal) {
7866 var baseSQExpr = SQExprBuilder.fieldExpr(percentOfGrandTotal.baseExpr);
7867 return SQExprBuilder.arithmetic(baseSQExpr, SQExprBuilder.scopedEval(baseSQExpr, []), 3 /* Divide */);
7868 };
7869 FieldExprToSQExprVisitor.prototype.visitSelectRef = function (selectRef) {
7870 return SQExprBuilder.selectRef(selectRef.expressionName);
7871 };
7872 FieldExprToSQExprVisitor.instance = new FieldExprToSQExprVisitor();
7873 return FieldExprToSQExprVisitor;
7874 }());
7875 })(SQExprBuilder = data.SQExprBuilder || (data.SQExprBuilder = {}));
7876 var SQExprConverter;
7877 (function (SQExprConverter) {
7878 function asFieldPattern(sqExpr) {
7879 return sqExpr.accept(FieldExprPatternBuilder.instance);
7880 }
7881 SQExprConverter.asFieldPattern = asFieldPattern;
7882 })(SQExprConverter = data.SQExprConverter || (data.SQExprConverter = {}));
7883 var FieldExprPatternBuilder = (function (_super) {
7884 __extends(FieldExprPatternBuilder, _super);
7885 function FieldExprPatternBuilder() {
7886 _super.apply(this, arguments);
7887 }
7888 FieldExprPatternBuilder.prototype.visitColumnRef = function (expr) {
7889 var sourceRef = expr.source.accept(SourceExprPatternBuilder.instance);
7890 if (!sourceRef)
7891 return;
7892 if (sourceRef.entity) {
7893 var columnRef = sourceRef.entity;
7894 columnRef.name = expr.ref;
7895 return { column: columnRef };
7896 }
7897 };
7898 FieldExprPatternBuilder.prototype.visitMeasureRef = function (expr) {
7899 var sourceRef = expr.source.accept(SourceExprPatternBuilder.instance);
7900 if (!sourceRef)
7901 return;
7902 if (sourceRef.entity) {
7903 var measureRef = sourceRef.entity;
7904 measureRef.name = expr.ref;
7905 return { measure: measureRef };
7906 }
7907 };
7908 FieldExprPatternBuilder.prototype.visitEntity = function (expr) {
7909 var entityRef = {
7910 schema: expr.schema,
7911 entity: expr.entity
7912 };
7913 if (expr.variable)
7914 entityRef.entityVar = expr.variable;
7915 return { entity: entityRef };
7916 };
7917 FieldExprPatternBuilder.prototype.visitAggr = function (expr) {
7918 var fieldPattern = expr.arg.accept(this);
7919 if (fieldPattern && fieldPattern.column) {
7920 var argAggr = fieldPattern.column;
7921 argAggr.aggregate = expr.func;
7922 return { columnAggr: argAggr };
7923 }
7924 else if (fieldPattern && fieldPattern.columnAggr) {
7925 var argAggr = fieldPattern.columnAggr;
7926 argAggr.aggregate = expr.func;
7927 return { columnAggr: argAggr };
7928 }
7929 else if (fieldPattern && fieldPattern.hierarchyLevel) {
7930 var argAggr = fieldPattern.hierarchyLevel;
7931 argAggr.aggregate = expr.func;
7932 return { hierarchyLevelAggr: argAggr };
7933 }
7934 var sourcePattern = expr.arg.accept(SourceExprPatternBuilder.instance);
7935 if (sourcePattern && sourcePattern.entity) {
7936 var argAggr = sourcePattern.entity;
7937 argAggr.aggregate = expr.func;
7938 return { entityAggr: argAggr };
7939 }
7940 };
7941 FieldExprPatternBuilder.prototype.visitPercentile = function (expr) {
7942 return {
7943 percentile: {
7944 arg: expr.arg.accept(this),
7945 k: expr.k,
7946 exclusive: expr.exclusive,
7947 }
7948 };
7949 };
7950 FieldExprPatternBuilder.prototype.visitHierarchy = function (expr) {
7951 var sourcePattern = expr.arg.accept(SourceExprPatternBuilder.instance);
7952 if (sourcePattern && sourcePattern.entity) {
7953 var hierarchyRef = (sourcePattern.entity);
7954 hierarchyRef.name = expr.hierarchy;
7955 return { hierarchy: hierarchyRef };
7956 }
7957 };
7958 FieldExprPatternBuilder.prototype.visitHierarchyLevel = function (expr) {
7959 var hierarchySourceExprPattern = expr.arg.accept(HierarchyExprPatternBuiler.instance);
7960 if (!hierarchySourceExprPattern)
7961 return;
7962 var hierarchyLevel;
7963 if (hierarchySourceExprPattern.hierarchy) {
7964 hierarchyLevel = {
7965 entity: hierarchySourceExprPattern.hierarchy.entity,
7966 schema: hierarchySourceExprPattern.hierarchy.schema,
7967 name: hierarchySourceExprPattern.hierarchy.name,
7968 level: expr.level,
7969 };
7970 }
7971 if (hierarchySourceExprPattern.variation) {
7972 return {
7973 columnHierarchyLevelVariation: {
7974 source: {
7975 entity: hierarchySourceExprPattern.variation.column.entity,
7976 schema: hierarchySourceExprPattern.variation.column.schema,
7977 name: hierarchySourceExprPattern.variation.column.name,
7978 },
7979 level: hierarchyLevel,
7980 variationName: hierarchySourceExprPattern.variation.variationName,
7981 }
7982 };
7983 }
7984 return { hierarchyLevel: hierarchyLevel };
7985 };
7986 FieldExprPatternBuilder.prototype.visitArithmetic = function (expr) {
7987 var percentOfGrandTotalPattern = {
7988 percentOfGrandTotal: {
7989 baseExpr: expr.left.accept(this)
7990 }
7991 };
7992 if (data.SQExpr.equals(expr, SQExprBuilder.fieldExpr(percentOfGrandTotalPattern))) {
7993 return percentOfGrandTotalPattern;
7994 }
7995 };
7996 FieldExprPatternBuilder.prototype.visitSelectRef = function (expr) {
7997 return {
7998 selectRef: {
7999 expressionName: expr.expressionName,
8000 }
8001 };
8002 };
8003 FieldExprPatternBuilder.instance = new FieldExprPatternBuilder();
8004 return FieldExprPatternBuilder;
8005 }(data.DefaultSQExprVisitor));
8006 var SourceExprPatternBuilder = (function (_super) {
8007 __extends(SourceExprPatternBuilder, _super);
8008 function SourceExprPatternBuilder() {
8009 _super.apply(this, arguments);
8010 }
8011 SourceExprPatternBuilder.prototype.visitEntity = function (expr) {
8012 var entityRef = {
8013 schema: expr.schema,
8014 entity: expr.entity
8015 };
8016 if (expr.variable)
8017 entityRef.entityVar = expr.variable;
8018 return { entity: entityRef };
8019 };
8020 SourceExprPatternBuilder.prototype.visitPropertyVariationSource = function (expr) {
8021 var entityExpr = expr.arg;
8022 if (entityExpr instanceof data.SQEntityExpr) {
8023 var propertyVariationSource = {
8024 schema: entityExpr.schema,
8025 entity: entityExpr.entity,
8026 name: expr.property,
8027 };
8028 if (entityExpr.variable)
8029 propertyVariationSource.entityVar = entityExpr.variable;
8030 return {
8031 variation: {
8032 column: propertyVariationSource,
8033 variationName: expr.name,
8034 }
8035 };
8036 }
8037 };
8038 SourceExprPatternBuilder.instance = new SourceExprPatternBuilder();
8039 return SourceExprPatternBuilder;
8040 }(data.DefaultSQExprVisitor));
8041 var HierarchyExprPatternBuiler = (function (_super) {
8042 __extends(HierarchyExprPatternBuiler, _super);
8043 function HierarchyExprPatternBuiler() {
8044 _super.apply(this, arguments);
8045 }
8046 HierarchyExprPatternBuiler.prototype.visitHierarchy = function (expr) {
8047 var exprPattern = expr.arg.accept(SourceExprPatternBuilder.instance);
8048 var hierarchyRef;
8049 var variationRef;
8050 if (exprPattern.variation) {
8051 hierarchyRef = {
8052 name: expr.hierarchy,
8053 schema: exprPattern.variation.column.schema,
8054 entity: exprPattern.variation.column.entity,
8055 };
8056 variationRef = exprPattern.variation;
8057 }
8058 else
8059 hierarchyRef = {
8060 name: expr.hierarchy,
8061 schema: exprPattern.entity.schema,
8062 entity: exprPattern.entity.entity,
8063 };
8064 return {
8065 hierarchy: hierarchyRef,
8066 variation: variationRef
8067 };
8068 };
8069 HierarchyExprPatternBuiler.instance = new HierarchyExprPatternBuiler();
8070 return HierarchyExprPatternBuiler;
8071 }(data.DefaultSQExprVisitor));
8072 var FieldExprPattern;
8073 (function (FieldExprPattern) {
8074 function visit(expr, visitor) {
8075 debug.assertValue(expr, 'expr');
8076 debug.assertValue(visitor, 'visitor');
8077 var fieldExprPattern = expr instanceof data.SQExpr ? SQExprConverter.asFieldPattern(expr) : expr;
8078 debug.assertValue(fieldExprPattern, 'expected sqExpr to conform to a fieldExprPattern');
8079 if (fieldExprPattern.column)
8080 return visitColumn(fieldExprPattern.column, visitor);
8081 if (fieldExprPattern.columnAggr)
8082 return visitColumnAggr(fieldExprPattern.columnAggr, visitor);
8083 if (fieldExprPattern.columnHierarchyLevelVariation)
8084 return visitColumnHierarchyLevelVariation(fieldExprPattern.columnHierarchyLevelVariation, visitor);
8085 if (fieldExprPattern.entity)
8086 return visitEntity(fieldExprPattern.entity, visitor);
8087 if (fieldExprPattern.entityAggr)
8088 return visitEntityAggr(fieldExprPattern.entityAggr, visitor);
8089 if (fieldExprPattern.hierarchy)
8090 return visitHierarchy(fieldExprPattern.hierarchy, visitor);
8091 if (fieldExprPattern.hierarchyLevel)
8092 return visitHierarchyLevel(fieldExprPattern.hierarchyLevel, visitor);
8093 if (fieldExprPattern.hierarchyLevelAggr)
8094 return visitHierarchyLevelAggr(fieldExprPattern.hierarchyLevelAggr, visitor);
8095 if (fieldExprPattern.measure)
8096 return visitMeasure(fieldExprPattern.measure, visitor);
8097 if (fieldExprPattern.percentile)
8098 return visitPercentile(fieldExprPattern.percentile, visitor);
8099 if (fieldExprPattern.percentOfGrandTotal)
8100 return visitPercentOfGrandTotal(fieldExprPattern.percentOfGrandTotal, visitor);
8101 if (fieldExprPattern.selectRef)
8102 return visitSelectRef(fieldExprPattern.selectRef, visitor);
8103 debug.assertFail('failed to visit a fieldExprPattern.');
8104 return;
8105 }
8106 FieldExprPattern.visit = visit;
8107 function visitColumn(column, visitor) {
8108 debug.assertValue(column, 'column');
8109 debug.assertValue(visitor, 'visitor');
8110 return visitor.visitColumn(column);
8111 }
8112 function visitColumnAggr(columnAggr, visitor) {
8113 debug.assertValue(columnAggr, 'columnAggr');
8114 debug.assertValue(visitor, 'visitor');
8115 return visitor.visitColumnAggr(columnAggr);
8116 }
8117 function visitColumnHierarchyLevelVariation(columnHierarchyLevelVariation, visitor) {
8118 debug.assertValue(columnHierarchyLevelVariation, 'columnHierarchyLevelVariation');
8119 debug.assertValue(visitor, 'visitor');
8120 return visitor.visitColumnHierarchyLevelVariation(columnHierarchyLevelVariation);
8121 }
8122 function visitEntity(entity, visitor) {
8123 debug.assertValue(entity, 'entity');
8124 debug.assertValue(visitor, 'visitor');
8125 return visitor.visitEntity(entity);
8126 }
8127 function visitEntityAggr(entityAggr, visitor) {
8128 debug.assertValue(entityAggr, 'entityAggr');
8129 debug.assertValue(visitor, 'visitor');
8130 return visitor.visitEntityAggr(entityAggr);
8131 }
8132 function visitHierarchy(hierarchy, visitor) {
8133 debug.assertValue(hierarchy, 'hierarchy');
8134 debug.assertValue(visitor, 'visitor');
8135 return visitor.visitHierarchy(hierarchy);
8136 }
8137 function visitHierarchyLevel(hierarchyLevel, visitor) {
8138 debug.assertValue(hierarchyLevel, 'hierarchyLevel');
8139 debug.assertValue(visitor, 'visitor');
8140 return visitor.visitHierarchyLevel(hierarchyLevel);
8141 }
8142 function visitHierarchyLevelAggr(hierarchyLevelAggr, visitor) {
8143 debug.assertValue(hierarchyLevelAggr, 'hierarchyLevelAggr');
8144 debug.assertValue(visitor, 'visitor');
8145 return visitor.visitHierarchyLevelAggr(hierarchyLevelAggr);
8146 }
8147 function visitMeasure(measure, visitor) {
8148 debug.assertValue(measure, 'measure');
8149 debug.assertValue(visitor, 'visitor');
8150 return visitor.visitMeasure(measure);
8151 }
8152 function visitSelectRef(selectRef, visitor) {
8153 debug.assertValue(selectRef, 'selectRef');
8154 debug.assertValue(visitor, 'visitor');
8155 return visitor.visitSelectRef(selectRef);
8156 }
8157 function visitPercentile(percentile, visitor) {
8158 debug.assertValue(percentile, 'percentile');
8159 debug.assertValue(visitor, 'visitor');
8160 return visitor.visitPercentile(percentile);
8161 }
8162 function visitPercentOfGrandTotal(percentOfGrandTotal, visitor) {
8163 debug.assertValue(percentOfGrandTotal, 'percentOfGrandTotal');
8164 debug.assertValue(visitor, 'visitor');
8165 return visitor.visitPercentOfGrandTotal(percentOfGrandTotal);
8166 }
8167 function toColumnRefSQExpr(columnPattern) {
8168 return SQExprBuilder.columnRef(SQExprBuilder.entity(columnPattern.schema, columnPattern.entity, columnPattern.entityVar), columnPattern.name);
8169 }
8170 FieldExprPattern.toColumnRefSQExpr = toColumnRefSQExpr;
8171 function getAggregate(fieldExpr) {
8172 debug.assertValue(fieldExpr, 'fieldExpr');
8173 return visit(fieldExpr, FieldExprPatternAggregateVisitor.instance);
8174 }
8175 FieldExprPattern.getAggregate = getAggregate;
8176 function isAggregation(fieldExpr) {
8177 debug.assertValue(fieldExpr, 'fieldExpr');
8178 return visit(fieldExpr, FieldExprPatternIsAggregationVisitor.instance);
8179 }
8180 FieldExprPattern.isAggregation = isAggregation;
8181 function hasFieldExprName(fieldExpr) {
8182 return (fieldExpr.column ||
8183 fieldExpr.columnAggr ||
8184 fieldExpr.measure) !== undefined;
8185 }
8186 FieldExprPattern.hasFieldExprName = hasFieldExprName;
8187 function getPropertyName(fieldExpr) {
8188 return FieldExprPattern.visit(fieldExpr, FieldExprPropertyNameVisitor.instance);
8189 }
8190 FieldExprPattern.getPropertyName = getPropertyName;
8191 function getHierarchyName(fieldExpr) {
8192 var hierarchy = fieldExpr.hierarchy;
8193 if (hierarchy)
8194 return hierarchy.name;
8195 }
8196 FieldExprPattern.getHierarchyName = getHierarchyName;
8197 function getColumnRef(fieldExpr) {
8198 if (fieldExpr.columnHierarchyLevelVariation)
8199 return fieldExpr.columnHierarchyLevelVariation.source;
8200 return fieldExpr.column || fieldExpr.measure || fieldExpr.columnAggr;
8201 }
8202 FieldExprPattern.getColumnRef = getColumnRef;
8203 function getFieldExprName(fieldExpr) {
8204 var name = getPropertyName(fieldExpr);
8205 if (name)
8206 return name;
8207 // In case it is an entity
8208 return toFieldExprEntityPattern(fieldExpr).entity;
8209 }
8210 FieldExprPattern.getFieldExprName = getFieldExprName;
8211 function getSchema(fieldExpr) {
8212 debug.assertValue(fieldExpr, 'fieldExpr');
8213 var item = FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
8214 debug.assertAnyValue(item, 'expected fieldExpr to be an entity item');
8215 return item.schema;
8216 }
8217 FieldExprPattern.getSchema = getSchema;
8218 function toFieldExprEntityPattern(fieldExpr) {
8219 return FieldExprPattern.visit(fieldExpr, FieldExprToEntityExprPatternBuilder.instance);
8220 }
8221 FieldExprPattern.toFieldExprEntityPattern = toFieldExprEntityPattern;
8222 function toFieldExprEntityItemPattern(fieldExpr) {
8223 return FieldExprPattern.visit(fieldExpr, FieldExprToEntityExprPatternBuilder.instance);
8224 }
8225 FieldExprPattern.toFieldExprEntityItemPattern = toFieldExprEntityItemPattern;
8226 var FieldExprPatternAggregateVisitor = (function () {
8227 function FieldExprPatternAggregateVisitor() {
8228 }
8229 FieldExprPatternAggregateVisitor.prototype.visitColumn = function (column) {
8230 return;
8231 };
8232 FieldExprPatternAggregateVisitor.prototype.visitColumnAggr = function (columnAggr) {
8233 return columnAggr.aggregate;
8234 };
8235 FieldExprPatternAggregateVisitor.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
8236 return;
8237 };
8238 FieldExprPatternAggregateVisitor.prototype.visitEntity = function (entity) {
8239 return;
8240 };
8241 FieldExprPatternAggregateVisitor.prototype.visitEntityAggr = function (entityAggr) {
8242 return entityAggr.aggregate;
8243 };
8244 FieldExprPatternAggregateVisitor.prototype.visitHierarchy = function (hierarchy) {
8245 return;
8246 };
8247 FieldExprPatternAggregateVisitor.prototype.visitHierarchyLevel = function (hierarchyLevel) {
8248 return;
8249 };
8250 FieldExprPatternAggregateVisitor.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
8251 return hierarchyLevelAggr.aggregate;
8252 };
8253 FieldExprPatternAggregateVisitor.prototype.visitMeasure = function (measure) {
8254 return;
8255 };
8256 FieldExprPatternAggregateVisitor.prototype.visitSelectRef = function (selectRef) {
8257 return;
8258 };
8259 FieldExprPatternAggregateVisitor.prototype.visitPercentile = function (percentile) {
8260 // NOTE: Percentile behaves like an aggregate (i.e., can be performed over numeric columns like a SUM), but
8261 // this function can't really convey that because percentile (intentionally) isn't in QueryAggregateFunction enum.
8262 // This should be revisited when we have UI support for the Percentile aggregate.
8263 return;
8264 };
8265 FieldExprPatternAggregateVisitor.prototype.visitPercentOfGrandTotal = function (percentOfGrandTotal) {
8266 return data.SQExprInfo.getAggregate(SQExprBuilder.fieldExpr(percentOfGrandTotal.baseExpr));
8267 };
8268 FieldExprPatternAggregateVisitor.instance = new FieldExprPatternAggregateVisitor();
8269 return FieldExprPatternAggregateVisitor;
8270 }());
8271 var FieldExprPatternIsAggregationVisitor = (function () {
8272 function FieldExprPatternIsAggregationVisitor() {
8273 }
8274 FieldExprPatternIsAggregationVisitor.prototype.visitColumn = function (column) {
8275 return false;
8276 };
8277 FieldExprPatternIsAggregationVisitor.prototype.visitColumnAggr = function (columnAggr) {
8278 return true;
8279 };
8280 FieldExprPatternIsAggregationVisitor.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
8281 return false;
8282 };
8283 FieldExprPatternIsAggregationVisitor.prototype.visitEntity = function (entity) {
8284 return false;
8285 };
8286 FieldExprPatternIsAggregationVisitor.prototype.visitEntityAggr = function (entityAggr) {
8287 return true;
8288 };
8289 FieldExprPatternIsAggregationVisitor.prototype.visitHierarchy = function (hierarchy) {
8290 return false;
8291 };
8292 FieldExprPatternIsAggregationVisitor.prototype.visitHierarchyLevel = function (hierarchyLevel) {
8293 return false;
8294 };
8295 FieldExprPatternIsAggregationVisitor.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
8296 return true;
8297 };
8298 FieldExprPatternIsAggregationVisitor.prototype.visitMeasure = function (measure) {
8299 return true;
8300 };
8301 FieldExprPatternIsAggregationVisitor.prototype.visitSelectRef = function (selectRef) {
8302 return false;
8303 };
8304 FieldExprPatternIsAggregationVisitor.prototype.visitPercentile = function (percentile) {
8305 return true;
8306 };
8307 FieldExprPatternIsAggregationVisitor.prototype.visitPercentOfGrandTotal = function (percentOfGrandTotal) {
8308 return true;
8309 };
8310 FieldExprPatternIsAggregationVisitor.instance = new FieldExprPatternIsAggregationVisitor();
8311 return FieldExprPatternIsAggregationVisitor;
8312 }());
8313 var FieldExprToEntityExprPatternBuilder = (function () {
8314 function FieldExprToEntityExprPatternBuilder() {
8315 }
8316 FieldExprToEntityExprPatternBuilder.prototype.visitColumn = function (column) {
8317 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(column);
8318 };
8319 FieldExprToEntityExprPatternBuilder.prototype.visitColumnAggr = function (columnAggr) {
8320 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(columnAggr);
8321 };
8322 FieldExprToEntityExprPatternBuilder.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
8323 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(columnHierarchyLevelVariation.source);
8324 };
8325 FieldExprToEntityExprPatternBuilder.prototype.visitEntity = function (entity) {
8326 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(entity);
8327 };
8328 FieldExprToEntityExprPatternBuilder.prototype.visitEntityAggr = function (entityAggr) {
8329 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(entityAggr);
8330 };
8331 FieldExprToEntityExprPatternBuilder.prototype.visitHierarchy = function (hierarchy) {
8332 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(hierarchy);
8333 };
8334 FieldExprToEntityExprPatternBuilder.prototype.visitHierarchyLevel = function (hierarchyLevel) {
8335 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(hierarchyLevel);
8336 };
8337 FieldExprToEntityExprPatternBuilder.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
8338 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(hierarchyLevelAggr);
8339 };
8340 FieldExprToEntityExprPatternBuilder.prototype.visitMeasure = function (measure) {
8341 return FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern(measure);
8342 };
8343 FieldExprToEntityExprPatternBuilder.prototype.visitSelectRef = function (selectRef) {
8344 return;
8345 };
8346 FieldExprToEntityExprPatternBuilder.prototype.visitPercentile = function (percentile) {
8347 return FieldExprPattern.visit(percentile.arg, this);
8348 };
8349 FieldExprToEntityExprPatternBuilder.prototype.visitPercentOfGrandTotal = function (percentOfGrandTotal) {
8350 return FieldExprPattern.visit(percentOfGrandTotal.baseExpr, this);
8351 };
8352 FieldExprToEntityExprPatternBuilder.toEntityItemExprPattern = function (exprPattern) {
8353 debug.assertValue(exprPattern, 'exprPattern');
8354 var pattern = { schema: exprPattern.schema, entity: exprPattern.entity };
8355 if (exprPattern.entityVar) {
8356 pattern.entityVar = exprPattern.entityVar;
8357 }
8358 return pattern;
8359 };
8360 FieldExprToEntityExprPatternBuilder.instance = new FieldExprToEntityExprPatternBuilder();
8361 return FieldExprToEntityExprPatternBuilder;
8362 }());
8363 var FieldExprPropertyNameVisitor = (function () {
8364 function FieldExprPropertyNameVisitor() {
8365 }
8366 FieldExprPropertyNameVisitor.prototype.visitColumn = function (column) {
8367 return column.name;
8368 };
8369 FieldExprPropertyNameVisitor.prototype.visitColumnAggr = function (columnAggr) {
8370 return columnAggr.name;
8371 };
8372 FieldExprPropertyNameVisitor.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
8373 return;
8374 };
8375 FieldExprPropertyNameVisitor.prototype.visitEntity = function (entity) {
8376 return;
8377 };
8378 FieldExprPropertyNameVisitor.prototype.visitEntityAggr = function (entityAggr) {
8379 return;
8380 };
8381 FieldExprPropertyNameVisitor.prototype.visitHierarchy = function (hierarchy) {
8382 return;
8383 };
8384 FieldExprPropertyNameVisitor.prototype.visitHierarchyLevel = function (hierarchyLevel) {
8385 return;
8386 };
8387 FieldExprPropertyNameVisitor.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
8388 return;
8389 };
8390 FieldExprPropertyNameVisitor.prototype.visitMeasure = function (measure) {
8391 return measure.name;
8392 };
8393 FieldExprPropertyNameVisitor.prototype.visitSelectRef = function (selectRef) {
8394 return;
8395 };
8396 FieldExprPropertyNameVisitor.prototype.visitPercentile = function (percentile) {
8397 return FieldExprPattern.visit(percentile.arg, this);
8398 };
8399 FieldExprPropertyNameVisitor.prototype.visitPercentOfGrandTotal = function (percentOfGrandTotal) {
8400 return FieldExprPattern.visit(percentOfGrandTotal.baseExpr, this);
8401 };
8402 FieldExprPropertyNameVisitor.instance = new FieldExprPropertyNameVisitor();
8403 return FieldExprPropertyNameVisitor;
8404 }());
8405 })(FieldExprPattern = data.FieldExprPattern || (data.FieldExprPattern = {}));
8406 })(data = powerbi.data || (powerbi.data = {}));
8407})(powerbi || (powerbi = {}));
8408/*
8409 * Power BI Visualizations
8410 *
8411 * Copyright (c) Microsoft Corporation
8412 * All rights reserved.
8413 * MIT License
8414 *
8415 * Permission is hereby granted, free of charge, to any person obtaining a copy
8416 * of this software and associated documentation files (the ""Software""), to deal
8417 * in the Software without restriction, including without limitation the rights
8418 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8419 * copies of the Software, and to permit persons to whom the Software is
8420 * furnished to do so, subject to the following conditions:
8421 *
8422 * The above copyright notice and this permission notice shall be included in
8423 * all copies or substantial portions of the Software.
8424 *
8425 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8426 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8427 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8428 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8429 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8430 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8431 * THE SOFTWARE.
8432 */
8433var powerbi;
8434(function (powerbi) {
8435 var DataViewAnalysis;
8436 (function (DataViewAnalysis) {
8437 var ArrayExtensions = jsCommon.ArrayExtensions;
8438 var DataViewObjectDefinitions = powerbi.data.DataViewObjectDefinitions;
8439 (function (DataViewMappingMatchErrorCode) {
8440 DataViewMappingMatchErrorCode[DataViewMappingMatchErrorCode["conditionRangeTooLarge"] = 0] = "conditionRangeTooLarge";
8441 DataViewMappingMatchErrorCode[DataViewMappingMatchErrorCode["conditionRangeTooSmall"] = 1] = "conditionRangeTooSmall";
8442 DataViewMappingMatchErrorCode[DataViewMappingMatchErrorCode["conditionKindExpectedMeasure"] = 2] = "conditionKindExpectedMeasure";
8443 DataViewMappingMatchErrorCode[DataViewMappingMatchErrorCode["conditionKindExpectedGrouping"] = 3] = "conditionKindExpectedGrouping";
8444 DataViewMappingMatchErrorCode[DataViewMappingMatchErrorCode["conditionKindExpectedGroupingOrMeasure"] = 4] = "conditionKindExpectedGroupingOrMeasure";
8445 })(DataViewAnalysis.DataViewMappingMatchErrorCode || (DataViewAnalysis.DataViewMappingMatchErrorCode = {}));
8446 var DataViewMappingMatchErrorCode = DataViewAnalysis.DataViewMappingMatchErrorCode;
8447 /** Reshapes the data view to match the provided schema if possible. If not, returns null */
8448 function validateAndReshape(dataView, dataViewMappings) {
8449 if (!dataViewMappings || dataViewMappings.length === 0)
8450 return { dataView: dataView, isValid: true };
8451 if (dataView) {
8452 for (var _i = 0, dataViewMappings_3 = dataViewMappings; _i < dataViewMappings_3.length; _i++) {
8453 var dataViewMapping = dataViewMappings_3[_i];
8454 // Keep the original when possible.
8455 if (supports(dataView, dataViewMapping))
8456 return { dataView: dataView, isValid: true };
8457 if (dataViewMapping.categorical && dataView.categorical)
8458 return reshapeCategorical(dataView, dataViewMapping);
8459 if (dataViewMapping.tree && dataView.tree)
8460 return reshapeTree(dataView, dataViewMapping.tree);
8461 if (dataViewMapping.single && dataView.single)
8462 return reshapeSingle(dataView, dataViewMapping.single);
8463 if (dataViewMapping.table && dataView.table)
8464 return reshapeTable(dataView, dataViewMapping.table);
8465 }
8466 }
8467 else if (powerbi.ScriptResultUtil.findScriptResult(dataViewMappings)) {
8468 // Currently, PBI Service treats R Script Visuals as static images.
8469 // This causes validation to fail, since in PBI service no DataView is generated, but there are DataViewMappings,
8470 // to support the PBI Desktop scenario.
8471 // This code will be removed once PBI Service fully supports R Script Visuals.
8472 // VSTS: 6217994 - [R Viz] Remove temporary DataViewAnalysis validation workaround of static R Script Visual mappings
8473 return { dataView: dataView, isValid: true };
8474 }
8475 return { isValid: false };
8476 }
8477 DataViewAnalysis.validateAndReshape = validateAndReshape;
8478 function reshapeCategorical(dataView, dataViewMapping) {
8479 debug.assertValue(dataViewMapping, 'dataViewMapping');
8480 //The functionality that used to compare categorical.values.length to schema.values doesn't apply any more, we don't want to use the same logic for re-shaping.
8481 var categoryRoleMapping = dataViewMapping.categorical;
8482 var categorical = dataView.categorical;
8483 if (!categorical)
8484 return { isValid: false };
8485 var rowCount;
8486 if (categoryRoleMapping.rowCount) {
8487 rowCount = categoryRoleMapping.rowCount.supported;
8488 if (rowCount && rowCount.max) {
8489 var updated = void 0;
8490 var categories = categorical.categories;
8491 var maxRowCount = rowCount.max;
8492 var originalLength = undefined;
8493 if (categories) {
8494 for (var i = 0, len = categories.length; i < len; i++) {
8495 var category = categories[i];
8496 originalLength = category.values.length;
8497 if (maxRowCount !== undefined && originalLength > maxRowCount) {
8498 // Row count too large: Trim it to fit.
8499 var updatedCategories = ArrayExtensions.range(category.values, 0, maxRowCount - 1);
8500 updated = updated || { categories: [] };
8501 updated.categories.push({
8502 source: category.source,
8503 values: updatedCategories
8504 });
8505 }
8506 }
8507 }
8508 if (categorical.values && categorical.values.length > 0 && maxRowCount) {
8509 if (!originalLength)
8510 originalLength = categorical.values[0].values.length;
8511 if (maxRowCount !== undefined && originalLength > maxRowCount) {
8512 updated = updated || {};
8513 updated.values = powerbi.data.DataViewTransform.createValueColumns();
8514 for (var i = 0, len = categorical.values.length; i < len; i++) {
8515 var column = categorical.values[i], updatedColumn = {
8516 source: column.source,
8517 values: ArrayExtensions.range(column.values, 0, maxRowCount - 1)
8518 };
8519 if (column.min !== undefined)
8520 updatedColumn.min = column.min;
8521 if (column.max !== undefined)
8522 updatedColumn.max = column.max;
8523 if (column.subtotal !== undefined)
8524 updatedColumn.subtotal = column.subtotal;
8525 updated.values.push(updatedColumn);
8526 }
8527 }
8528 }
8529 if (updated) {
8530 dataView = {
8531 metadata: dataView.metadata,
8532 categorical: updated,
8533 };
8534 }
8535 }
8536 }
8537 if (supportsCategorical(dataView, dataViewMapping))
8538 return { dataView: dataView, isValid: true };
8539 return null;
8540 }
8541 function reshapeSingle(dataView, singleRoleMapping) {
8542 debug.assertValue(dataView, 'dataView');
8543 debug.assertValue(singleRoleMapping, 'singleRoleMapping');
8544 if (dataView.single)
8545 return { dataView: dataView, isValid: true };
8546 return { isValid: false };
8547 }
8548 function reshapeTree(dataView, treeRoleMapping) {
8549 debug.assertValue(dataView, 'dataView');
8550 debug.assertValue(treeRoleMapping, 'treeRoleMapping');
8551 // TODO: Need to implement the reshaping of Tree
8552 var metadata = dataView.metadata;
8553 if (validateRange(countGroups(metadata.columns), treeRoleMapping.depth) == null /*&& conforms(countMeasures(metadata.columns), treeRoleMapping.aggregates)*/)
8554 return { dataView: dataView, isValid: true };
8555 return { isValid: false };
8556 }
8557 function reshapeTable(dataView, tableRoleMapping) {
8558 debug.assertValue(dataView, 'dataView');
8559 debug.assertValue(tableRoleMapping, 'tableRoleMapping');
8560 if (dataView.table)
8561 return { dataView: dataView, isValid: true };
8562 return { isValid: false };
8563 }
8564 function countGroups(columns) {
8565 var count = 0;
8566 for (var i = 0, len = columns.length; i < len; i++) {
8567 if (!columns[i].isMeasure)
8568 ++count;
8569 }
8570 return count;
8571 }
8572 DataViewAnalysis.countGroups = countGroups;
8573 function countMeasures(columns) {
8574 var count = 0;
8575 for (var i = 0, len = columns.length; i < len; i++) {
8576 if (columns[i].isMeasure)
8577 ++count;
8578 }
8579 return count;
8580 }
8581 DataViewAnalysis.countMeasures = countMeasures;
8582 /** Indicates whether the dataView conforms to the specified schema. */
8583 function supports(dataView, roleMapping, usePreferredDataViewSchema) {
8584 if (!roleMapping || !dataView)
8585 return false;
8586 if (roleMapping.scriptResult && !supportsScriptResult(dataView.scriptResult, roleMapping.scriptResult))
8587 return false;
8588 if (roleMapping.categorical && !supportsCategorical(dataView, roleMapping.categorical, usePreferredDataViewSchema))
8589 return false;
8590 if (roleMapping.tree && !supportsTree(dataView, roleMapping.tree))
8591 return false;
8592 if (roleMapping.single && !supportsSingle(dataView.single, roleMapping.single))
8593 return false;
8594 if (roleMapping.table && !supportsTable(dataView.table, roleMapping.table, usePreferredDataViewSchema))
8595 return false;
8596 return true;
8597 }
8598 DataViewAnalysis.supports = supports;
8599 function supportsCategorical(dataView, categoryRoleMapping, usePreferredDataViewSchema) {
8600 debug.assertValue(categoryRoleMapping, 'categoryRoleMapping');
8601 var dataViewCategorical = dataView.categorical;
8602 if (!dataViewCategorical)
8603 return false;
8604 // TODO: Disabling this implementation isn't right.
8605 //if (!conforms(countMeasures(dataView.metadata.columns), categoryRoleMapping.values.roles.length))
8606 // return false;
8607 if (categoryRoleMapping.rowCount) {
8608 var rowCount = categoryRoleMapping.rowCount.supported;
8609 if (usePreferredDataViewSchema && categoryRoleMapping.rowCount.preferred)
8610 rowCount = categoryRoleMapping.rowCount.preferred;
8611 if (rowCount) {
8612 var len = 0;
8613 if (dataViewCategorical.values && dataViewCategorical.values.length)
8614 len = dataViewCategorical.values[0].values.length;
8615 else if (dataViewCategorical.categories && dataViewCategorical.categories.length)
8616 len = dataViewCategorical.categories[0].values.length;
8617 if (validateRange(len, rowCount) != null)
8618 return false;
8619 }
8620 }
8621 return true;
8622 }
8623 function supportsSingle(dataViewSingle, singleRoleMapping) {
8624 debug.assertValue(singleRoleMapping, 'singleRoleMapping');
8625 if (!dataViewSingle)
8626 return false;
8627 return true;
8628 }
8629 function supportsTree(dataView, treeRoleMapping) {
8630 debug.assertValue(treeRoleMapping, 'treeRoleMapping');
8631 var metadata = dataView.metadata;
8632 return validateRange(countGroups(metadata.columns), treeRoleMapping.depth) == null;
8633 }
8634 function supportsTable(dataViewTable, tableRoleMapping, usePreferredDataViewSchema) {
8635 debug.assertValue(tableRoleMapping, 'tableRoleMapping');
8636 if (!dataViewTable)
8637 return false;
8638 if (tableRoleMapping.rowCount) {
8639 var rowCount = tableRoleMapping.rowCount.supported;
8640 if (usePreferredDataViewSchema && tableRoleMapping.rowCount.preferred)
8641 rowCount = tableRoleMapping.rowCount.preferred;
8642 if (rowCount) {
8643 var len = 0;
8644 if (dataViewTable.rows && dataViewTable.rows.length)
8645 len = dataViewTable.rows.length;
8646 if (validateRange(len, rowCount) != null)
8647 return false;
8648 }
8649 }
8650 return true;
8651 }
8652 function supportsScriptResult(dataView, scriptResultRoleMapping) {
8653 debug.assertValue(scriptResultRoleMapping, 'scriptResultRoleMapping');
8654 if (!dataView)
8655 return false;
8656 if (!dataView.imageBase64)
8657 return false;
8658 return true;
8659 }
8660 /**
8661 * Determines whether the value conforms to the range in the role condition, returning undefined
8662 * if so or an appropriate error code if not.
8663 */
8664 function validateRange(value, roleCondition, ignoreMin) {
8665 debug.assertValue(value, 'value');
8666 if (!roleCondition)
8667 return;
8668 if (!ignoreMin && roleCondition.min !== undefined && roleCondition.min > value)
8669 return DataViewMappingMatchErrorCode.conditionRangeTooSmall;
8670 if (roleCondition.max !== undefined && roleCondition.max < value)
8671 return DataViewMappingMatchErrorCode.conditionRangeTooLarge;
8672 }
8673 DataViewAnalysis.validateRange = validateRange;
8674 /**
8675 * Determines whether the value conforms to the kind in the role condition, returning undefined
8676 * if so or an appropriate error code if not.
8677 */
8678 function validateKind(roleCondition, roleName, projections, roleKindByQueryRef) {
8679 if (!roleCondition || roleCondition.kind === undefined) {
8680 return;
8681 }
8682 var expectedKind = roleCondition.kind;
8683 var roleCollection = projections[roleName];
8684 if (roleCollection) {
8685 var roleProjections = roleCollection.all();
8686 for (var _i = 0, roleProjections_1 = roleProjections; _i < roleProjections_1.length; _i++) {
8687 var roleProjection = roleProjections_1[_i];
8688 if (roleKindByQueryRef[roleProjection.queryRef] !== expectedKind) {
8689 switch (expectedKind) {
8690 case powerbi.VisualDataRoleKind.Measure:
8691 return DataViewMappingMatchErrorCode.conditionKindExpectedMeasure;
8692 case powerbi.VisualDataRoleKind.Grouping:
8693 return DataViewMappingMatchErrorCode.conditionKindExpectedGrouping;
8694 case powerbi.VisualDataRoleKind.GroupingOrMeasure:
8695 return DataViewMappingMatchErrorCode.conditionKindExpectedGroupingOrMeasure;
8696 }
8697 }
8698 }
8699 }
8700 }
8701 /** Determines the appropriate DataViewMappings for the projections. */
8702 function chooseDataViewMappings(projections, mappings, roleKindByQueryRef, objectDescriptors, objectDefinitions) {
8703 debug.assertValue(projections, 'projections');
8704 debug.assertAnyValue(mappings, 'mappings');
8705 var supportedMappings = [];
8706 var errors = [];
8707 if (!_.isEmpty(mappings)) {
8708 for (var mappingIndex = 0, mappingCount = mappings.length; mappingIndex < mappingCount; mappingIndex++) {
8709 var mapping = mappings[mappingIndex], mappingConditions = mapping.conditions, requiredProperties = mapping.requiredProperties;
8710 var allPropertiesValid = areAllPropertiesValid(requiredProperties, objectDescriptors, objectDefinitions);
8711 var conditionsMet = [];
8712 if (!_.isEmpty(mappingConditions)) {
8713 for (var conditionIndex = 0, conditionCount = mappingConditions.length; conditionIndex < conditionCount; conditionIndex++) {
8714 var condition = mappingConditions[conditionIndex];
8715 var currentConditionErrors = checkForConditionErrors(projections, condition, roleKindByQueryRef);
8716 if (!_.isEmpty(currentConditionErrors)) {
8717 for (var _i = 0, currentConditionErrors_1 = currentConditionErrors; _i < currentConditionErrors_1.length; _i++) {
8718 var error = currentConditionErrors_1[_i];
8719 error.mappingIndex = mappingIndex;
8720 error.conditionIndex = conditionIndex;
8721 errors.push(error);
8722 }
8723 }
8724 else
8725 conditionsMet.push(condition);
8726 }
8727 }
8728 else {
8729 conditionsMet.push({});
8730 }
8731 if (!_.isEmpty(conditionsMet) && allPropertiesValid) {
8732 var supportedMapping = _.cloneDeep(mapping);
8733 var updatedConditions = _.filter(conditionsMet, function (condition) { return Object.keys(condition).length > 0; });
8734 if (!_.isEmpty(updatedConditions))
8735 supportedMapping.conditions = updatedConditions;
8736 supportedMappings.push(supportedMapping);
8737 }
8738 }
8739 }
8740 return {
8741 supportedMappings: ArrayExtensions.emptyToNull(supportedMappings),
8742 mappingErrors: ArrayExtensions.emptyToNull(errors),
8743 };
8744 }
8745 DataViewAnalysis.chooseDataViewMappings = chooseDataViewMappings;
8746 function checkForConditionErrors(projections, condition, roleKindByQueryRef) {
8747 debug.assertValue(projections, 'projections');
8748 debug.assertValue(condition, 'condition');
8749 var conditionRoles = Object.keys(condition);
8750 var errors = [];
8751 for (var i = 0, len = conditionRoles.length; i < len; i++) {
8752 var roleName = conditionRoles[i], isDrillable = projections[roleName] && !_.isEmpty(projections[roleName].activeProjectionRefs), roleCondition = condition[roleName];
8753 var roleCount = getPropertyCount(roleName, projections, isDrillable);
8754 var rangeError = validateRange(roleCount, roleCondition);
8755 if (rangeError != null) {
8756 errors.push({
8757 code: rangeError,
8758 roleName: roleName,
8759 });
8760 }
8761 var kindError = validateKind(roleCondition, roleName, projections, roleKindByQueryRef);
8762 if (kindError != null) {
8763 errors.push({
8764 code: kindError,
8765 roleName: roleName,
8766 });
8767 }
8768 }
8769 return errors;
8770 }
8771 function areAllPropertiesValid(requiredProperties, objectDescriptors, objectDefinitions) {
8772 if (_.isEmpty(requiredProperties))
8773 return true;
8774 if (!objectDescriptors || !objectDefinitions)
8775 return false;
8776 var staticEvalContext = powerbi.data.createStaticEvalContext();
8777 return _.every(requiredProperties, function (requiredProperty) {
8778 var objectDescriptorValue = null;
8779 var objectDescriptorProperty = objectDescriptors[requiredProperty.objectName];
8780 if (objectDescriptorProperty)
8781 objectDescriptorValue = objectDescriptorProperty.properties[requiredProperty.propertyName];
8782 var objectDefinitionValue = DataViewObjectDefinitions.getValue(objectDefinitions, requiredProperty, null);
8783 if (!objectDescriptorValue || !objectDefinitionValue)
8784 return false;
8785 return powerbi.data.DataViewObjectEvaluator.evaluateProperty(staticEvalContext, objectDescriptorValue, objectDefinitionValue);
8786 });
8787 }
8788 function getPropertyCount(roleName, projections, useActiveIfAvailable) {
8789 debug.assertValue(roleName, 'roleName');
8790 debug.assertValue(projections, 'projections');
8791 var projectionsForRole = projections[roleName];
8792 if (projectionsForRole) {
8793 if (useActiveIfAvailable)
8794 return 1;
8795 return projectionsForRole.all().length;
8796 }
8797 return 0;
8798 }
8799 DataViewAnalysis.getPropertyCount = getPropertyCount;
8800 function hasSameCategoryIdentity(dataView1, dataView2) {
8801 if (dataView1
8802 && dataView2
8803 && dataView1.categorical
8804 && dataView2.categorical) {
8805 var dv1Categories = dataView1.categorical.categories;
8806 var dv2Categories = dataView2.categorical.categories;
8807 if (dv1Categories
8808 && dv2Categories
8809 && dv1Categories.length === dv2Categories.length) {
8810 for (var i = 0, len = dv1Categories.length; i < len; i++) {
8811 var dv1Identity = dv1Categories[i].identity;
8812 var dv2Identity = dv2Categories[i].identity;
8813 var dv1Length = getLengthOptional(dv1Identity);
8814 if (dv1Length !== getLengthOptional(dv2Identity))
8815 return false;
8816 for (var j = 0; j < dv1Length; j++) {
8817 if (!powerbi.DataViewScopeIdentity.equals(dv1Identity[j], dv2Identity[j]))
8818 return false;
8819 }
8820 }
8821 return true;
8822 }
8823 }
8824 return false;
8825 }
8826 DataViewAnalysis.hasSameCategoryIdentity = hasSameCategoryIdentity;
8827 function getLengthOptional(identity) {
8828 if (identity)
8829 return identity.length;
8830 return 0;
8831 }
8832 function areMetadataColumnsEquivalent(column1, column2) {
8833 if (!column1 && !column2)
8834 return true;
8835 if (!column1 || !column2)
8836 return false;
8837 if (column1.displayName !== column2.displayName)
8838 return false;
8839 if (column1.queryName !== column2.queryName)
8840 return false;
8841 if (column1.isMeasure !== column2.isMeasure)
8842 return false;
8843 if (column1.type !== column2.type)
8844 return false;
8845 if (column1.sort !== column2.sort)
8846 return false;
8847 return true;
8848 }
8849 DataViewAnalysis.areMetadataColumnsEquivalent = areMetadataColumnsEquivalent;
8850 /* Returns true if the metadata columns at the same positions in the array are equivalent. */
8851 function isMetadataEquivalent(metadata1, metadata2) {
8852 if (!metadata1 && !metadata2)
8853 return true;
8854 if (!metadata1 || !metadata2)
8855 return false;
8856 var previousColumnsLength = metadata1.columns.length;
8857 var newColumnsLength = metadata2.columns.length;
8858 if (previousColumnsLength !== newColumnsLength)
8859 return false;
8860 for (var i = 0; i < newColumnsLength; i++) {
8861 if (!DataViewAnalysis.areMetadataColumnsEquivalent(metadata1.columns[i], metadata2.columns[i]))
8862 return false;
8863 }
8864 return true;
8865 }
8866 DataViewAnalysis.isMetadataEquivalent = isMetadataEquivalent;
8867 })(DataViewAnalysis = powerbi.DataViewAnalysis || (powerbi.DataViewAnalysis = {}));
8868})(powerbi || (powerbi = {}));
8869/*
8870 * Power BI Visualizations
8871 *
8872 * Copyright (c) Microsoft Corporation
8873 * All rights reserved.
8874 * MIT License
8875 *
8876 * Permission is hereby granted, free of charge, to any person obtaining a copy
8877 * of this software and associated documentation files (the ""Software""), to deal
8878 * in the Software without restriction, including without limitation the rights
8879 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8880 * copies of the Software, and to permit persons to whom the Software is
8881 * furnished to do so, subject to the following conditions:
8882 *
8883 * The above copyright notice and this permission notice shall be included in
8884 * all copies or substantial portions of the Software.
8885 *
8886 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8887 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8888 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8889 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8890 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8891 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8892 * THE SOFTWARE.
8893 */
8894var powerbi;
8895(function (powerbi) {
8896 var data;
8897 (function (data) {
8898 var ArrayExtensions = jsCommon.ArrayExtensions;
8899 var Lazy = jsCommon.Lazy;
8900 var DataViewRoleWildcard;
8901 (function (DataViewRoleWildcard) {
8902 function fromRoles(roles) {
8903 return new DataViewRoleWildcardImpl(roles);
8904 }
8905 DataViewRoleWildcard.fromRoles = fromRoles;
8906 function equals(firstRoleWildcard, secondRoleWildcard) {
8907 return firstRoleWildcard.key &&
8908 secondRoleWildcard.key &&
8909 firstRoleWildcard.key === secondRoleWildcard.key &&
8910 ArrayExtensions.sequenceEqual(firstRoleWildcard.roles, secondRoleWildcard.roles, function (role1, role2) { return role1 === role2; });
8911 }
8912 DataViewRoleWildcard.equals = equals;
8913 var DataViewRoleWildcardImpl = (function () {
8914 function DataViewRoleWildcardImpl(roles) {
8915 var _this = this;
8916 debug.assertNonEmpty(roles, 'roles');
8917 this._roles = roles;
8918 this._key = new Lazy(function () { return JSON.stringify(_this.roles); });
8919 }
8920 Object.defineProperty(DataViewRoleWildcardImpl.prototype, "roles", {
8921 get: function () {
8922 return this._roles;
8923 },
8924 enumerable: true,
8925 configurable: true
8926 });
8927 Object.defineProperty(DataViewRoleWildcardImpl.prototype, "key", {
8928 get: function () {
8929 return this._key.getValue();
8930 },
8931 enumerable: true,
8932 configurable: true
8933 });
8934 return DataViewRoleWildcardImpl;
8935 }());
8936 })(DataViewRoleWildcard = data.DataViewRoleWildcard || (data.DataViewRoleWildcard = {}));
8937 })(data = powerbi.data || (powerbi.data = {}));
8938})(powerbi || (powerbi = {}));
8939/*
8940 * Power BI Visualizations
8941 *
8942 * Copyright (c) Microsoft Corporation
8943 * All rights reserved.
8944 * MIT License
8945 *
8946 * Permission is hereby granted, free of charge, to any person obtaining a copy
8947 * of this software and associated documentation files (the ""Software""), to deal
8948 * in the Software without restriction, including without limitation the rights
8949 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8950 * copies of the Software, and to permit persons to whom the Software is
8951 * furnished to do so, subject to the following conditions:
8952 *
8953 * The above copyright notice and this permission notice shall be included in
8954 * all copies or substantial portions of the Software.
8955 *
8956 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8957 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8958 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8959 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8960 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8961 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8962 * THE SOFTWARE.
8963 */
8964var powerbi;
8965(function (powerbi) {
8966 var DataViewScopeIdentity;
8967 (function (DataViewScopeIdentity) {
8968 /** Compares the two DataViewScopeIdentity values for equality. */
8969 function equals(x, y, ignoreCase) {
8970 // Normalize falsy to null
8971 x = x || null;
8972 y = y || null;
8973 if (x === y)
8974 return true;
8975 if (!x !== !y)
8976 return false;
8977 debug.assertValue(x, 'x');
8978 debug.assertValue(y, 'y');
8979 return data.SQExpr.equals(x.expr, y.expr, ignoreCase);
8980 }
8981 DataViewScopeIdentity.equals = equals;
8982 function filterFromIdentity(identities, isNot) {
8983 if (_.isEmpty(identities))
8984 return;
8985 var exprs = [];
8986 for (var _i = 0, identities_1 = identities; _i < identities_1.length; _i++) {
8987 var identity = identities_1[_i];
8988 exprs.push(identity.expr);
8989 }
8990 return filterFromExprs(exprs, isNot);
8991 }
8992 DataViewScopeIdentity.filterFromIdentity = filterFromIdentity;
8993 function filterFromExprs(orExprs, isNot) {
8994 if (_.isEmpty(orExprs))
8995 return;
8996 var resultExpr;
8997 for (var _i = 0, orExprs_1 = orExprs; _i < orExprs_1.length; _i++) {
8998 var orExpr = orExprs_1[_i];
8999 var inExpr = data.ScopeIdentityExtractor.getInExpr(orExpr);
9000 if (resultExpr)
9001 resultExpr = data.SQExprBuilder.or(resultExpr, inExpr);
9002 else
9003 resultExpr = inExpr || orExpr;
9004 }
9005 if (resultExpr) {
9006 if (isNot)
9007 resultExpr = powerbi.data.SQExprBuilder.not(resultExpr);
9008 }
9009 return powerbi.data.SemanticFilter.fromSQExpr(resultExpr);
9010 }
9011 DataViewScopeIdentity.filterFromExprs = filterFromExprs;
9012 })(DataViewScopeIdentity = powerbi.DataViewScopeIdentity || (powerbi.DataViewScopeIdentity = {}));
9013 var data;
9014 (function (data) {
9015 var Lazy = jsCommon.Lazy;
9016 function createDataViewScopeIdentity(expr) {
9017 return new DataViewScopeIdentityImpl(expr);
9018 }
9019 data.createDataViewScopeIdentity = createDataViewScopeIdentity;
9020 var DataViewScopeIdentityImpl = (function () {
9021 function DataViewScopeIdentityImpl(expr) {
9022 debug.assertValue(expr, 'expr');
9023 this._expr = expr;
9024 this._key = new Lazy(function () { return data.SQExprShortSerializer.serialize(expr); });
9025 }
9026 Object.defineProperty(DataViewScopeIdentityImpl.prototype, "expr", {
9027 get: function () {
9028 return this._expr;
9029 },
9030 enumerable: true,
9031 configurable: true
9032 });
9033 Object.defineProperty(DataViewScopeIdentityImpl.prototype, "key", {
9034 get: function () {
9035 return this._key.getValue();
9036 },
9037 enumerable: true,
9038 configurable: true
9039 });
9040 return DataViewScopeIdentityImpl;
9041 }());
9042 })(data = powerbi.data || (powerbi.data = {}));
9043})(powerbi || (powerbi = {}));
9044/*
9045 * Power BI Visualizations
9046 *
9047 * Copyright (c) Microsoft Corporation
9048 * All rights reserved.
9049 * MIT License
9050 *
9051 * Permission is hereby granted, free of charge, to any person obtaining a copy
9052 * of this software and associated documentation files (the ""Software""), to deal
9053 * in the Software without restriction, including without limitation the rights
9054 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9055 * copies of the Software, and to permit persons to whom the Software is
9056 * furnished to do so, subject to the following conditions:
9057 *
9058 * The above copyright notice and this permission notice shall be included in
9059 * all copies or substantial portions of the Software.
9060 *
9061 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9062 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9063 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9064 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9065 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9066 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9067 * THE SOFTWARE.
9068 */
9069var powerbi;
9070(function (powerbi) {
9071 var data;
9072 (function (data) {
9073 var Lazy = jsCommon.Lazy;
9074 var DataViewScopeWildcard;
9075 (function (DataViewScopeWildcard) {
9076 function matches(wildcard, instance) {
9077 var instanceExprs = data.ScopeIdentityExtractor.getKeys(instance.expr);
9078 if (!instanceExprs)
9079 return false;
9080 return data.SQExprUtils.sequenceEqual(wildcard.exprs, instanceExprs);
9081 }
9082 DataViewScopeWildcard.matches = matches;
9083 function equals(firstScopeWildcard, secondScopeWildcard) {
9084 return firstScopeWildcard.key === secondScopeWildcard.key &&
9085 data.SQExprUtils.sequenceEqual(firstScopeWildcard.exprs, secondScopeWildcard.exprs);
9086 }
9087 DataViewScopeWildcard.equals = equals;
9088 function fromExprs(exprs) {
9089 return new DataViewScopeWildcardImpl(exprs);
9090 }
9091 DataViewScopeWildcard.fromExprs = fromExprs;
9092 var DataViewScopeWildcardImpl = (function () {
9093 function DataViewScopeWildcardImpl(exprs) {
9094 debug.assertValue(exprs, 'exprs');
9095 this._exprs = exprs;
9096 this._key = new Lazy(function () { return data.SQExprShortSerializer.serializeArray(exprs); });
9097 }
9098 Object.defineProperty(DataViewScopeWildcardImpl.prototype, "exprs", {
9099 get: function () {
9100 return this._exprs;
9101 },
9102 enumerable: true,
9103 configurable: true
9104 });
9105 Object.defineProperty(DataViewScopeWildcardImpl.prototype, "key", {
9106 get: function () {
9107 return this._key.getValue();
9108 },
9109 enumerable: true,
9110 configurable: true
9111 });
9112 return DataViewScopeWildcardImpl;
9113 }());
9114 })(DataViewScopeWildcard = data.DataViewScopeWildcard || (data.DataViewScopeWildcard = {}));
9115 })(data = powerbi.data || (powerbi.data = {}));
9116})(powerbi || (powerbi = {}));
9117/*
9118 * Power BI Visualizations
9119 *
9120 * Copyright (c) Microsoft Corporation
9121 * All rights reserved.
9122 * MIT License
9123 *
9124 * Permission is hereby granted, free of charge, to any person obtaining a copy
9125 * of this software and associated documentation files (the ""Software""), to deal
9126 * in the Software without restriction, including without limitation the rights
9127 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9128 * copies of the Software, and to permit persons to whom the Software is
9129 * furnished to do so, subject to the following conditions:
9130 *
9131 * The above copyright notice and this permission notice shall be included in
9132 * all copies or substantial portions of the Software.
9133 *
9134 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9135 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9136 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9137 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9138 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9139 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9140 * THE SOFTWARE.
9141 */
9142var powerbi;
9143(function (powerbi) {
9144 var data;
9145 (function (data) {
9146 function createColorAllocatorCache() {
9147 return new ColorAllocatorProvider();
9148 }
9149 data.createColorAllocatorCache = createColorAllocatorCache;
9150 var ColorAllocatorProvider = (function () {
9151 function ColorAllocatorProvider() {
9152 this.cache = [];
9153 }
9154 ColorAllocatorProvider.prototype.get = function (key) {
9155 debug.assertValue(key, 'key');
9156 for (var _i = 0, _a = this.cache; _i < _a.length; _i++) {
9157 var entry = _a[_i];
9158 if (entry.key === key)
9159 return entry.allocator;
9160 }
9161 };
9162 ColorAllocatorProvider.prototype.register = function (key, colorAllocator) {
9163 debug.assertValue(key, 'key');
9164 debug.assertValue(colorAllocator, 'colorAllocator');
9165 debug.assert(this.get(key) == null, 'Trying to re-register for same key expr.');
9166 this.cache.push({
9167 key: key,
9168 allocator: colorAllocator,
9169 });
9170 return this;
9171 };
9172 return ColorAllocatorProvider;
9173 }());
9174 })(data = powerbi.data || (powerbi.data = {}));
9175})(powerbi || (powerbi = {}));
9176/*
9177 * Power BI Visualizations
9178 *
9179 * Copyright (c) Microsoft Corporation
9180 * All rights reserved.
9181 * MIT License
9182 *
9183 * Permission is hereby granted, free of charge, to any person obtaining a copy
9184 * of this software and associated documentation files (the ""Software""), to deal
9185 * in the Software without restriction, including without limitation the rights
9186 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9187 * copies of the Software, and to permit persons to whom the Software is
9188 * furnished to do so, subject to the following conditions:
9189 *
9190 * The above copyright notice and this permission notice shall be included in
9191 * all copies or substantial portions of the Software.
9192 *
9193 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9194 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9195 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9196 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9197 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9198 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9199 * THE SOFTWARE.
9200 */
9201/*
9202 * Power BI Visualizations
9203 *
9204 * Copyright (c) Microsoft Corporation
9205 * All rights reserved.
9206 * MIT License
9207 *
9208 * Permission is hereby granted, free of charge, to any person obtaining a copy
9209 * of this software and associated documentation files (the ""Software""), to deal
9210 * in the Software without restriction, including without limitation the rights
9211 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9212 * copies of the Software, and to permit persons to whom the Software is
9213 * furnished to do so, subject to the following conditions:
9214 *
9215 * The above copyright notice and this permission notice shall be included in
9216 * all copies or substantial portions of the Software.
9217 *
9218 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9219 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9220 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9221 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9222 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9223 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9224 * THE SOFTWARE.
9225 */
9226var powerbi;
9227(function (powerbi) {
9228 var data;
9229 (function (data) {
9230 var DataViewRegression;
9231 (function (DataViewRegression) {
9232 // TODO VSTS 6842046: Currently we are using a constant queryName since we don't have a way to generate
9233 // unique ones. There is a bug filed to do this by lawong, so this part will be fixed with that bug.
9234 var regressionXQueryName = 'RegressionX';
9235 var regressionSeriesQueryName = 'RegressionSeries';
9236 DataViewRegression.regressionYQueryName = 'RegressionY';
9237 function run(options) {
9238 debug.assertValue(options, 'options');
9239 var dataViewMappings = options.dataViewMappings;
9240 var visualDataViews = options.visualDataViews;
9241 var dataRoles = options.dataRoles;
9242 var objectDescriptors = options.objectDescriptors;
9243 var objectDefinitions = options.objectDefinitions;
9244 var colorAllocatorFactory = options.colorAllocatorFactory;
9245 var transformSelects = options.transformSelects;
9246 var projectionActiveItems = options.projectionActiveItems;
9247 var metadata = options.metadata;
9248 if (!_.isEmpty(visualDataViews) && transformSelects && metadata) {
9249 // compute linear regression line if applicable
9250 var roleKindByQueryRef = data.DataViewSelectTransform.createRoleKindFromMetadata(transformSelects, metadata);
9251 var projections = data.DataViewSelectTransform.projectionsFromSelects(transformSelects, projectionActiveItems);
9252 if (!roleKindByQueryRef || !projections || _.isEmpty(dataViewMappings) || !objectDescriptors || !objectDefinitions)
9253 return visualDataViews;
9254 var applicableDataViewMappings = powerbi.DataViewAnalysis.chooseDataViewMappings(projections, dataViewMappings, roleKindByQueryRef, objectDescriptors, objectDefinitions).supportedMappings;
9255 if (applicableDataViewMappings) {
9256 var regressionDataViewMapping = _.find(applicableDataViewMappings, function (dataViewMapping) {
9257 return dataViewMapping.usage && dataViewMapping.usage.regression;
9258 });
9259 if (regressionDataViewMapping) {
9260 var regressionDataViews = [];
9261 for (var _i = 0, visualDataViews_1 = visualDataViews; _i < visualDataViews_1.length; _i++) {
9262 var visualDataView = visualDataViews_1[_i];
9263 var regressionDataView = this.linearRegressionTransform(visualDataView, dataRoles, regressionDataViewMapping, objectDescriptors, objectDefinitions, colorAllocatorFactory);
9264 if (regressionDataView)
9265 regressionDataViews.push(regressionDataView);
9266 }
9267 if (!_.isEmpty(regressionDataViews))
9268 visualDataViews.push.apply(visualDataViews, regressionDataViews);
9269 }
9270 }
9271 }
9272 return visualDataViews;
9273 }
9274 DataViewRegression.run = run;
9275 /**
9276 * This function will compute the linear regression algorithm on the sourceDataView and create a new dataView.
9277 * It works on scalar axis only.
9278 * The algorithm is as follows
9279 *
9280 * 1. Find the cartesian X and Y roles and the columns that correspond to those roles
9281 * 2. Get the data points, (X, Y) pairs, for each series, combining if needed.
9282 * 3. Compute the X and Y points for regression line using Y = Slope * X + Intercept
9283 * If highlights values are present, repeat steps 2 & 3 using highlight values.
9284 * 4. Create the new dataView using the points computed above
9285 */
9286 function linearRegressionTransform(sourceDataView, dataRoles, regressionDataViewMapping, objectDescriptors, objectDefinitions, colorAllocatorFactory) {
9287 debug.assertValue(sourceDataView, 'sourceDataView');
9288 debug.assertValue(sourceDataView.categorical, 'sourceDataView.categorical');
9289 debug.assertValue(dataRoles, 'dataRoles');
9290 debug.assertValue(objectDescriptors, 'objectDescriptors');
9291 debug.assertValue(objectDefinitions, 'objectDefinitions');
9292 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
9293 if (!sourceDataView.categorical)
9294 return;
9295 // Step 1
9296 var xColumns = getColumnsForCartesianRoleKind(0 /* X */, sourceDataView.categorical, dataRoles);
9297 var yColumns = getColumnsForCartesianRoleKind(1 /* Y */, sourceDataView.categorical, dataRoles);
9298 if (_.isEmpty(xColumns) || _.isEmpty(yColumns))
9299 return;
9300 var xColumnSource = xColumns[0].source;
9301 var yColumnSource = yColumns[0].source;
9302 var combineSeries = true;
9303 if (regressionDataViewMapping.usage && regressionDataViewMapping.usage.regression && sourceDataView.metadata.objects) {
9304 var regressionUsage = regressionDataViewMapping.usage.regression;
9305 var combineSeriesPropertyId = regressionUsage['combineSeries'];
9306 if (combineSeriesPropertyId) {
9307 combineSeries = powerbi.DataViewObjects.getValue(sourceDataView.metadata.objects, combineSeriesPropertyId, true);
9308 }
9309 }
9310 // Step 2
9311 var dataPointsBySeries = getDataPointsBySeries(xColumns, yColumns, combineSeries, /* preferHighlights */ false);
9312 var lineDefSet = calculateLineDefinitions(dataPointsBySeries);
9313 var xMin = lineDefSet.xMin;
9314 var xMax = lineDefSet.xMax;
9315 var shouldComputeHightlights = hasHighlightValues(yColumns) || hasHighlightValues(xColumns);
9316 var highlightsLineDefSet;
9317 if (shouldComputeHightlights) {
9318 var highlightDataPointsBySeries = getDataPointsBySeries(xColumns, yColumns, combineSeries, /* preferHighlights */ true);
9319 highlightsLineDefSet = calculateLineDefinitions(highlightDataPointsBySeries);
9320 if (highlightsLineDefSet) {
9321 xMin = _.min([xMin, highlightsLineDefSet.xMin]);
9322 xMax = _.max([xMax, highlightsLineDefSet.xMax]);
9323 }
9324 else {
9325 shouldComputeHightlights = false;
9326 }
9327 }
9328 // Step 3
9329 var valuesByTrend = [];
9330 for (var _i = 0, _a = lineDefSet.lineDefs; _i < _a.length; _i++) {
9331 var trend = _a[_i];
9332 valuesByTrend.push(computeLineYValues(trend, +xMin, +xMax));
9333 }
9334 var highlightsByTrend;
9335 if (shouldComputeHightlights) {
9336 highlightsByTrend = [];
9337 for (var _b = 0, _c = highlightsLineDefSet.lineDefs; _b < _c.length; _b++) {
9338 var trend = _c[_b];
9339 highlightsByTrend.push(computeLineYValues(trend, +xMin, +xMax));
9340 }
9341 }
9342 // Step 4
9343 var groupValues;
9344 if (combineSeries) {
9345 groupValues = ['combinedRegressionSeries'];
9346 }
9347 else {
9348 // If we are producing a trend line per series we need to maintain the group identities so that we can map between the
9349 // trend line and the original series (to match the color for example).
9350 if (sourceDataView.categorical.values.source) {
9351 // Source data view has dynamic series.
9352 var groups = sourceDataView.categorical.values.grouped();
9353 groupValues = _.map(groups, function (group) { return group.name; });
9354 }
9355 else {
9356 // Source data view has static or no series.
9357 groupValues = _.map(yColumns, function (column) { return column.source.queryName; });
9358 }
9359 }
9360 // Step 5
9361 var regressionDataView = createRegressionDataView(xColumnSource, yColumnSource, groupValues, [xMin, xMax], valuesByTrend, highlightsByTrend, sourceDataView, regressionDataViewMapping, objectDescriptors, objectDefinitions, colorAllocatorFactory);
9362 return regressionDataView;
9363 }
9364 DataViewRegression.linearRegressionTransform = linearRegressionTransform;
9365 function calculateLineDefinitions(dataPointsBySeries) {
9366 var xMin;
9367 var xMax;
9368 var lineDefs = [];
9369 for (var _i = 0, dataPointsBySeries_1 = dataPointsBySeries; _i < dataPointsBySeries_1.length; _i++) {
9370 var dataPointSet = dataPointsBySeries_1[_i];
9371 var unsortedXValues = dataPointSet.xValues;
9372 var unsortedYValues = dataPointSet.yValues;
9373 if (_.isEmpty(unsortedXValues) || _.isEmpty(unsortedYValues))
9374 return;
9375 // get the data type for each column; we will have null type when dataPoints have different type or if a value is null
9376 var xDataType = getDataType(unsortedXValues);
9377 if (!xDataType)
9378 return;
9379 var yDataType = getDataType(unsortedYValues);
9380 if (!yDataType)
9381 return;
9382 var sortedDataPointSet = sortValues(unsortedXValues, unsortedYValues);
9383 var minCategoryValue = sortedDataPointSet.xValues[0];
9384 var maxCategoryValue = sortedDataPointSet.xValues[sortedDataPointSet.xValues.length - 1];
9385 var lineDef = computeRegressionLine(sortedDataPointSet.xValues, sortedDataPointSet.yValues);
9386 xMin = _.min([xMin, minCategoryValue]);
9387 xMax = _.max([xMax, maxCategoryValue]);
9388 lineDefs.push(lineDef);
9389 }
9390 return {
9391 lineDefs: lineDefs,
9392 xMin: xMin,
9393 xMax: xMax,
9394 };
9395 }
9396 function getColumnsForCartesianRoleKind(roleKind, categorical, roles) {
9397 debug.assertValue(roleKind, 'roleKind');
9398 debug.assertValue(categorical, 'categorical');
9399 var columns = getColumnsWithRoleKind(roleKind, categorical.values, roles);
9400 if (!_.isEmpty(columns))
9401 return columns;
9402 var categories = categorical.categories;
9403 if (_.isEmpty(categories))
9404 return;
9405 debug.assert(categories.length === 1, 'composite category columns not supported');
9406 var categoryColumn = categories[0];
9407 columns = getColumnsWithRoleKind(roleKind, [categoryColumn], roles);
9408 if (!_.isEmpty(columns))
9409 return columns;
9410 }
9411 function getColumnsWithRoleKind(roleKind, columns, roles) {
9412 if (_.isEmpty(columns))
9413 return;
9414 return _.filter(columns, function (column) {
9415 var _loop_1 = function(roleName) {
9416 if (!column.source.roles[roleName])
9417 return "continue";
9418 var role = _.find(roles, function (role) { return role.name === roleName; });
9419 if (role && role.cartesianKind === roleKind)
9420 return { value: true };
9421 };
9422 for (var roleName in column.source.roles) {
9423 var state_1 = _loop_1(roleName);
9424 if (typeof state_1 === "object") return state_1.value;
9425 if (state_1 === "continue") continue;
9426 }
9427 return false;
9428 });
9429 }
9430 function getDataType(values) {
9431 var firstNonNull = _.find(values, function (value) { return value != null; });
9432 if (firstNonNull == null)
9433 return;
9434 var dataType = typeof firstNonNull;
9435 if (_.some(values, function (value) { return value != null && typeof value !== dataType; }))
9436 return;
9437 return dataType;
9438 }
9439 function sortValues(unsortedXValues, unsortedYValues) {
9440 debug.assertValue(unsortedXValues, 'unsortedXValues');
9441 debug.assertValue(unsortedYValues, 'unsortedYValues');
9442 var zippedValues = _.zip(unsortedXValues, unsortedYValues);
9443 var _a = _.chain(zippedValues)
9444 .filter(function (valuePair) { return valuePair[0] != null && valuePair[1] != null; })
9445 .sortBy(function (valuePair) { return valuePair[0]; })
9446 .unzip()
9447 .value(), xValues = _a[0], yValues = _a[1];
9448 return {
9449 xValues: xValues,
9450 yValues: yValues
9451 };
9452 }
9453 /**
9454 * Computes a line definition using linear regression.
9455 * xBar: average of X values, yBar: average of Y values
9456 * ssXX: sum of squares of X values = Sum(xi - xBar)^2
9457 * ssXY: sum of squares of X and Y values = Sum((xi - xBar)(yi - yBar)
9458 * Slope: ssXY / ssXX
9459 * Intercept: yBar - xBar * slope
9460 */
9461 function computeRegressionLine(xValues, yValues) {
9462 debug.assertValue(xValues, 'xValues');
9463 debug.assertValue(yValues, 'yValues');
9464 var xBar = _.sum(xValues) / xValues.length;
9465 var yBar = _.sum(yValues) / yValues.length;
9466 var ssXX = _.chain(xValues)
9467 .map(function (x) {
9468 return Math.pow((x - xBar), 2);
9469 })
9470 .sum();
9471 var ssXY = _.chain(xValues)
9472 .map(function (x, i) {
9473 return (x - xBar) * (yValues[i] - yBar);
9474 })
9475 .sum();
9476 var slope = ssXY / ssXX;
9477 var intercept = yBar - (xBar * slope);
9478 return {
9479 slope: slope,
9480 intercept: intercept
9481 };
9482 }
9483 function computeLineYValues(lineDef, x1, x2) {
9484 return [x1 * lineDef.slope + lineDef.intercept, x2 * lineDef.slope + lineDef.intercept];
9485 }
9486 function getValuesFromColumn(column, preferHighlights) {
9487 if (preferHighlights) {
9488 // Attempt to use highlight values. When X is categorical, we may not have highlight values so we should fall back to the non-highlight values.
9489 var valueColumn = column;
9490 if (valueColumn.highlights) {
9491 return valueColumn.highlights;
9492 }
9493 }
9494 return column.values;
9495 }
9496 function getDataPointsBySeries(xColumns, yColumns, combineSeries, preferHighlights) {
9497 var dataPointsBySeries = [];
9498 var xValueArray = _.map(xColumns, function (column) { return getValuesFromColumn(column, preferHighlights); });
9499 var seriesYValues = _.map(yColumns, function (column) { return getValuesFromColumn(column, preferHighlights); });
9500 var multipleXValueColumns = xColumns.length > 1;
9501 for (var i = 0; i < seriesYValues.length; i++) {
9502 var xValues = multipleXValueColumns ? xValueArray[i] : xValueArray[0];
9503 var yValues = seriesYValues[i];
9504 if (combineSeries && dataPointsBySeries.length > 0) {
9505 dataPointsBySeries[0].xValues = dataPointsBySeries[0].xValues.concat(xValues);
9506 dataPointsBySeries[0].yValues = dataPointsBySeries[0].yValues.concat(yValues);
9507 }
9508 else {
9509 dataPointsBySeries.push({
9510 xValues: xValues,
9511 yValues: yValues,
9512 });
9513 }
9514 }
9515 return dataPointsBySeries;
9516 }
9517 function createRegressionDataView(xColumnSource, yColumnSource, groupValues, categories, values, highlights, sourceDataView, regressionDataViewMapping, objectDescriptors, objectDefinitions, colorAllocatorFactory) {
9518 debug.assertValue(xColumnSource, 'xColumnSource');
9519 debug.assertValue(yColumnSource, 'yColumnSource');
9520 debug.assertValue(categories, 'categories');
9521 debug.assertValue(values, 'values');
9522 debug.assertValue(sourceDataView, 'sourceDataView');
9523 debug.assertValue(objectDescriptors, 'objectDescriptors');
9524 debug.assertValue(objectDefinitions, 'objectDefinitions');
9525 debug.assertValue(colorAllocatorFactory, 'colorAllocatorFactory');
9526 debug.assertAnyValue(highlights, 'highlights');
9527 debug.assert(!highlights || highlights.length === values.length, 'highlights should have the same length as values');
9528 var xRole = regressionDataViewMapping.categorical.categories.for.in;
9529 var grouped = regressionDataViewMapping.categorical.values.group;
9530 var yRole;
9531 var seriesRole;
9532 if (grouped && !_.isEmpty(grouped.select)) {
9533 yRole = grouped.select[0].for ?
9534 grouped.select[0].for.in :
9535 grouped.select[0].bind.to;
9536 seriesRole = grouped.by;
9537 }
9538 if (!yRole || !seriesRole)
9539 return;
9540 var categoricalRoles = (_a = {}, _a[xRole] = true, _a);
9541 var valueRoles = (_b = {}, _b[yRole] = true, _b);
9542 var seriesRoles = (_c = {}, _c[seriesRole] = true, _c);
9543 var valuesBySeries = [];
9544 for (var index in values) {
9545 var seriesData = {
9546 values: values[index],
9547 };
9548 if (highlights)
9549 seriesData.highlights = highlights[index];
9550 valuesBySeries.push([seriesData]);
9551 }
9552 var regressionDataView = data.createCategoricalDataViewBuilder()
9553 .withCategory({
9554 source: {
9555 displayName: xColumnSource.displayName,
9556 queryName: regressionXQueryName,
9557 type: xColumnSource.type,
9558 isMeasure: false,
9559 roles: categoricalRoles
9560 },
9561 values: categories,
9562 identityFrom: {
9563 fields: [data.SQExprBuilder.columnRef(data.SQExprBuilder.entity('s', 'RegressionEntity'), 'RegressionCategories')],
9564 },
9565 })
9566 .withGroupedValues({
9567 groupColumn: {
9568 source: {
9569 displayName: yColumnSource.displayName + 'Regression',
9570 queryName: regressionSeriesQueryName,
9571 type: yColumnSource.type,
9572 isMeasure: yColumnSource.isMeasure,
9573 roles: seriesRoles
9574 },
9575 values: groupValues,
9576 identityFrom: {
9577 fields: [data.SQExprBuilder.columnRef(data.SQExprBuilder.entity('s', 'RegressionEntity'), 'RegressionSeries')],
9578 }
9579 },
9580 valueColumns: [{
9581 source: {
9582 displayName: yColumnSource.displayName,
9583 queryName: DataViewRegression.regressionYQueryName,
9584 type: yColumnSource.type,
9585 isMeasure: yColumnSource.isMeasure,
9586 roles: valueRoles
9587 },
9588 }],
9589 data: valuesBySeries
9590 })
9591 .build();
9592 data.DataViewTransform.transformObjects(regressionDataView, 1 /* Categorical */, objectDescriptors, objectDefinitions, [], colorAllocatorFactory);
9593 return regressionDataView;
9594 var _a, _b, _c;
9595 }
9596 function hasHighlightValues(columns) {
9597 return _.any(columns, function (column) {
9598 var valueColumn = column;
9599 return valueColumn.highlights != null;
9600 });
9601 }
9602 })(DataViewRegression = data.DataViewRegression || (data.DataViewRegression = {}));
9603 })(data = powerbi.data || (powerbi.data = {}));
9604})(powerbi || (powerbi = {}));
9605/*
9606 * Power BI Visualizations
9607 *
9608 * Copyright (c) Microsoft Corporation
9609 * All rights reserved.
9610 * MIT License
9611 *
9612 * Permission is hereby granted, free of charge, to any person obtaining a copy
9613 * of this software and associated documentation files (the ""Software""), to deal
9614 * in the Software without restriction, including without limitation the rights
9615 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9616 * copies of the Software, and to permit persons to whom the Software is
9617 * furnished to do so, subject to the following conditions:
9618 *
9619 * The above copyright notice and this permission notice shall be included in
9620 * all copies or substantial portions of the Software.
9621 *
9622 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9623 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9624 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9625 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9626 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9627 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9628 * THE SOFTWARE.
9629 */
9630var powerbi;
9631(function (powerbi) {
9632 var data;
9633 (function (data) {
9634 var DataViewSelectTransform;
9635 (function (DataViewSelectTransform) {
9636 /** Convert selection info to projections */
9637 function projectionsFromSelects(selects, projectionActiveItems) {
9638 debug.assertAnyValue(selects, "selects");
9639 debug.assertAnyValue(projectionActiveItems, "projectionActiveItems");
9640 var projections = {};
9641 for (var _i = 0, selects_1 = selects; _i < selects_1.length; _i++) {
9642 var select = selects_1[_i];
9643 var roles = select.roles;
9644 if (!roles)
9645 continue;
9646 for (var roleName in roles) {
9647 if (roles[roleName]) {
9648 var qp = projections[roleName];
9649 if (!qp)
9650 qp = projections[roleName] = new data.QueryProjectionCollection([]);
9651 qp.all().push({ queryRef: select.queryName });
9652 if (projectionActiveItems && projectionActiveItems[roleName])
9653 qp.activeProjectionRefs = _.map(projectionActiveItems[roleName], function (activeItem) { return activeItem.queryRef; });
9654 }
9655 }
9656 }
9657 return projections;
9658 }
9659 DataViewSelectTransform.projectionsFromSelects = projectionsFromSelects;
9660 /** Use selections and metadata to fashion query role kinds */
9661 function createRoleKindFromMetadata(selects, metadata) {
9662 var roleKindByQueryRef = {};
9663 for (var _i = 0, _a = metadata.columns; _i < _a.length; _i++) {
9664 var column = _a[_i];
9665 if ((!column.index && column.index !== 0) || column.index < 0 || column.index >= selects.length)
9666 continue;
9667 var select = selects[column.index];
9668 if (select) {
9669 var queryRef = select.queryName;
9670 if (queryRef && roleKindByQueryRef[queryRef] === undefined) {
9671 roleKindByQueryRef[queryRef] = column.isMeasure ? powerbi.VisualDataRoleKind.Measure : powerbi.VisualDataRoleKind.Grouping;
9672 }
9673 }
9674 }
9675 return roleKindByQueryRef;
9676 }
9677 DataViewSelectTransform.createRoleKindFromMetadata = createRoleKindFromMetadata;
9678 })(DataViewSelectTransform = data.DataViewSelectTransform || (data.DataViewSelectTransform = {}));
9679 })(data = powerbi.data || (powerbi.data = {}));
9680})(powerbi || (powerbi = {}));
9681/*
9682 * Power BI Visualizations
9683 *
9684 * Copyright (c) Microsoft Corporation
9685 * All rights reserved.
9686 * MIT License
9687 *
9688 * Permission is hereby granted, free of charge, to any person obtaining a copy
9689 * of this software and associated documentation files (the ""Software""), to deal
9690 * in the Software without restriction, including without limitation the rights
9691 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9692 * copies of the Software, and to permit persons to whom the Software is
9693 * furnished to do so, subject to the following conditions:
9694 *
9695 * The above copyright notice and this permission notice shall be included in
9696 * all copies or substantial portions of the Software.
9697 *
9698 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9699 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9700 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9701 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9702 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9703 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9704 * THE SOFTWARE.
9705 */
9706var powerbi;
9707(function (powerbi) {
9708 var data;
9709 (function (data) {
9710 function createCategoricalEvalContext(colorAllocatorProvider, dataViewCategorical) {
9711 return new CategoricalEvalContext(colorAllocatorProvider, dataViewCategorical);
9712 }
9713 data.createCategoricalEvalContext = createCategoricalEvalContext;
9714 var CategoricalEvalContext = (function () {
9715 function CategoricalEvalContext(colorAllocatorProvider, dataView) {
9716 debug.assertValue(colorAllocatorProvider, 'colorAllocatorProvider');
9717 debug.assertValue(dataView, 'dataView');
9718 this.colorAllocatorProvider = colorAllocatorProvider;
9719 this.dataView = dataView;
9720 this.columnsByRole = {};
9721 }
9722 CategoricalEvalContext.prototype.getColorAllocator = function (expr) {
9723 return this.colorAllocatorProvider.get(expr);
9724 };
9725 CategoricalEvalContext.prototype.getExprValue = function (expr) {
9726 return;
9727 };
9728 CategoricalEvalContext.prototype.getRoleValue = function (roleName) {
9729 var columnsByRole = this.columnsByRole;
9730 var column = columnsByRole[roleName];
9731 if (!column)
9732 column = columnsByRole[roleName] = findRuleInputColumn(this.dataView, roleName);
9733 if (!column)
9734 return;
9735 var index = this.index;
9736 if (index != null)
9737 return column.values[this.index];
9738 };
9739 CategoricalEvalContext.prototype.setCurrentRowIndex = function (index) {
9740 debug.assertValue(index, 'index');
9741 this.index = index;
9742 };
9743 return CategoricalEvalContext;
9744 }());
9745 function findRuleInputColumn(dataViewCategorical, inputRole) {
9746 debug.assertValue(dataViewCategorical, 'dataViewCategorical');
9747 return findRuleInputInColumns(dataViewCategorical.values, inputRole) ||
9748 findRuleInputInColumns(dataViewCategorical.categories, inputRole);
9749 }
9750 function findRuleInputInColumns(columns, inputRole) {
9751 debug.assertAnyValue(columns, 'columns');
9752 if (!columns)
9753 return;
9754 for (var _i = 0, columns_7 = columns; _i < columns_7.length; _i++) {
9755 var column = columns_7[_i];
9756 var roles = column.source.roles;
9757 if (!roles || !roles[inputRole])
9758 continue;
9759 return column;
9760 }
9761 }
9762 })(data = powerbi.data || (powerbi.data = {}));
9763})(powerbi || (powerbi = {}));
9764/*
9765 * Power BI Visualizations
9766 *
9767 * Copyright (c) Microsoft Corporation
9768 * All rights reserved.
9769 * MIT License
9770 *
9771 * Permission is hereby granted, free of charge, to any person obtaining a copy
9772 * of this software and associated documentation files (the ""Software""), to deal
9773 * in the Software without restriction, including without limitation the rights
9774 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9775 * copies of the Software, and to permit persons to whom the Software is
9776 * furnished to do so, subject to the following conditions:
9777 *
9778 * The above copyright notice and this permission notice shall be included in
9779 * all copies or substantial portions of the Software.
9780 *
9781 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9782 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9783 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9784 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9785 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9786 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9787 * THE SOFTWARE.
9788 */
9789var powerbi;
9790(function (powerbi) {
9791 var data;
9792 (function (data) {
9793 function createTableEvalContext(colorAllocatorProvider, dataViewTable, selectTransforms) {
9794 return new TableEvalContext(colorAllocatorProvider, dataViewTable, selectTransforms);
9795 }
9796 data.createTableEvalContext = createTableEvalContext;
9797 var TableEvalContext = (function () {
9798 function TableEvalContext(colorAllocatorProvider, dataView, selectTransforms) {
9799 debug.assertValue(colorAllocatorProvider, 'colorAllocatorProvider');
9800 debug.assertValue(dataView, 'dataView');
9801 debug.assertValue(selectTransforms, 'selectTransforms');
9802 this.colorAllocatorProvider = colorAllocatorProvider;
9803 this.dataView = dataView;
9804 this.selectTransforms = selectTransforms;
9805 }
9806 TableEvalContext.prototype.getColorAllocator = function (expr) {
9807 return this.colorAllocatorProvider.get(expr);
9808 };
9809 TableEvalContext.prototype.getExprValue = function (expr) {
9810 debug.assertValue(expr, 'expr');
9811 var rowIdx = this.rowIdx;
9812 if (rowIdx == null)
9813 return;
9814 return data.getExprValueFromTable(expr, this.selectTransforms, this.dataView, rowIdx);
9815 };
9816 TableEvalContext.prototype.getRoleValue = function (roleName) {
9817 return;
9818 };
9819 TableEvalContext.prototype.setCurrentRowIndex = function (index) {
9820 debug.assertValue(index, 'index');
9821 this.rowIdx = index;
9822 };
9823 return TableEvalContext;
9824 }());
9825 })(data = powerbi.data || (powerbi.data = {}));
9826})(powerbi || (powerbi = {}));
9827/*
9828 * Power BI Visualizations
9829 *
9830 * Copyright (c) Microsoft Corporation
9831 * All rights reserved.
9832 * MIT License
9833 *
9834 * Permission is hereby granted, free of charge, to any person obtaining a copy
9835 * of this software and associated documentation files (the ""Software""), to deal
9836 * in the Software without restriction, including without limitation the rights
9837 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9838 * copies of the Software, and to permit persons to whom the Software is
9839 * furnished to do so, subject to the following conditions:
9840 *
9841 * The above copyright notice and this permission notice shall be included in
9842 * all copies or substantial portions of the Software.
9843 *
9844 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9845 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9846 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9847 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9848 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9849 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9850 * THE SOFTWARE.
9851 */
9852var powerbi;
9853(function (powerbi) {
9854 var data;
9855 (function (data) {
9856 var RuleEvaluation = (function () {
9857 function RuleEvaluation() {
9858 }
9859 // NOTE: even though this class has no behaviour, we still use a class to facilitate instanceof checks.
9860 RuleEvaluation.prototype.evaluate = function (evalContext) {
9861 debug.assertFail('Abstract method RuleEvaluation.evaluate not implemented.');
9862 };
9863 return RuleEvaluation;
9864 }());
9865 data.RuleEvaluation = RuleEvaluation;
9866 })(data = powerbi.data || (powerbi.data = {}));
9867})(powerbi || (powerbi = {}));
9868/*
9869 * Power BI Visualizations
9870 *
9871 * Copyright (c) Microsoft Corporation
9872 * All rights reserved.
9873 * MIT License
9874 *
9875 * Permission is hereby granted, free of charge, to any person obtaining a copy
9876 * of this software and associated documentation files (the ""Software""), to deal
9877 * in the Software without restriction, including without limitation the rights
9878 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9879 * copies of the Software, and to permit persons to whom the Software is
9880 * furnished to do so, subject to the following conditions:
9881 *
9882 * The above copyright notice and this permission notice shall be included in
9883 * all copies or substantial portions of the Software.
9884 *
9885 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9886 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9887 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9888 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9889 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9890 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9891 * THE SOFTWARE.
9892 */
9893var powerbi;
9894(function (powerbi) {
9895 var data;
9896 (function (data) {
9897 var ColorRuleEvaluation = (function (_super) {
9898 __extends(ColorRuleEvaluation, _super);
9899 function ColorRuleEvaluation(inputRole, allocator) {
9900 debug.assertValue(inputRole, 'inputRole');
9901 debug.assertValue(allocator, 'allocator');
9902 _super.call(this);
9903 this.inputRole = inputRole;
9904 this.allocator = allocator;
9905 }
9906 ColorRuleEvaluation.prototype.evaluate = function (evalContext) {
9907 debug.assertValue(evalContext, 'evalContext');
9908 var value = evalContext.getRoleValue(this.inputRole);
9909 if (value !== undefined)
9910 return this.allocator.color(value);
9911 };
9912 return ColorRuleEvaluation;
9913 }(data.RuleEvaluation));
9914 data.ColorRuleEvaluation = ColorRuleEvaluation;
9915 })(data = powerbi.data || (powerbi.data = {}));
9916})(powerbi || (powerbi = {}));
9917/*
9918 * Power BI Visualizations
9919 *
9920 * Copyright (c) Microsoft Corporation
9921 * All rights reserved.
9922 * MIT License
9923 *
9924 * Permission is hereby granted, free of charge, to any person obtaining a copy
9925 * of this software and associated documentation files (the ""Software""), to deal
9926 * in the Software without restriction, including without limitation the rights
9927 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9928 * copies of the Software, and to permit persons to whom the Software is
9929 * furnished to do so, subject to the following conditions:
9930 *
9931 * The above copyright notice and this permission notice shall be included in
9932 * all copies or substantial portions of the Software.
9933 *
9934 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9935 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9936 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9937 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9938 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9939 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9940 * THE SOFTWARE.
9941 */
9942var powerbi;
9943(function (powerbi) {
9944 var data;
9945 (function (data) {
9946 var utils;
9947 (function (utils) {
9948 var inherit = powerbi.Prototype.inherit;
9949 var inheritSingle = powerbi.Prototype.inheritSingle;
9950 var ArrayExtensions = jsCommon.ArrayExtensions;
9951 var DataViewMatrixUtils;
9952 (function (DataViewMatrixUtils) {
9953 /**
9954 * Invokes the specified callback once per leaf nodes (including root-level leaves and descendent leaves) of the
9955 * specified rootNodes, with an optional index parameter in the callback that is the 0-based index of the
9956 * particular leaf node in the context of this forEachLeafNode(...) invocation.
9957 *
9958 * If rootNodes is null or undefined or empty, the specified callback will not get invoked.
9959 *
9960 * The treePath parameter in the callback is an ordered set of nodes that form the path from the specified
9961 * rootNodes down to the leafNode argument itself. If callback leafNode is one of the specified rootNodes,
9962 * then treePath will be an array of length 1 containing that very node.
9963 *
9964 * IMPORTANT: The treePath array passed to the callback will be modified after the callback function returns!
9965 * If your callback needs to retain a copy of the treePath, please clone the array before returning.
9966 */
9967 function forEachLeafNode(rootNodes, callback) {
9968 debug.assertAnyValue(rootNodes, 'rootNodes');
9969 debug.assertValue(callback, 'callback');
9970 // Note: Don't do "if (!_.isEmpty(rootNodes))" for checking whether rootNodes is an empty array DataViewMatrixNode[],
9971 // because rootNodes can also be an non-array DataViewMatrixNode, and an empty object can be a valid root node DataViewMatrixNode,
9972 // for the fact that all the properties on DataViewMatrixNode are optional...
9973 if (rootNodes) {
9974 if (isNodeArray(rootNodes)) {
9975 var index = 0;
9976 for (var _i = 0, rootNodes_1 = rootNodes; _i < rootNodes_1.length; _i++) {
9977 var rootNode = rootNodes_1[_i];
9978 if (rootNode) {
9979 index = forEachLeafNodeRecursive(rootNode, index, [], callback);
9980 }
9981 }
9982 }
9983 else {
9984 forEachLeafNodeRecursive(rootNodes, 0, [], callback);
9985 }
9986 }
9987 }
9988 DataViewMatrixUtils.forEachLeafNode = forEachLeafNode;
9989 function isNodeArray(nodeOrNodeArray) {
9990 return ArrayExtensions.isArrayOrInheritedArray(nodeOrNodeArray);
9991 }
9992 /**
9993 * Recursively traverses to each leaf node of the specified matrixNode and invokes callback with each of them.
9994 * Returns the index for the next node after the last node that this function invokes callback with.
9995 *
9996 * @treePath an array that contains the path from the specified rootNodes in forEachLeafNode() down to the parent of the argument matrixNode (i.e. treePath does not contain the matrixNode argument yet).
9997 */
9998 function forEachLeafNodeRecursive(matrixNode, nextIndex, treePath, callback) {
9999 debug.assertValue(matrixNode, 'matrixNode');
10000 debug.assertValue(treePath, 'treePath');
10001 debug.assertValue(callback, 'callback');
10002 // If treePath already contains matrixNode, then either one of the following errors has happened:
10003 // 1. the caller code mistakenly added matrixNode to treePath, or
10004 // 2. the callback modified treePath by adding a node to it, or
10005 // 3. the matrix hierarchy contains a cyclical node reference.');
10006 debug.assert(!_.contains(treePath, matrixNode), 'pre-condition: treePath must not already contain matrixNode');
10007 treePath.push(matrixNode);
10008 if (_.isEmpty(matrixNode.children)) {
10009 callback(matrixNode, nextIndex, treePath);
10010 nextIndex++;
10011 }
10012 else {
10013 var children = matrixNode.children;
10014 for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
10015 var nextChild = children_1[_i];
10016 if (nextChild) {
10017 nextIndex = forEachLeafNodeRecursive(nextChild, nextIndex, treePath, callback);
10018 }
10019 }
10020 }
10021 debug.assert(_.last(treePath) === matrixNode, 'pre-condition: the callback given to forEachLeafNode() is not supposed to modify the treePath argument array.');
10022 treePath.pop();
10023 return nextIndex;
10024 }
10025 /**
10026 * Returned an object tree where each node and its children property are inherited from the specified node
10027 * hierarchy, from the root down to the nodes at the specified deepestLevelToInherit, inclusively.
10028 *
10029 * The inherited nodes at level === deepestLevelToInherit will NOT get an inherited version of children array
10030 * property, i.e. its children property is the same array object referenced in the input node's object tree.
10031 *
10032 * @param node The input node with the hierarchy object tree.
10033 * @param deepestLevelToInherit The highest level for a node to get inherited. See DataViewMatrixNode.level property.
10034 * @param useInheritSingle If true, then a node will get inherited in the returned object tree only if it is
10035 * not already an inherited object. Same goes for the node's children property. This is useful for creating
10036 * "visual DataView" objects from "query DataView" objects, as object inheritance is the mechanism for
10037 * "visual DataView" to override properties in "query DataView", and that "query DataView" never contains
10038 * inherited objects.
10039 */
10040 function inheritMatrixNodeHierarchy(node, deepestLevelToInherit, useInheritSingle) {
10041 debug.assertValue(node, 'node');
10042 debug.assert(deepestLevelToInherit >= 0, 'deepestLevelToInherit >= 0');
10043 debug.assertValue(useInheritSingle, 'useInheritSingle');
10044 var returnNode = node;
10045 // Note: The level property of DataViewMatrix.rows.root and DataViewMatrix.columns.root are always undefined.
10046 // Also, in a matrix with multiple column grouping fields and multiple value fields, the DataViewMatrixNode
10047 // for the Grand Total column in the column hierarchy will have children nodes where level > (parent.level + 1):
10048 // {
10049 // "level": 0,
10050 // "isSubtotal": true,
10051 // "children": [
10052 // { "level": 2, "isSubtotal": true },
10053 // { "level": 2, "levelSourceIndex": 1, "isSubtotal": true }
10054 // ]
10055 // }
10056 var isRootNode = _.isUndefined(node.level);
10057 var shouldInheritCurrentNode = isRootNode || (node.level <= deepestLevelToInherit);
10058 if (shouldInheritCurrentNode) {
10059 var inheritFunc = useInheritSingle ? inheritSingle : inherit;
10060 var inheritedNode = inheritFunc(node);
10061 var shouldInheritChildNodes = isRootNode || (node.level < deepestLevelToInherit);
10062 if (shouldInheritChildNodes && !_.isEmpty(node.children)) {
10063 inheritedNode.children = inheritFunc(node.children); // first, make an inherited array
10064 for (var i = 0, ilen = inheritedNode.children.length; i < ilen; i++) {
10065 inheritedNode.children[i] =
10066 inheritMatrixNodeHierarchy(inheritedNode.children[i], deepestLevelToInherit, useInheritSingle);
10067 }
10068 }
10069 returnNode = inheritedNode;
10070 }
10071 return returnNode;
10072 }
10073 DataViewMatrixUtils.inheritMatrixNodeHierarchy = inheritMatrixNodeHierarchy;
10074 /**
10075 * Returns true if the specified matrixOrHierarchy contains any composite grouping, i.e. a grouping on multiple columns.
10076 * An example of composite grouping is one on [Year, Quarter, Month], where a particular group instance can have
10077 * Year === 2016, Quarter === 'Qtr 1', Month === 1.
10078 *
10079 * Returns false if the specified matrixOrHierarchy does not contain any composite group,
10080 * or if matrixOrHierarchy is null or undefined.
10081 */
10082 function containsCompositeGroup(matrixOrHierarchy) {
10083 debug.assertAnyValue(matrixOrHierarchy, 'matrixOrHierarchy');
10084 var hasCompositeGroup = false;
10085 if (matrixOrHierarchy) {
10086 if (isMatrix(matrixOrHierarchy)) {
10087 hasCompositeGroup = containsCompositeGroup(matrixOrHierarchy.rows) ||
10088 containsCompositeGroup(matrixOrHierarchy.columns);
10089 }
10090 else {
10091 var hierarchyLevels = matrixOrHierarchy.levels;
10092 if (!_.isEmpty(hierarchyLevels)) {
10093 for (var _i = 0, hierarchyLevels_1 = hierarchyLevels; _i < hierarchyLevels_1.length; _i++) {
10094 var level = hierarchyLevels_1[_i];
10095 // it takes at least 2 columns at the same hierarchy level to form a composite group...
10096 if (level.sources && (level.sources.length >= 2)) {
10097 debug.assert(_.all(level.sources, function (sourceColumn) { return sourceColumn.isMeasure === level.sources[0].isMeasure; }), 'pre-condition: in a valid DataViewMatrix, the source columns in each of its hierarchy levels must either be all non-measure columns (i.e. a grouping level) or all measure columns (i.e. a measure headers level)');
10098 // Measure headers are not group
10099 var isMeasureHeadersLevel = level.sources[0].isMeasure;
10100 if (!isMeasureHeadersLevel) {
10101 hasCompositeGroup = true;
10102 break;
10103 }
10104 }
10105 }
10106 }
10107 }
10108 }
10109 return hasCompositeGroup;
10110 }
10111 DataViewMatrixUtils.containsCompositeGroup = containsCompositeGroup;
10112 function isMatrix(matrixOrHierarchy) {
10113 return 'rows' in matrixOrHierarchy &&
10114 'columns' in matrixOrHierarchy &&
10115 'valueSources' in matrixOrHierarchy;
10116 }
10117 })(DataViewMatrixUtils = utils.DataViewMatrixUtils || (utils.DataViewMatrixUtils = {}));
10118 })(utils = data.utils || (data.utils = {}));
10119 })(data = powerbi.data || (powerbi.data = {}));
10120})(powerbi || (powerbi = {}));
10121/*
10122 * Power BI Visualizations
10123 *
10124 * Copyright (c) Microsoft Corporation
10125 * All rights reserved.
10126 * MIT License
10127 *
10128 * Permission is hereby granted, free of charge, to any person obtaining a copy
10129 * of this software and associated documentation files (the ""Software""), to deal
10130 * in the Software without restriction, including without limitation the rights
10131 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10132 * copies of the Software, and to permit persons to whom the Software is
10133 * furnished to do so, subject to the following conditions:
10134 *
10135 * The above copyright notice and this permission notice shall be included in
10136 * all copies or substantial portions of the Software.
10137 *
10138 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10139 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10140 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10141 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10142 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10143 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10144 * THE SOFTWARE.
10145 */
10146var powerbi;
10147(function (powerbi) {
10148 var data;
10149 (function (data) {
10150 var utils;
10151 (function (utils) {
10152 var DataViewMetadataColumnUtils;
10153 (function (DataViewMetadataColumnUtils) {
10154 /**
10155 * Returns true iff the specified metadataColumn is assigned to the specified targetRole.
10156 */
10157 function isForRole(metadataColumn, targetRole) {
10158 debug.assertValue(metadataColumn, 'metadataColumn');
10159 debug.assertValue(targetRole, 'targetRole');
10160 var roles = metadataColumn.roles;
10161 return roles && roles[targetRole];
10162 }
10163 DataViewMetadataColumnUtils.isForRole = isForRole;
10164 /**
10165 * Joins each column in the specified columnSources with projection ordering index into a wrapper object.
10166 *
10167 * Note: In order for this function to reliably calculate the "source index" of a particular column, the
10168 * specified columnSources must be a non-filtered array of column sources from the DataView, such as
10169 * the DataViewHierarchyLevel.sources and DataViewMatrix.valueSources array properties.
10170 *
10171 * @param columnSources E.g. DataViewHierarchyLevel.sources, DataViewMatrix.valueSources...
10172 * @param projection The projection ordering. It must contain an ordering for the specified role.
10173 * @param role The role for getting the relevant projection ordering, as well as for filtering out the irrevalent columns in columnSources.
10174 */
10175 function joinMetadataColumnsAndProjectionOrder(columnSources, projection, role) {
10176 debug.assertAnyValue(columnSources, 'columnSources');
10177 debug.assert(_.all(columnSources, function (column) { return _.isNumber(column.index); }), 'pre-condition: Every value in columnSources must already have its Select Index property initialized.');
10178 debug.assertNonEmpty(projection[role], 'projection[role]');
10179 debug.assert(_.all(columnSources, function (column) { return !isForRole(column, role) || _.contains(projection[role], column.index); }), 'pre-condition: The projection order for the specified role must contain the Select Index of every column with matching role in the specified columnSources.');
10180 var jointResult = [];
10181 if (!_.isEmpty(columnSources)) {
10182 var projectionOrderSelectIndices = projection[role];
10183 var selectIndexToProjectionIndexMap = {};
10184 for (var i = 0, ilen = projectionOrderSelectIndices.length; i < ilen; i++) {
10185 var selectIndex = projectionOrderSelectIndices[i];
10186 selectIndexToProjectionIndexMap[selectIndex] = i;
10187 }
10188 for (var j = 0, jlen = columnSources.length; j < jlen; j++) {
10189 var column = columnSources[j];
10190 if (isForRole(column, role)) {
10191 var jointColumnInfo = {
10192 metadataColumn: column,
10193 sourceIndex: j,
10194 projectionOrderIndex: selectIndexToProjectionIndexMap[column.index]
10195 };
10196 jointResult.push(jointColumnInfo);
10197 }
10198 }
10199 }
10200 return jointResult;
10201 }
10202 DataViewMetadataColumnUtils.joinMetadataColumnsAndProjectionOrder = joinMetadataColumnsAndProjectionOrder;
10203 })(DataViewMetadataColumnUtils = utils.DataViewMetadataColumnUtils || (utils.DataViewMetadataColumnUtils = {}));
10204 })(utils = data.utils || (data.utils = {}));
10205 })(data = powerbi.data || (powerbi.data = {}));
10206})(powerbi || (powerbi = {}));
10207/*
10208 * Power BI Visualizations
10209 *
10210 * Copyright (c) Microsoft Corporation
10211 * All rights reserved.
10212 * MIT License
10213 *
10214 * Permission is hereby granted, free of charge, to any person obtaining a copy
10215 * of this software and associated documentation files (the ""Software""), to deal
10216 * in the Software without restriction, including without limitation the rights
10217 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10218 * copies of the Software, and to permit persons to whom the Software is
10219 * furnished to do so, subject to the following conditions:
10220 *
10221 * The above copyright notice and this permission notice shall be included in
10222 * all copies or substantial portions of the Software.
10223 *
10224 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10225 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10226 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10227 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10228 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10229 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10230 * THE SOFTWARE.
10231 */
10232var powerbi;
10233(function (powerbi) {
10234 var data;
10235 (function (data) {
10236 var ConceptualSchema = (function () {
10237 function ConceptualSchema() {
10238 }
10239 ConceptualSchema.prototype.findProperty = function (entityName, propertyName) {
10240 var entity = this.entities.withName(entityName);
10241 if (!entity || _.isEmpty(entity.properties))
10242 return;
10243 return entity.properties.withName(propertyName);
10244 };
10245 ConceptualSchema.prototype.findHierarchy = function (entityName, name) {
10246 var entity = this.entities.withName(entityName);
10247 if (!entity || _.isEmpty(entity.hierarchies))
10248 return;
10249 return entity.hierarchies.withName(name);
10250 };
10251 ConceptualSchema.prototype.findHierarchyByVariation = function (variationEntityName, variationColumnName, variationName, hierarchyName) {
10252 var variationEntity = this.entities.withName(variationEntityName);
10253 if (!variationEntity || _.isEmpty(variationEntity.properties))
10254 return;
10255 var variationProperty = variationEntity.properties.withName(variationColumnName);
10256 if (!variationProperty)
10257 return;
10258 var variationColumn = variationProperty.column;
10259 if (!variationColumn || _.isEmpty(variationColumn.variations))
10260 return;
10261 var variation = variationColumn.variations.withName(variationName);
10262 if (variation) {
10263 var targetEntity = variation.navigationProperty ? variation.navigationProperty.targetEntity : variationEntity;
10264 if (!targetEntity || _.isEmpty(targetEntity.hierarchies))
10265 return;
10266 return targetEntity.hierarchies.withName(hierarchyName);
10267 }
10268 };
10269 /**
10270 * Returns the first property of the entity whose kpi is tied to kpiProperty
10271 */
10272 ConceptualSchema.prototype.findPropertyWithKpi = function (entityName, kpiProperty) {
10273 debug.assertValue(kpiProperty, 'kpiProperty');
10274 var entity = this.entities.withName(entityName);
10275 if (!entity || _.isEmpty(entity.properties))
10276 return;
10277 for (var _i = 0, _a = entity.properties; _i < _a.length; _i++) {
10278 var prop = _a[_i];
10279 if (prop &&
10280 prop.measure &&
10281 prop.measure.kpi &&
10282 (prop.measure.kpi.status === kpiProperty || prop.measure.kpi.goal === kpiProperty))
10283 return prop;
10284 }
10285 return;
10286 };
10287 return ConceptualSchema;
10288 }());
10289 data.ConceptualSchema = ConceptualSchema;
10290 // TODO: Remove this (replaced by ValueType)
10291 (function (ConceptualDataCategory) {
10292 ConceptualDataCategory[ConceptualDataCategory["None"] = 0] = "None";
10293 ConceptualDataCategory[ConceptualDataCategory["Address"] = 1] = "Address";
10294 ConceptualDataCategory[ConceptualDataCategory["City"] = 2] = "City";
10295 ConceptualDataCategory[ConceptualDataCategory["Company"] = 3] = "Company";
10296 ConceptualDataCategory[ConceptualDataCategory["Continent"] = 4] = "Continent";
10297 ConceptualDataCategory[ConceptualDataCategory["Country"] = 5] = "Country";
10298 ConceptualDataCategory[ConceptualDataCategory["County"] = 6] = "County";
10299 ConceptualDataCategory[ConceptualDataCategory["Date"] = 7] = "Date";
10300 ConceptualDataCategory[ConceptualDataCategory["Image"] = 8] = "Image";
10301 ConceptualDataCategory[ConceptualDataCategory["ImageUrl"] = 9] = "ImageUrl";
10302 ConceptualDataCategory[ConceptualDataCategory["Latitude"] = 10] = "Latitude";
10303 ConceptualDataCategory[ConceptualDataCategory["Longitude"] = 11] = "Longitude";
10304 ConceptualDataCategory[ConceptualDataCategory["Organization"] = 12] = "Organization";
10305 ConceptualDataCategory[ConceptualDataCategory["Place"] = 13] = "Place";
10306 ConceptualDataCategory[ConceptualDataCategory["PostalCode"] = 14] = "PostalCode";
10307 ConceptualDataCategory[ConceptualDataCategory["Product"] = 15] = "Product";
10308 ConceptualDataCategory[ConceptualDataCategory["StateOrProvince"] = 16] = "StateOrProvince";
10309 ConceptualDataCategory[ConceptualDataCategory["WebUrl"] = 17] = "WebUrl";
10310 })(data.ConceptualDataCategory || (data.ConceptualDataCategory = {}));
10311 var ConceptualDataCategory = data.ConceptualDataCategory;
10312 })(data = powerbi.data || (powerbi.data = {}));
10313})(powerbi || (powerbi = {}));
10314/*
10315 * Power BI Visualizations
10316 *
10317 * Copyright (c) Microsoft Corporation
10318 * All rights reserved.
10319 * MIT License
10320 *
10321 * Permission is hereby granted, free of charge, to any person obtaining a copy
10322 * of this software and associated documentation files (the ""Software""), to deal
10323 * in the Software without restriction, including without limitation the rights
10324 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10325 * copies of the Software, and to permit persons to whom the Software is
10326 * furnished to do so, subject to the following conditions:
10327 *
10328 * The above copyright notice and this permission notice shall be included in
10329 * all copies or substantial portions of the Software.
10330 *
10331 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10332 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10333 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10334 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10335 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10336 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10337 * THE SOFTWARE.
10338 */
10339var powerbi;
10340(function (powerbi) {
10341 var StringExtensions = jsCommon.StringExtensions;
10342 var FieldExprPattern = powerbi.data.FieldExprPattern;
10343 var ScriptResultUtil;
10344 (function (ScriptResultUtil) {
10345 function findScriptResult(dataViewMappings) {
10346 if (dataViewMappings && dataViewMappings.length === 1) {
10347 return dataViewMappings[0].scriptResult;
10348 }
10349 return undefined;
10350 }
10351 ScriptResultUtil.findScriptResult = findScriptResult;
10352 function extractScriptResult(dataViewMappings) {
10353 var scriptResult = findScriptResult(dataViewMappings);
10354 if (scriptResult) {
10355 var objects = dataViewMappings[0].metadata.objects;
10356 var source = powerbi.DataViewObjects.getValue(objects, scriptResult.script.source);
10357 var provider = powerbi.DataViewObjects.getValue(objects, scriptResult.script.provider);
10358 return {
10359 source: source,
10360 provider: provider
10361 };
10362 }
10363 return undefined;
10364 }
10365 ScriptResultUtil.extractScriptResult = extractScriptResult;
10366 function extractScriptResultFromVisualConfig(dataViewMappings, objects) {
10367 var scriptResult = findScriptResult(dataViewMappings);
10368 if (scriptResult && objects) {
10369 var scriptSource = powerbi.data.DataViewObjectDefinitions.getValue(objects, scriptResult.script.source, null);
10370 var provider = powerbi.data.DataViewObjectDefinitions.getValue(objects, scriptResult.script.provider, null);
10371 return {
10372 source: scriptSource ? scriptSource.value : null,
10373 provider: provider ? provider.value : null
10374 };
10375 }
10376 return undefined;
10377 }
10378 ScriptResultUtil.extractScriptResultFromVisualConfig = extractScriptResultFromVisualConfig;
10379 function getScriptInput(projections, selects, schema) {
10380 var scriptInput = {
10381 VariableName: "dataset",
10382 Columns: []
10383 };
10384 // Go over all the projections, and create an input column according to the order
10385 // of the projections (including duplicate expressions)
10386 if (projections && selects && !_.isEmpty(selects)) {
10387 var scriptInputColumnNames = [];
10388 var scriptInputColumns = [];
10389 for (var role in projections) {
10390 for (var _i = 0, _a = projections[role].all(); _i < _a.length; _i++) {
10391 var projection = _a[_i];
10392 var select = selects.withName(projection.queryRef);
10393 if (select) {
10394 var scriptInputColumn = {
10395 QueryName: select.name,
10396 Name: FieldExprPattern.visit(select.expr, new ScriptInputColumnNameVisitor(schema))
10397 };
10398 scriptInputColumns.push(scriptInputColumn);
10399 scriptInputColumnNames.push(scriptInputColumn.Name);
10400 }
10401 }
10402 }
10403 // Make sure the names of the columns are unique
10404 scriptInputColumnNames = StringExtensions.ensureUniqueNames(scriptInputColumnNames);
10405 // Update the names of the columns
10406 for (var i = 0; i < scriptInputColumnNames.length; i++) {
10407 var scriptInputColumn = scriptInputColumns[i];
10408 scriptInputColumn.Name = scriptInputColumnNames[i];
10409 }
10410 scriptInput.Columns = scriptInputColumns;
10411 }
10412 return scriptInput;
10413 }
10414 ScriptResultUtil.getScriptInput = getScriptInput;
10415 var ScriptInputColumnNameVisitor = (function () {
10416 function ScriptInputColumnNameVisitor(federatedSchema) {
10417 this.federatedSchema = federatedSchema;
10418 }
10419 ScriptInputColumnNameVisitor.prototype.visitColumn = function (column) {
10420 return ScriptInputColumnNameVisitor.getNameForProperty(column, this.federatedSchema);
10421 };
10422 ScriptInputColumnNameVisitor.prototype.visitColumnAggr = function (columnAggr) {
10423 return ScriptInputColumnNameVisitor.getNameForProperty(columnAggr, this.federatedSchema);
10424 };
10425 ScriptInputColumnNameVisitor.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
10426 return ScriptInputColumnNameVisitor.getVariationLevelName(columnHierarchyLevelVariation, this.federatedSchema);
10427 };
10428 ScriptInputColumnNameVisitor.prototype.visitEntity = function (entity) {
10429 return entity.entity;
10430 };
10431 ScriptInputColumnNameVisitor.prototype.visitEntityAggr = function (entityAggr) {
10432 return entityAggr.entity;
10433 };
10434 ScriptInputColumnNameVisitor.prototype.visitHierarchy = function (hierarchy) {
10435 return ScriptInputColumnNameVisitor.getNameForHierarchy(hierarchy, this.federatedSchema);
10436 };
10437 ScriptInputColumnNameVisitor.prototype.visitHierarchyLevel = function (hierarchyLevel) {
10438 /*Hierarchy levels are not supported yet*/
10439 return;
10440 };
10441 ScriptInputColumnNameVisitor.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
10442 return ScriptInputColumnNameVisitor.getNameForProperty(hierarchyLevelAggr, this.federatedSchema);
10443 };
10444 ScriptInputColumnNameVisitor.prototype.visitMeasure = function (measure) {
10445 return ScriptInputColumnNameVisitor.getNameForProperty(measure, this.federatedSchema);
10446 };
10447 ScriptInputColumnNameVisitor.prototype.visitSelectRef = function (selectRef) {
10448 return FieldExprPattern.visit(selectRef, this);
10449 };
10450 ScriptInputColumnNameVisitor.prototype.visitPercentile = function (percentile) {
10451 return FieldExprPattern.visit(percentile.arg, this);
10452 };
10453 ScriptInputColumnNameVisitor.prototype.visitPercentOfGrandTotal = function (percentOfGrandTotal) {
10454 return FieldExprPattern.visit(percentOfGrandTotal.baseExpr, this);
10455 };
10456 ScriptInputColumnNameVisitor.getNameForHierarchy = function (pattern, federatedScheam) {
10457 debug.assertValue(pattern, 'pattern');
10458 var schema = federatedScheam.schema(pattern.schema), hierarchy = schema.findHierarchy(pattern.entity, pattern.name);
10459 if (hierarchy)
10460 return hierarchy.name;
10461 };
10462 ScriptInputColumnNameVisitor.getNameForProperty = function (pattern, federatedSchema) {
10463 debug.assertValue(pattern, 'pattern');
10464 var schema = federatedSchema.schema(pattern.schema), property = schema.findProperty(pattern.entity, pattern.name);
10465 if (property)
10466 return property.name;
10467 };
10468 ScriptInputColumnNameVisitor.getVariationLevelName = function (pattern, federatedSchema) {
10469 debug.assertValue(pattern, 'pattern');
10470 var source = pattern.source;
10471 var prop = federatedSchema.schema(source.schema).findProperty(source.entity, source.name);
10472 if (!prop)
10473 return;
10474 var variations = prop.column.variations;
10475 for (var _i = 0, variations_1 = variations; _i < variations_1.length; _i++) {
10476 var variation = variations_1[_i];
10477 if (variation.name === pattern.variationName)
10478 for (var _a = 0, _b = variation.defaultHierarchy.levels; _a < _b.length; _a++) {
10479 var level = _b[_a];
10480 if (level.name === pattern.level.level)
10481 return level.column.name;
10482 }
10483 }
10484 };
10485 return ScriptInputColumnNameVisitor;
10486 }());
10487 })(ScriptResultUtil = powerbi.ScriptResultUtil || (powerbi.ScriptResultUtil = {}));
10488})(powerbi || (powerbi = {}));
10489/*
10490 * Power BI Visualizations
10491 *
10492 * Copyright (c) Microsoft Corporation
10493 * All rights reserved.
10494 * MIT License
10495 *
10496 * Permission is hereby granted, free of charge, to any person obtaining a copy
10497 * of this software and associated documentation files (the ""Software""), to deal
10498 * in the Software without restriction, including without limitation the rights
10499 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10500 * copies of the Software, and to permit persons to whom the Software is
10501 * furnished to do so, subject to the following conditions:
10502 *
10503 * The above copyright notice and this permission notice shall be included in
10504 * all copies or substantial portions of the Software.
10505 *
10506 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10507 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10508 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10509 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10510 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10511 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10512 * THE SOFTWARE.
10513 */
10514var powerbi;
10515(function (powerbi) {
10516 var data;
10517 (function (data) {
10518 var segmentation;
10519 (function (segmentation) {
10520 var DataViewMerger;
10521 (function (DataViewMerger) {
10522 function mergeDataViews(source, segment) {
10523 if (!powerbi.DataViewAnalysis.isMetadataEquivalent(source.metadata, segment.metadata)) {
10524 debug.assertFail("Cannot merge data views with different metadata columns");
10525 }
10526 // The last segment is complete. We mark the source as complete.
10527 if (!segment.metadata.segment)
10528 delete source.metadata.segment;
10529 if (source.table && segment.table)
10530 mergeTables(source.table, segment.table);
10531 if (source.categorical && segment.categorical)
10532 mergeCategorical(source.categorical, segment.categorical);
10533 // Tree cannot support subtotals hence we can get into situations
10534 // where a node has no children in one segment and more than 1 child
10535 // in another segment.
10536 if (source.tree && segment.tree)
10537 mergeTreeNodes(source.tree.root, segment.tree.root, true /*allowDifferentStructure*/);
10538 if (source.matrix && segment.matrix)
10539 mergeTreeNodes(source.matrix.rows.root, segment.matrix.rows.root, false /*allowDifferentStructure*/);
10540 }
10541 DataViewMerger.mergeDataViews = mergeDataViews;
10542 /** Note: Public for testability */
10543 function mergeTables(source, segment) {
10544 debug.assertValue(source, 'source');
10545 debug.assertValue(segment, 'segment');
10546 if (_.isEmpty(segment.rows))
10547 return;
10548 var mergeIndex = segment.lastMergeIndex + 1;
10549 merge(source.rows, segment.rows, mergeIndex);
10550 debug.assert(!source.identity === !segment.identity, 'The existence of identity in the new segment is different than the source');
10551 if (segment.identity)
10552 merge(source.identity, segment.identity, mergeIndex);
10553 }
10554 DataViewMerger.mergeTables = mergeTables;
10555 /**
10556 * Merge categories values and identities
10557 *
10558 * Note: Public for testability
10559 */
10560 function mergeCategorical(source, segment) {
10561 debug.assertValue(source, 'source');
10562 debug.assertValue(segment, 'segment');
10563 // Merge categories values and identities
10564 if (source.categories && segment.categories) {
10565 var segmentCategoriesLength = segment.categories.length;
10566 debug.assert(source.categories.length === segmentCategoriesLength, "Source and segment categories have different lengths.");
10567 for (var categoryIndex = 0; categoryIndex < segmentCategoriesLength; categoryIndex++) {
10568 var segmentCategory = segment.categories[categoryIndex];
10569 var sourceCategory = source.categories[categoryIndex];
10570 debug.assert(powerbi.DataViewAnalysis.areMetadataColumnsEquivalent(sourceCategory.source, segmentCategory.source), "Source and segment category have different sources.");
10571 debug.assert(_.isUndefined(sourceCategory.values) ? _.isUndefined(sourceCategory.identity) : true, 'Source category is missing values but has identities.');
10572 var mergeIndex = segment.lastMergeIndex + 1;
10573 if (segmentCategory.values) {
10574 merge(sourceCategory.values, segmentCategory.values, mergeIndex);
10575 }
10576 if (segmentCategory.identity) {
10577 merge(sourceCategory.identity, segmentCategory.identity, mergeIndex);
10578 }
10579 }
10580 }
10581 // Merge values for each value column
10582 if (source.values && segment.values) {
10583 var segmentValuesLength = segment.values.length;
10584 debug.assert(source.values.length === segmentValuesLength, "Source and segment values have different lengths.");
10585 for (var valueIndex = 0; valueIndex < segmentValuesLength; valueIndex++) {
10586 var segmentValue = segment.values[valueIndex];
10587 var sourceValue = source.values[valueIndex];
10588 debug.assert(powerbi.DataViewAnalysis.areMetadataColumnsEquivalent(sourceValue.source, segmentValue.source), "Source and segment value have different sources.");
10589 if (!sourceValue.values && segmentValue.values) {
10590 sourceValue.values = [];
10591 }
10592 var mergeIndex = segment.lastMergeIndex + 1;
10593 if (segmentValue.values) {
10594 merge(sourceValue.values, segmentValue.values, mergeIndex);
10595 }
10596 if (segmentValue.highlights) {
10597 merge(sourceValue.highlights, segmentValue.highlights, mergeIndex);
10598 }
10599 }
10600 }
10601 }
10602 DataViewMerger.mergeCategorical = mergeCategorical;
10603 /**
10604 * Merges the segment array starting at the specified index into the source array
10605 * and returns the segment slice that wasn't merged.
10606 * The segment array is spliced up to specified index in the process.
10607 */
10608 function merge(source, segment, index) {
10609 if (index >= segment.length)
10610 return segment;
10611 var result = [];
10612 if (index !== undefined)
10613 result = segment.splice(0, index);
10614 Array.prototype.push.apply(source, segment);
10615 return result;
10616 }
10617 /** Note: Public for testability */
10618 function mergeTreeNodes(sourceRoot, segmentRoot, allowDifferentStructure) {
10619 debug.assertValue(sourceRoot, 'sourceRoot');
10620 debug.assertValue(segmentRoot, 'segmentRoot');
10621 if (!segmentRoot.children || segmentRoot.children.length === 0)
10622 return;
10623 if (allowDifferentStructure && (!sourceRoot.children || sourceRoot.children.length === 0)) {
10624 sourceRoot.children = segmentRoot.children;
10625 return;
10626 }
10627 debug.assert(sourceRoot.children && sourceRoot.children.length >= 0, "Source tree has different structure than segment.");
10628 var firstAppendIndex = findFirstAppendIndex(segmentRoot.children);
10629 var lastSourceChild = sourceRoot.children[sourceRoot.children.length - 1];
10630 var mergedChildren = merge(sourceRoot.children, segmentRoot.children, firstAppendIndex);
10631 if (mergedChildren.length > 0)
10632 mergeTreeNodes(lastSourceChild, mergedChildren[mergedChildren.length - 1], allowDifferentStructure);
10633 }
10634 DataViewMerger.mergeTreeNodes = mergeTreeNodes;
10635 function findFirstAppendIndex(children) {
10636 if (children.length === 0)
10637 return 0;
10638 var i = 0;
10639 for (; i < children.length; i++) {
10640 var childSegment = children[i];
10641 if (!childSegment.isMerge)
10642 break;
10643 }
10644 return i;
10645 }
10646 })(DataViewMerger = segmentation.DataViewMerger || (segmentation.DataViewMerger = {}));
10647 })(segmentation = data.segmentation || (data.segmentation = {}));
10648 })(data = powerbi.data || (powerbi.data = {}));
10649})(powerbi || (powerbi = {}));
10650/*
10651 * Power BI Visualizations
10652 *
10653 * Copyright (c) Microsoft Corporation
10654 * All rights reserved.
10655 * MIT License
10656 *
10657 * Permission is hereby granted, free of charge, to any person obtaining a copy
10658 * of this software and associated documentation files (the ""Software""), to deal
10659 * in the Software without restriction, including without limitation the rights
10660 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10661 * copies of the Software, and to permit persons to whom the Software is
10662 * furnished to do so, subject to the following conditions:
10663 *
10664 * The above copyright notice and this permission notice shall be included in
10665 * all copies or substantial portions of the Software.
10666 *
10667 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10668 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10669 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10670 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10671 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10672 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10673 * THE SOFTWARE.
10674 */
10675var powerbi;
10676(function (powerbi) {
10677 var data;
10678 (function (data) {
10679 var ArrayExtensions = jsCommon.ArrayExtensions;
10680 /** Rewrites an expression tree, including all descendant nodes. */
10681 var SQExprRewriter = (function () {
10682 function SQExprRewriter() {
10683 }
10684 SQExprRewriter.prototype.visitColumnRef = function (expr) {
10685 var origArg = expr.source, rewrittenArg = origArg.accept(this);
10686 if (origArg === rewrittenArg)
10687 return expr;
10688 return new data.SQColumnRefExpr(rewrittenArg, expr.ref);
10689 };
10690 SQExprRewriter.prototype.visitMeasureRef = function (expr) {
10691 var origArg = expr.source, rewrittenArg = origArg.accept(this);
10692 if (origArg === rewrittenArg)
10693 return expr;
10694 return new data.SQMeasureRefExpr(rewrittenArg, expr.ref);
10695 };
10696 SQExprRewriter.prototype.visitAggr = function (expr) {
10697 var origArg = expr.arg, rewrittenArg = origArg.accept(this);
10698 if (origArg === rewrittenArg)
10699 return expr;
10700 return new data.SQAggregationExpr(rewrittenArg, expr.func);
10701 };
10702 SQExprRewriter.prototype.visitSelectRef = function (expr) {
10703 return expr;
10704 };
10705 SQExprRewriter.prototype.visitPercentile = function (expr) {
10706 var origArg = expr.arg, rewrittenArg = origArg.accept(this);
10707 if (origArg === rewrittenArg)
10708 return expr;
10709 return new data.SQPercentileExpr(rewrittenArg, expr.k, expr.exclusive);
10710 };
10711 SQExprRewriter.prototype.visitHierarchy = function (expr) {
10712 var origArg = expr.arg, rewrittenArg = origArg.accept(this);
10713 if (origArg === rewrittenArg)
10714 return expr;
10715 return new data.SQHierarchyExpr(rewrittenArg, expr.hierarchy);
10716 };
10717 SQExprRewriter.prototype.visitHierarchyLevel = function (expr) {
10718 var origArg = expr.arg, rewrittenArg = origArg.accept(this);
10719 if (origArg === rewrittenArg)
10720 return expr;
10721 return new data.SQHierarchyLevelExpr(rewrittenArg, expr.level);
10722 };
10723 SQExprRewriter.prototype.visitPropertyVariationSource = function (expr) {
10724 var origArg = expr.arg, rewrittenArg = origArg.accept(this);
10725 if (origArg === rewrittenArg)
10726 return expr;
10727 return new data.SQPropertyVariationSourceExpr(rewrittenArg, expr.name, expr.property);
10728 };
10729 SQExprRewriter.prototype.visitEntity = function (expr) {
10730 return expr;
10731 };
10732 SQExprRewriter.prototype.visitAnd = function (orig) {
10733 var origLeft = orig.left, rewrittenLeft = origLeft.accept(this), origRight = orig.right, rewrittenRight = origRight.accept(this);
10734 if (origLeft === rewrittenLeft && origRight === rewrittenRight)
10735 return orig;
10736 return new data.SQAndExpr(rewrittenLeft, rewrittenRight);
10737 };
10738 SQExprRewriter.prototype.visitBetween = function (orig) {
10739 var origArg = orig.arg, rewrittenArg = origArg.accept(this), origLower = orig.lower, rewrittenLower = origLower.accept(this), origUpper = orig.upper, rewrittenUpper = origUpper.accept(this);
10740 if (origArg === rewrittenArg && origLower === rewrittenLower && origUpper === rewrittenUpper)
10741 return orig;
10742 return new data.SQBetweenExpr(rewrittenArg, rewrittenLower, rewrittenUpper);
10743 };
10744 SQExprRewriter.prototype.visitIn = function (orig) {
10745 var origArgs = orig.args, rewrittenArgs = this.rewriteAll(origArgs), origValues = orig.values, rewrittenValues;
10746 for (var i = 0, len = origValues.length; i < len; i++) {
10747 var origValueTuple = origValues[i], rewrittenValueTuple = this.rewriteAll(origValueTuple);
10748 if (origValueTuple !== rewrittenValueTuple && !rewrittenValues)
10749 rewrittenValues = ArrayExtensions.take(origValues, i);
10750 if (rewrittenValues)
10751 rewrittenValues.push(rewrittenValueTuple);
10752 }
10753 if (origArgs === rewrittenArgs && !rewrittenValues)
10754 return orig;
10755 return new data.SQInExpr(rewrittenArgs, rewrittenValues || origValues);
10756 };
10757 SQExprRewriter.prototype.rewriteAll = function (origExprs) {
10758 debug.assertValue(origExprs, 'origExprs');
10759 var rewrittenResult;
10760 for (var i = 0, len = origExprs.length; i < len; i++) {
10761 var origExpr = origExprs[i], rewrittenExpr = origExpr.accept(this);
10762 if (origExpr !== rewrittenExpr && !rewrittenResult)
10763 rewrittenResult = ArrayExtensions.take(origExprs, i);
10764 if (rewrittenResult)
10765 rewrittenResult.push(rewrittenExpr);
10766 }
10767 return rewrittenResult || origExprs;
10768 };
10769 SQExprRewriter.prototype.visitOr = function (orig) {
10770 var origLeft = orig.left, rewrittenLeft = origLeft.accept(this), origRight = orig.right, rewrittenRight = origRight.accept(this);
10771 if (origLeft === rewrittenLeft && origRight === rewrittenRight)
10772 return orig;
10773 return new data.SQOrExpr(rewrittenLeft, rewrittenRight);
10774 };
10775 SQExprRewriter.prototype.visitCompare = function (orig) {
10776 var origLeft = orig.left, rewrittenLeft = origLeft.accept(this), origRight = orig.right, rewrittenRight = origRight.accept(this);
10777 if (origLeft === rewrittenLeft && origRight === rewrittenRight)
10778 return orig;
10779 return new data.SQCompareExpr(orig.comparison, rewrittenLeft, rewrittenRight);
10780 };
10781 SQExprRewriter.prototype.visitContains = function (orig) {
10782 var origLeft = orig.left, rewrittenLeft = origLeft.accept(this), origRight = orig.right, rewrittenRight = origRight.accept(this);
10783 if (origLeft === rewrittenLeft && origRight === rewrittenRight)
10784 return orig;
10785 return new data.SQContainsExpr(rewrittenLeft, rewrittenRight);
10786 };
10787 SQExprRewriter.prototype.visitExists = function (orig) {
10788 var origArg = orig.arg, rewrittenArg = origArg.accept(this);
10789 if (origArg === rewrittenArg)
10790 return orig;
10791 return new data.SQExistsExpr(rewrittenArg);
10792 };
10793 SQExprRewriter.prototype.visitNot = function (orig) {
10794 var origArg = orig.arg, rewrittenArg = origArg.accept(this);
10795 if (origArg === rewrittenArg)
10796 return orig;
10797 return new data.SQNotExpr(rewrittenArg);
10798 };
10799 SQExprRewriter.prototype.visitStartsWith = function (orig) {
10800 var origLeft = orig.left, rewrittenLeft = origLeft.accept(this), origRight = orig.right, rewrittenRight = origRight.accept(this);
10801 if (origLeft === rewrittenLeft && origRight === rewrittenRight)
10802 return orig;
10803 return new data.SQStartsWithExpr(rewrittenLeft, rewrittenRight);
10804 };
10805 SQExprRewriter.prototype.visitConstant = function (expr) {
10806 return expr;
10807 };
10808 SQExprRewriter.prototype.visitDateSpan = function (orig) {
10809 var origArg = orig.arg, rewrittenArg = origArg.accept(this);
10810 if (origArg === rewrittenArg)
10811 return orig;
10812 return new data.SQDateSpanExpr(orig.unit, rewrittenArg);
10813 };
10814 SQExprRewriter.prototype.visitDateAdd = function (orig) {
10815 var origArg = orig.arg, rewrittenArg = origArg.accept(this);
10816 if (origArg === rewrittenArg)
10817 return orig;
10818 return new data.SQDateAddExpr(orig.unit, orig.amount, rewrittenArg);
10819 };
10820 SQExprRewriter.prototype.visitNow = function (orig) {
10821 return orig;
10822 };
10823 SQExprRewriter.prototype.visitDefaultValue = function (orig) {
10824 return orig;
10825 };
10826 SQExprRewriter.prototype.visitAnyValue = function (orig) {
10827 return orig;
10828 };
10829 SQExprRewriter.prototype.visitArithmetic = function (orig) {
10830 var origLeft = orig.left, rewrittenLeft = origLeft.accept(this), origRight = orig.right, rewrittenRight = origRight.accept(this);
10831 if (origLeft === rewrittenLeft && origRight === rewrittenRight)
10832 return orig;
10833 return new data.SQArithmeticExpr(rewrittenLeft, rewrittenRight, orig.operator);
10834 };
10835 SQExprRewriter.prototype.visitScopedEval = function (orig) {
10836 var origExpression = orig.expression, rewrittenExpression = origExpression.accept(this), origScope = orig.scope, rewrittenScope = this.rewriteAll(origScope);
10837 if (origExpression === rewrittenExpression && origScope === rewrittenScope)
10838 return orig;
10839 return new data.SQScopedEvalExpr(rewrittenExpression, rewrittenScope);
10840 };
10841 SQExprRewriter.prototype.visitFillRule = function (orig) {
10842 var origInput = orig.input, rewrittenInput = origInput.accept(this);
10843 var origRule = orig.rule;
10844 var origGradient2 = origRule.linearGradient2, rewrittenGradient2 = origGradient2;
10845 if (origGradient2) {
10846 rewrittenGradient2 = this.visitLinearGradient2(origGradient2);
10847 }
10848 var origGradient3 = origRule.linearGradient3, rewrittenGradient3 = origGradient3;
10849 if (origGradient3) {
10850 rewrittenGradient3 = this.visitLinearGradient3(origGradient3);
10851 }
10852 if (origInput !== rewrittenInput ||
10853 origGradient2 !== rewrittenGradient2 ||
10854 origGradient3 !== rewrittenGradient3) {
10855 var rewrittenRule = {};
10856 if (rewrittenGradient2)
10857 rewrittenRule.linearGradient2 = rewrittenGradient2;
10858 if (rewrittenGradient3)
10859 rewrittenRule.linearGradient3 = rewrittenGradient3;
10860 return new data.SQFillRuleExpr(rewrittenInput, rewrittenRule);
10861 }
10862 return orig;
10863 };
10864 SQExprRewriter.prototype.visitLinearGradient2 = function (origGradient2) {
10865 debug.assertValue(origGradient2, 'origGradient2');
10866 var origMin = origGradient2.min, rewrittenMin = this.visitFillRuleStop(origMin), origMax = origGradient2.max, rewrittenMax = this.visitFillRuleStop(origMax);
10867 if (origMin !== rewrittenMin || origMax !== rewrittenMax) {
10868 return {
10869 min: rewrittenMin,
10870 max: rewrittenMax,
10871 };
10872 }
10873 return origGradient2;
10874 };
10875 SQExprRewriter.prototype.visitLinearGradient3 = function (origGradient3) {
10876 debug.assertValue(origGradient3, 'origGradient3');
10877 var origMin = origGradient3.min, rewrittenMin = this.visitFillRuleStop(origMin), origMid = origGradient3.mid, rewrittenMid = this.visitFillRuleStop(origMid), origMax = origGradient3.max, rewrittenMax = this.visitFillRuleStop(origMax);
10878 if (origMin !== rewrittenMin || origMid !== rewrittenMid || origMax !== rewrittenMax) {
10879 return {
10880 min: rewrittenMin,
10881 mid: rewrittenMid,
10882 max: rewrittenMax,
10883 };
10884 }
10885 return origGradient3;
10886 };
10887 SQExprRewriter.prototype.visitFillRuleStop = function (stop) {
10888 debug.assertValue(stop, 'stop');
10889 var origColor = stop.color, rewrittenColor = stop.color.accept(this);
10890 var origValue = stop.value, rewrittenValue = origValue;
10891 if (origValue)
10892 rewrittenValue = origValue.accept(this);
10893 if (origColor !== rewrittenColor || origValue !== rewrittenValue) {
10894 var rewrittenStop = {
10895 color: rewrittenColor
10896 };
10897 if (rewrittenValue)
10898 rewrittenStop.value = rewrittenValue;
10899 return rewrittenStop;
10900 }
10901 return stop;
10902 };
10903 SQExprRewriter.prototype.visitResourcePackageItem = function (orig) {
10904 return orig;
10905 };
10906 return SQExprRewriter;
10907 }());
10908 data.SQExprRewriter = SQExprRewriter;
10909 })(data = powerbi.data || (powerbi.data = {}));
10910})(powerbi || (powerbi = {}));
10911/*
10912 * Power BI Visualizations
10913 *
10914 * Copyright (c) Microsoft Corporation
10915 * All rights reserved.
10916 * MIT License
10917 *
10918 * Permission is hereby granted, free of charge, to any person obtaining a copy
10919 * of this software and associated documentation files (the ""Software""), to deal
10920 * in the Software without restriction, including without limitation the rights
10921 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10922 * copies of the Software, and to permit persons to whom the Software is
10923 * furnished to do so, subject to the following conditions:
10924 *
10925 * The above copyright notice and this permission notice shall be included in
10926 * all copies or substantial portions of the Software.
10927 *
10928 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10929 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10930 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10931 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10932 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10933 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10934 * THE SOFTWARE.
10935 */
10936var powerbi;
10937(function (powerbi) {
10938 var data;
10939 (function (data) {
10940 /** Responsible for writing equality comparisons against a field to an SQInExpr. */
10941 var EqualsToInRewriter;
10942 (function (EqualsToInRewriter) {
10943 function run(expr) {
10944 debug.assertValue(expr, 'expr');
10945 return expr.accept(new Rewriter());
10946 }
10947 EqualsToInRewriter.run = run;
10948 var Rewriter = (function (_super) {
10949 __extends(Rewriter, _super);
10950 function Rewriter() {
10951 _super.call(this);
10952 }
10953 Rewriter.prototype.visitCompare = function (expr) {
10954 if (expr.comparison !== data.QueryComparisonKind.Equal)
10955 return this.visitUnsupported(expr);
10956 if (!this.isSupported(expr.left) || !this.isSupported(expr.right))
10957 return this.visitUnsupported(expr);
10958 var leftIsComparand = this.isComparand(expr.left);
10959 var rightIsComparand = this.isComparand(expr.right);
10960 if (leftIsComparand === rightIsComparand)
10961 return this.visitUnsupported(expr);
10962 var operand = leftIsComparand
10963 ? expr.left
10964 : expr.right;
10965 var value = leftIsComparand
10966 ? expr.right
10967 : expr.left;
10968 var current = this.current;
10969 if (!current) {
10970 return data.SQExprBuilder.inExpr([operand], [[value]]);
10971 }
10972 current.add(operand, value);
10973 return expr;
10974 };
10975 Rewriter.prototype.visitOr = function (expr) {
10976 if (!this.isSupported(expr.left) || !this.isSupported(expr.right))
10977 return this.visitUnsupported(expr);
10978 var current;
10979 if (!this.current) {
10980 current = this.current = new InBuilder();
10981 }
10982 expr.left.accept(this);
10983 expr.right.accept(this);
10984 if (current) {
10985 this.current = null;
10986 return current.complete() || expr;
10987 }
10988 return expr;
10989 };
10990 Rewriter.prototype.visitAnd = function (expr) {
10991 if (!this.isSupported(expr.left) || !this.isSupported(expr.right))
10992 return this.visitUnsupported(expr);
10993 var current = this.current;
10994 if (current) {
10995 // NOTE: Composite keys are not supported by this algorithm.
10996 current.cancel();
10997 return expr;
10998 }
10999 return _super.prototype.visitAnd.call(this, expr);
11000 };
11001 Rewriter.prototype.visitUnsupported = function (expr) {
11002 var current = this.current;
11003 if (current)
11004 current.cancel();
11005 return expr;
11006 };
11007 Rewriter.prototype.isSupported = function (expr) {
11008 debug.assertValue(expr, 'expr');
11009 return expr instanceof data.SQCompareExpr
11010 || expr instanceof data.SQColumnRefExpr
11011 || expr instanceof data.SQConstantExpr
11012 || expr instanceof data.SQHierarchyLevelExpr
11013 || expr instanceof data.SQOrExpr
11014 || expr instanceof data.SQAndExpr;
11015 };
11016 Rewriter.prototype.isComparand = function (expr) {
11017 return expr instanceof data.SQColumnRefExpr
11018 || expr instanceof data.SQHierarchyLevelExpr;
11019 };
11020 return Rewriter;
11021 }(data.SQExprRewriter));
11022 var InBuilder = (function () {
11023 function InBuilder() {
11024 }
11025 InBuilder.prototype.add = function (operand, value) {
11026 debug.assertValue(operand, 'operand');
11027 debug.assertValue(value, 'value');
11028 if (this.cancelled)
11029 return;
11030 if (this.operand && !data.SQExpr.equals(operand, this.operand)) {
11031 this.cancel();
11032 return;
11033 }
11034 this.operand = operand;
11035 var values = this.values;
11036 if (!values)
11037 values = this.values = [];
11038 values.push(value);
11039 };
11040 InBuilder.prototype.cancel = function () {
11041 this.cancelled = true;
11042 };
11043 InBuilder.prototype.complete = function () {
11044 if (this.cancelled || !this.operand)
11045 return;
11046 return data.SQExprBuilder.inExpr([this.operand], _.map(this.values, function (v) { return [v]; }));
11047 };
11048 return InBuilder;
11049 }());
11050 })(EqualsToInRewriter = data.EqualsToInRewriter || (data.EqualsToInRewriter = {}));
11051 })(data = powerbi.data || (powerbi.data = {}));
11052})(powerbi || (powerbi = {}));
11053/*
11054 * Power BI Visualizations
11055 *
11056 * Copyright (c) Microsoft Corporation
11057 * All rights reserved.
11058 * MIT License
11059 *
11060 * Permission is hereby granted, free of charge, to any person obtaining a copy
11061 * of this software and associated documentation files (the ""Software""), to deal
11062 * in the Software without restriction, including without limitation the rights
11063 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11064 * copies of the Software, and to permit persons to whom the Software is
11065 * furnished to do so, subject to the following conditions:
11066 *
11067 * The above copyright notice and this permission notice shall be included in
11068 * all copies or substantial portions of the Software.
11069 *
11070 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11071 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11072 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11073 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11074 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11075 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11076 * THE SOFTWARE.
11077 */
11078var powerbi;
11079(function (powerbi) {
11080 var data;
11081 (function (data) {
11082 var SQExprConverter;
11083 (function (SQExprConverter) {
11084 function asScopeIdsContainer(filter, fieldSQExprs) {
11085 debug.assertValue(filter, 'filter');
11086 debug.assertValue(fieldSQExprs, 'fieldSQExprs');
11087 debug.assert(fieldSQExprs.length > 0, 'There should be at least 1 field expression.');
11088 var filterItems = filter.conditions();
11089 debug.assert(filterItems.length === 1, 'There should be exactly 1 filter expression.');
11090 var filterItem = filterItems[0];
11091 if (filterItem) {
11092 var visitor = new FilterScopeIdsCollectorVisitor(fieldSQExprs);
11093 if (filterItem.accept(visitor))
11094 return visitor.getResult();
11095 }
11096 }
11097 SQExprConverter.asScopeIdsContainer = asScopeIdsContainer;
11098 /** Gets a comparand value from the given DataViewScopeIdentity. */
11099 function getFirstComparandValue(identity) {
11100 debug.assertValue(identity, 'identity');
11101 var comparandExpr = identity.expr.accept(new FindComparandVisitor());
11102 if (comparandExpr)
11103 return comparandExpr.value;
11104 }
11105 SQExprConverter.getFirstComparandValue = getFirstComparandValue;
11106 })(SQExprConverter = data.SQExprConverter || (data.SQExprConverter = {}));
11107 /** Collect filter values from simple semantic filter that is similar to 'is any of' or 'is not any of', getResult() returns a collection of scopeIds.**/
11108 var FilterScopeIdsCollectorVisitor = (function (_super) {
11109 __extends(FilterScopeIdsCollectorVisitor, _super);
11110 function FilterScopeIdsCollectorVisitor(fieldSQExprs) {
11111 _super.call(this);
11112 this.isRoot = true;
11113 this.isNot = false;
11114 this.keyExprsCount = null;
11115 this.valueExprs = [];
11116 // Need to drop the entitylet before create the scopeIdentity. The ScopeIdentity created on the client is used to
11117 // compare the ScopeIdentity came from the server. But server doesn't have the entity variable concept, so we will
11118 // need to drop it in order to use JsonComparer.
11119 this.fieldExprs = [];
11120 for (var _i = 0, fieldSQExprs_1 = fieldSQExprs; _i < fieldSQExprs_1.length; _i++) {
11121 var field = fieldSQExprs_1[_i];
11122 this.fieldExprs.push(data.SQExprBuilder.removeEntityVariables(field));
11123 }
11124 }
11125 FilterScopeIdsCollectorVisitor.prototype.getResult = function () {
11126 debug.assert(this.fieldExprs.length > 0, 'fieldExprs has at least one fieldExpr');
11127 var valueExprs = this.valueExprs, scopeIds = [];
11128 var valueCount = this.keyExprsCount || 1;
11129 for (var startIndex = 0, endIndex = valueCount, len = valueExprs.length; startIndex < len && endIndex <= len;) {
11130 var values = valueExprs.slice(startIndex, endIndex);
11131 var scopeId = FilterScopeIdsCollectorVisitor.getScopeIdentity(this.fieldExprs, values);
11132 if (!jsCommon.ArrayExtensions.isInArray(scopeIds, scopeId, powerbi.DataViewScopeIdentity.equals))
11133 scopeIds.push(scopeId);
11134 startIndex += valueCount;
11135 endIndex += valueCount;
11136 }
11137 return {
11138 isNot: this.isNot,
11139 scopeIds: scopeIds,
11140 };
11141 };
11142 FilterScopeIdsCollectorVisitor.getScopeIdentity = function (fieldExprs, valueExprs) {
11143 debug.assert(valueExprs.length > 0, 'valueExprs has at least one valueExpr');
11144 debug.assert(valueExprs.length === fieldExprs.length, 'fieldExpr and valueExpr count should match');
11145 var compoundSQExpr;
11146 for (var i = 0, len = fieldExprs.length; i < len; i++) {
11147 var equalsExpr = data.SQExprBuilder.equal(fieldExprs[i], valueExprs[i]);
11148 if (!compoundSQExpr)
11149 compoundSQExpr = equalsExpr;
11150 else
11151 compoundSQExpr = data.SQExprBuilder.and(compoundSQExpr, equalsExpr);
11152 }
11153 return data.createDataViewScopeIdentity(compoundSQExpr);
11154 };
11155 FilterScopeIdsCollectorVisitor.prototype.visitOr = function (expr) {
11156 if (this.keyExprsCount !== null)
11157 return this.unsupportedSQExpr();
11158 this.isRoot = false;
11159 return expr.left.accept(this) && expr.right.accept(this);
11160 };
11161 FilterScopeIdsCollectorVisitor.prototype.visitNot = function (expr) {
11162 if (!this.isRoot)
11163 return this.unsupportedSQExpr();
11164 this.isNot = true;
11165 return expr.arg.accept(this);
11166 };
11167 FilterScopeIdsCollectorVisitor.prototype.visitConstant = function (expr) {
11168 if (this.isRoot && expr.type.primitiveType === powerbi.PrimitiveType.Null)
11169 return this.unsupportedSQExpr();
11170 this.valueExprs.push(expr);
11171 return true;
11172 };
11173 FilterScopeIdsCollectorVisitor.prototype.visitCompare = function (expr) {
11174 if (this.keyExprsCount !== null)
11175 return this.unsupportedSQExpr();
11176 this.isRoot = false;
11177 if (expr.comparison !== data.QueryComparisonKind.Equal)
11178 return this.unsupportedSQExpr();
11179 return expr.left.accept(this) && expr.right.accept(this);
11180 };
11181 FilterScopeIdsCollectorVisitor.prototype.visitIn = function (expr) {
11182 this.keyExprsCount = 0;
11183 var result;
11184 this.isRoot = false;
11185 for (var _i = 0, _a = expr.args; _i < _a.length; _i++) {
11186 var arg = _a[_i];
11187 result = arg.accept(this);
11188 if (!result)
11189 return this.unsupportedSQExpr();
11190 this.keyExprsCount++;
11191 }
11192 if (this.keyExprsCount !== this.fieldExprs.length)
11193 return this.unsupportedSQExpr();
11194 var values = expr.values;
11195 for (var _b = 0, values_1 = values; _b < values_1.length; _b++) {
11196 var valueTuple = values_1[_b];
11197 var jlen = valueTuple.length;
11198 debug.assert(jlen === this.keyExprsCount, "keys count and values count should match");
11199 for (var _c = 0, valueTuple_1 = valueTuple; _c < valueTuple_1.length; _c++) {
11200 var value = valueTuple_1[_c];
11201 result = value.accept(this);
11202 if (!result)
11203 return this.unsupportedSQExpr();
11204 }
11205 }
11206 return result;
11207 };
11208 FilterScopeIdsCollectorVisitor.prototype.visitColumnRef = function (expr) {
11209 if (this.isRoot)
11210 return this.unsupportedSQExpr();
11211 var fixedExpr = data.SQExprBuilder.removeEntityVariables(expr);
11212 if (this.keyExprsCount !== null)
11213 return data.SQExpr.equals(this.fieldExprs[this.keyExprsCount], fixedExpr);
11214 return data.SQExpr.equals(this.fieldExprs[0], fixedExpr);
11215 };
11216 FilterScopeIdsCollectorVisitor.prototype.visitDefaultValue = function (expr) {
11217 if (this.isRoot || this.keyExprsCount !== null)
11218 return this.unsupportedSQExpr();
11219 this.valueExprs.push(expr);
11220 return true;
11221 };
11222 FilterScopeIdsCollectorVisitor.prototype.visitAnyValue = function (expr) {
11223 if (this.isRoot || this.keyExprsCount !== null)
11224 return this.unsupportedSQExpr();
11225 this.valueExprs.push(expr);
11226 return true;
11227 };
11228 FilterScopeIdsCollectorVisitor.prototype.visitDefault = function (expr) {
11229 return this.unsupportedSQExpr();
11230 };
11231 FilterScopeIdsCollectorVisitor.prototype.unsupportedSQExpr = function () {
11232 return false;
11233 };
11234 return FilterScopeIdsCollectorVisitor;
11235 }(data.DefaultSQExprVisitor));
11236 var FindComparandVisitor = (function (_super) {
11237 __extends(FindComparandVisitor, _super);
11238 function FindComparandVisitor() {
11239 _super.apply(this, arguments);
11240 }
11241 FindComparandVisitor.prototype.visitAnd = function (expr) {
11242 return expr.left.accept(this) || expr.right.accept(this);
11243 };
11244 FindComparandVisitor.prototype.visitCompare = function (expr) {
11245 if (expr.comparison === data.QueryComparisonKind.Equal) {
11246 if (expr.right instanceof data.SQConstantExpr)
11247 return expr.right;
11248 if (expr.left instanceof data.SQConstantExpr)
11249 return expr.left;
11250 }
11251 };
11252 return FindComparandVisitor;
11253 }(data.DefaultSQExprVisitor));
11254 })(data = powerbi.data || (powerbi.data = {}));
11255})(powerbi || (powerbi = {}));
11256/*
11257 * Power BI Visualizations
11258 *
11259 * Copyright (c) Microsoft Corporation
11260 * All rights reserved.
11261 * MIT License
11262 *
11263 * Permission is hereby granted, free of charge, to any person obtaining a copy
11264 * of this software and associated documentation files (the ""Software""), to deal
11265 * in the Software without restriction, including without limitation the rights
11266 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11267 * copies of the Software, and to permit persons to whom the Software is
11268 * furnished to do so, subject to the following conditions:
11269 *
11270 * The above copyright notice and this permission notice shall be included in
11271 * all copies or substantial portions of the Software.
11272 *
11273 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11274 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11275 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11276 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11277 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11278 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11279 * THE SOFTWARE.
11280 */
11281var powerbi;
11282(function (powerbi) {
11283 var data;
11284 (function (data) {
11285 var ArrayExtensions = jsCommon.ArrayExtensions;
11286 /** Recognizes DataViewScopeIdentity expression trees to extract comparison keys. */
11287 var ScopeIdentityExtractor;
11288 (function (ScopeIdentityExtractor) {
11289 function getKeys(expr) {
11290 var extractor = new ScopeIdExtractorImpl();
11291 expr.accept(extractor);
11292 if (extractor.malformed)
11293 return null;
11294 return ArrayExtensions.emptyToNull(extractor.keys);
11295 }
11296 ScopeIdentityExtractor.getKeys = getKeys;
11297 function getInExpr(expr) {
11298 var extractor = new ScopeIdExtractorImpl();
11299 expr.accept(extractor);
11300 if (extractor.malformed)
11301 return;
11302 var keys = ArrayExtensions.emptyToNull(extractor.keys);
11303 var keyValues = ArrayExtensions.emptyToNull(extractor.values);
11304 if (keys && keyValues)
11305 return data.SQExprBuilder.inExpr(keys, [keyValues]);
11306 }
11307 ScopeIdentityExtractor.getInExpr = getInExpr;
11308 /**
11309 * Recognizes expressions of the form:
11310 * 1) Equals(ColRef, Constant)
11311 * 2) And(Equals(ColRef1, Constant1), Equals(ColRef2, Constant2))
11312 * or And(And(Equals(ColRef1, Constant1), Equals(ColRef2, Constant2)), Equals(ColRef3, Constant3)) etc..
11313 */
11314 var ScopeIdExtractorImpl = (function (_super) {
11315 __extends(ScopeIdExtractorImpl, _super);
11316 function ScopeIdExtractorImpl() {
11317 _super.apply(this, arguments);
11318 this.keys = [];
11319 this.values = [];
11320 }
11321 ScopeIdExtractorImpl.prototype.visitAnd = function (expr) {
11322 expr.left.accept(this);
11323 expr.right.accept(this);
11324 };
11325 ScopeIdExtractorImpl.prototype.visitCompare = function (expr) {
11326 if (expr.comparison !== data.QueryComparisonKind.Equal) {
11327 this.visitDefault(expr);
11328 return;
11329 }
11330 debug.assert(expr.left instanceof data.SQExpr && expr.right instanceof data.SQConstantExpr, 'invalid compare expr operands');
11331 expr.left.accept(this);
11332 expr.right.accept(this);
11333 };
11334 ScopeIdExtractorImpl.prototype.visitColumnRef = function (expr) {
11335 this.keys.push(expr);
11336 };
11337 ScopeIdExtractorImpl.prototype.visitHierarchyLevel = function (expr) {
11338 this.keys.push(expr);
11339 };
11340 ScopeIdExtractorImpl.prototype.visitConstant = function (expr) {
11341 this.values.push(expr);
11342 };
11343 ScopeIdExtractorImpl.prototype.visitArithmetic = function (expr) {
11344 this.keys.push(expr);
11345 };
11346 ScopeIdExtractorImpl.prototype.visitDefault = function (expr) {
11347 this.malformed = true;
11348 };
11349 return ScopeIdExtractorImpl;
11350 }(data.DefaultSQExprVisitor));
11351 })(ScopeIdentityExtractor = data.ScopeIdentityExtractor || (data.ScopeIdentityExtractor = {}));
11352 })(data = powerbi.data || (powerbi.data = {}));
11353})(powerbi || (powerbi = {}));
11354/*
11355 * Power BI Visualizations
11356 *
11357 * Copyright (c) Microsoft Corporation
11358 * All rights reserved.
11359 * MIT License
11360 *
11361 * Permission is hereby granted, free of charge, to any person obtaining a copy
11362 * of this software and associated documentation files (the ""Software""), to deal
11363 * in the Software without restriction, including without limitation the rights
11364 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11365 * copies of the Software, and to permit persons to whom the Software is
11366 * furnished to do so, subject to the following conditions:
11367 *
11368 * The above copyright notice and this permission notice shall be included in
11369 * all copies or substantial portions of the Software.
11370 *
11371 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11372 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11373 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11374 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11375 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11376 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11377 * THE SOFTWARE.
11378 */
11379var powerbi;
11380(function (powerbi) {
11381 var data;
11382 (function (data) {
11383 var PrimitiveValueEncoding;
11384 (function (PrimitiveValueEncoding) {
11385 var SingleQuoteRegex = /'/g;
11386 function decimal(value) {
11387 debug.assertValue(value, 'value');
11388 return value + 'M';
11389 }
11390 PrimitiveValueEncoding.decimal = decimal;
11391 function double(value) {
11392 debug.assertValue(value, 'value');
11393 return value + 'D';
11394 }
11395 PrimitiveValueEncoding.double = double;
11396 function integer(value) {
11397 debug.assertValue(value, 'value');
11398 return value + 'L';
11399 }
11400 PrimitiveValueEncoding.integer = integer;
11401 function dateTime(value) {
11402 debug.assertValue(value, 'value');
11403 // Currently, server doesn't support timezone. All date time data on the server don't have time zone information.
11404 // So, when we construct a dateTime object on the client, we will need to ignor user's time zone and force it to be UTC time.
11405 // When we subtract the timeZone offset, the date time object will remain the same value as you entered but dropped the local timeZone.
11406 var date = new Date(value.getTime() - (value.getTimezoneOffset() * 60000));
11407 var dateTimeString = date.toISOString();
11408 // If it ends with Z, we want to get rid of it, because with trailing Z, it will assume the dateTime is UTC, but we don't want any timeZone information, so
11409 // we will drop it.
11410 // Also, we need to add Prefix and Suffix to match the dsr value format for dateTime object.
11411 if (jsCommon.StringExtensions.endsWith(dateTimeString, 'Z'))
11412 dateTimeString = dateTimeString.substr(0, dateTimeString.length - 1);
11413 return "datetime'" + dateTimeString + "'";
11414 }
11415 PrimitiveValueEncoding.dateTime = dateTime;
11416 function text(value) {
11417 debug.assertValue(value, 'value');
11418 return "'" + value.replace(SingleQuoteRegex, "''") + "'";
11419 }
11420 PrimitiveValueEncoding.text = text;
11421 function nullEncoding() {
11422 return 'null';
11423 }
11424 PrimitiveValueEncoding.nullEncoding = nullEncoding;
11425 function boolean(value) {
11426 return value ? 'true' : 'false';
11427 }
11428 PrimitiveValueEncoding.boolean = boolean;
11429 })(PrimitiveValueEncoding = data.PrimitiveValueEncoding || (data.PrimitiveValueEncoding = {}));
11430 })(data = powerbi.data || (powerbi.data = {}));
11431})(powerbi || (powerbi = {}));
11432/*
11433 * Power BI Visualizations
11434 *
11435 * Copyright (c) Microsoft Corporation
11436 * All rights reserved.
11437 * MIT License
11438 *
11439 * Permission is hereby granted, free of charge, to any person obtaining a copy
11440 * of this software and associated documentation files (the ""Software""), to deal
11441 * in the Software without restriction, including without limitation the rights
11442 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11443 * copies of the Software, and to permit persons to whom the Software is
11444 * furnished to do so, subject to the following conditions:
11445 *
11446 * The above copyright notice and this permission notice shall be included in
11447 * all copies or substantial portions of the Software.
11448 *
11449 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11450 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11451 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11452 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11453 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11454 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11455 * THE SOFTWARE.
11456 */
11457var powerbi;
11458(function (powerbi) {
11459 var data;
11460 (function (data) {
11461 var Agg = powerbi.data.QueryAggregateFunction;
11462 function createSQAggregationOperations(datetimeMinMaxSupported) {
11463 return new SQAggregationOperations(datetimeMinMaxSupported);
11464 }
11465 data.createSQAggregationOperations = createSQAggregationOperations;
11466 var SQAggregationOperations = (function () {
11467 function SQAggregationOperations(datetimeMinMaxSupported) {
11468 this.datetimeMinMaxSupported = datetimeMinMaxSupported;
11469 }
11470 SQAggregationOperations.prototype.getSupportedAggregates = function (expr, schema, targetTypes) {
11471 debug.assertValue(expr, 'expr');
11472 debug.assertValue(schema, 'schema');
11473 debug.assertAnyValue(targetTypes, 'targetTypes');
11474 var metadata = getMetadataForUnderlyingType(expr, schema);
11475 // don't use expr.validate as validate will be using this function and we end up in a recursive loop
11476 if (!metadata)
11477 return [];
11478 var valueType = metadata.type, fieldKind = metadata.kind, isPropertyIdentity = metadata.idOnEntityKey;
11479 if (!valueType)
11480 return [];
11481 // Cannot aggregate on model measures
11482 if (fieldKind === 1 /* Measure */)
11483 return [];
11484 if (valueType.numeric || valueType.integer) {
11485 var aggregates_1 = [Agg.Sum, Agg.Avg, Agg.Min, Agg.Max, Agg.Count, Agg.CountNonNull, Agg.StandardDeviation, Agg.Variance];
11486 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
11487 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
11488 var currentSchema = schema.schema(fieldExprItem.schema);
11489 if (currentSchema.capabilities.supportsMedian)
11490 aggregates_1.push(Agg.Median);
11491 return aggregates_1;
11492 }
11493 var aggregates = [];
11494 // Min/Max of DateTime
11495 if (this.datetimeMinMaxSupported &&
11496 valueType.dateTime &&
11497 (_.isEmpty(targetTypes) || powerbi.ValueType.isCompatibleTo(valueType, targetTypes))) {
11498 aggregates.push(Agg.Min);
11499 aggregates.push(Agg.Max);
11500 }
11501 // The supported aggregation types for an identity field are restricted to 'Count Non-Null' (e.g. for the field well aggregation options)
11502 // but a valid semantic query can return a less-restricted aggregation option which we should honor. (e.g. this results from Q&A)
11503 var distinctCountAggExists = data.SQExprInfo.getAggregate(expr) === Agg.Count;
11504 if (!(isPropertyIdentity && !distinctCountAggExists))
11505 aggregates.push(Agg.Count);
11506 aggregates.push(Agg.CountNonNull);
11507 return aggregates;
11508 };
11509 SQAggregationOperations.prototype.isSupportedAggregate = function (expr, schema, aggregate, targetTypes) {
11510 debug.assertValue(expr, 'expr');
11511 debug.assertValue(schema, 'schema');
11512 var supportedAggregates = this.getSupportedAggregates(expr, schema, targetTypes);
11513 return _.contains(supportedAggregates, aggregate);
11514 };
11515 SQAggregationOperations.prototype.createExprWithAggregate = function (expr, schema, aggregateNonNumericFields, targetTypes, preferredAggregate) {
11516 debug.assertValue(expr, 'expr');
11517 debug.assertValue(schema, 'schema');
11518 var aggregate;
11519 if (preferredAggregate != null && this.isSupportedAggregate(expr, schema, preferredAggregate, targetTypes)) {
11520 aggregate = preferredAggregate;
11521 }
11522 else {
11523 aggregate = expr.getDefaultAggregate(schema, aggregateNonNumericFields);
11524 }
11525 if (aggregate !== undefined)
11526 expr = data.SQExprBuilder.aggregate(expr, aggregate);
11527 return expr;
11528 };
11529 return SQAggregationOperations;
11530 }());
11531 function getMetadataForUnderlyingType(expr, schema) {
11532 // Unwrap the aggregate (if the expr has one), and look at the underlying type.
11533 var metadata = data.SQExprBuilder.removeAggregate(expr).getMetadata(schema);
11534 if (!metadata)
11535 metadata = expr.getMetadata(schema);
11536 return metadata;
11537 }
11538 })(data = powerbi.data || (powerbi.data = {}));
11539})(powerbi || (powerbi = {}));
11540/*
11541 * Power BI Visualizations
11542 *
11543 * Copyright (c) Microsoft Corporation
11544 * All rights reserved.
11545 * MIT License
11546 *
11547 * Permission is hereby granted, free of charge, to any person obtaining a copy
11548 * of this software and associated documentation files (the ""Software""), to deal
11549 * in the Software without restriction, including without limitation the rights
11550 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11551 * copies of the Software, and to permit persons to whom the Software is
11552 * furnished to do so, subject to the following conditions:
11553 *
11554 * The above copyright notice and this permission notice shall be included in
11555 * all copies or substantial portions of the Software.
11556 *
11557 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11558 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11559 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11560 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11561 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11562 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11563 * THE SOFTWARE.
11564 */
11565var powerbi;
11566(function (powerbi) {
11567 var data;
11568 (function (data) {
11569 var SQHierarchyExprUtils;
11570 (function (SQHierarchyExprUtils) {
11571 function getConceptualHierarchyLevelFromExpr(conceptualSchema, fieldExpr) {
11572 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
11573 var hierarchyLevel = fieldExpr.hierarchyLevel || fieldExpr.hierarchyLevelAggr;
11574 if (hierarchyLevel)
11575 return SQHierarchyExprUtils.getConceptualHierarchyLevel(conceptualSchema, fieldExprItem.schema, fieldExprItem.entity, hierarchyLevel.name, hierarchyLevel.level);
11576 }
11577 SQHierarchyExprUtils.getConceptualHierarchyLevelFromExpr = getConceptualHierarchyLevelFromExpr;
11578 function getConceptualHierarchyLevel(conceptualSchema, schemaName, entity, hierarchy, hierarchyLevel) {
11579 var schema = conceptualSchema.schema(schemaName);
11580 var conceptualHierarchy = schema.findHierarchy(entity, hierarchy);
11581 if (conceptualHierarchy) {
11582 return conceptualHierarchy.levels.withName(hierarchyLevel);
11583 }
11584 }
11585 SQHierarchyExprUtils.getConceptualHierarchyLevel = getConceptualHierarchyLevel;
11586 function getConceptualHierarchy(sqExpr, federatedSchema) {
11587 if (sqExpr instanceof data.SQHierarchyExpr) {
11588 var hierarchy = sqExpr;
11589 if (sqExpr.arg instanceof data.SQEntityExpr) {
11590 var entityExpr = sqExpr.arg;
11591 return federatedSchema
11592 .schema(entityExpr.schema)
11593 .findHierarchy(entityExpr.entity, hierarchy.hierarchy);
11594 }
11595 else if (sqExpr.arg instanceof data.SQPropertyVariationSourceExpr) {
11596 var variationExpr = sqExpr.arg;
11597 var sourceEntityExpr = variationExpr.arg;
11598 return federatedSchema
11599 .schema(sourceEntityExpr.schema)
11600 .findHierarchyByVariation(sourceEntityExpr.entity, variationExpr.property, variationExpr.name, hierarchy.hierarchy);
11601 }
11602 }
11603 }
11604 SQHierarchyExprUtils.getConceptualHierarchy = getConceptualHierarchy;
11605 function expandExpr(schema, expr, suppressHierarchyLevelExpansion) {
11606 return SQExprHierarchyToHierarchyLevelConverter.convert(expr, schema) ||
11607 SQExprVariationConverter.expand(expr, schema) ||
11608 // If we are calling expandExpr from suppressHierarchyLevelExpansion, we should not expand the hierarchylevels
11609 (!suppressHierarchyLevelExpansion && SQExprHierarchyLevelConverter.expand(expr, schema)) ||
11610 expr;
11611 }
11612 SQHierarchyExprUtils.expandExpr = expandExpr;
11613 function isHierarchyOrVariation(schema, expr) {
11614 if (expr instanceof data.SQHierarchyExpr || expr instanceof data.SQHierarchyLevelExpr)
11615 return true;
11616 var conceptualProperty = expr.getConceptualProperty(schema);
11617 if (conceptualProperty) {
11618 var column = conceptualProperty.column;
11619 if (column && column.variations && column.variations.length > 0)
11620 return true;
11621 }
11622 return false;
11623 }
11624 SQHierarchyExprUtils.isHierarchyOrVariation = isHierarchyOrVariation;
11625 // Return column reference expression for hierarchy level expression.
11626 function getSourceVariationExpr(hierarchyLevelExpr) {
11627 var fieldExprPattern = data.SQExprConverter.asFieldPattern(hierarchyLevelExpr);
11628 if (fieldExprPattern.columnHierarchyLevelVariation) {
11629 var entity = data.SQExprBuilder.entity(fieldExprPattern.columnHierarchyLevelVariation.source.schema, fieldExprPattern.columnHierarchyLevelVariation.source.entity);
11630 return data.SQExprBuilder.columnRef(entity, fieldExprPattern.columnHierarchyLevelVariation.source.name);
11631 }
11632 }
11633 SQHierarchyExprUtils.getSourceVariationExpr = getSourceVariationExpr;
11634 // Return hierarchy expression for hierarchy level expression.
11635 function getSourceHierarchy(hierarchyLevelExpr) {
11636 var fieldExprPattern = data.SQExprConverter.asFieldPattern(hierarchyLevelExpr);
11637 var hierarchyLevel = fieldExprPattern.hierarchyLevel;
11638 if (hierarchyLevel) {
11639 var entity = data.SQExprBuilder.entity(hierarchyLevel.schema, hierarchyLevel.entity, hierarchyLevel.entityVar);
11640 return data.SQExprBuilder.hierarchy(entity, hierarchyLevel.name);
11641 }
11642 }
11643 SQHierarchyExprUtils.getSourceHierarchy = getSourceHierarchy;
11644 function getHierarchySourceAsVariationSource(hierarchyLevelExpr) {
11645 // Make sure the hierarchy level source is a hierarchy
11646 if (!(hierarchyLevelExpr.arg instanceof data.SQHierarchyExpr))
11647 return;
11648 // Check if the hierarchy source if a variation
11649 var hierarchyRef = hierarchyLevelExpr.arg;
11650 if (hierarchyRef.arg instanceof data.SQPropertyVariationSourceExpr)
11651 return hierarchyRef.arg;
11652 }
11653 SQHierarchyExprUtils.getHierarchySourceAsVariationSource = getHierarchySourceAsVariationSource;
11654 /**
11655 * Returns true if firstExpr and secondExpr are levels in the same hierarchy and firstExpr is before secondExpr in allLevels.
11656 */
11657 function areHierarchyLevelsOrdered(allLevels, firstExpr, secondExpr) {
11658 // Validate that both items hierarchy levels
11659 if (!(firstExpr instanceof data.SQHierarchyLevelExpr) || !(secondExpr instanceof data.SQHierarchyLevelExpr))
11660 return false;
11661 var firstLevel = firstExpr;
11662 var secondLevel = secondExpr;
11663 // Validate that both items belong to the same hierarchy
11664 if (!data.SQExpr.equals(firstLevel.arg, secondLevel.arg))
11665 return false;
11666 // Determine the order
11667 var firstIndex = data.SQExprUtils.indexOfExpr(allLevels, firstLevel);
11668 var secondIndex = data.SQExprUtils.indexOfExpr(allLevels, secondLevel);
11669 return firstIndex !== -1 && secondIndex !== -1 && firstIndex < secondIndex;
11670 }
11671 SQHierarchyExprUtils.areHierarchyLevelsOrdered = areHierarchyLevelsOrdered;
11672 /**
11673 * Given an ordered set of levels and an ordered subset of those levels, returns the index where
11674 * expr should be inserted into the subset to maintain the correct order.
11675 */
11676 function getInsertionIndex(allLevels, orderedSubsetOfLevels, expr) {
11677 var insertIndex = 0;
11678 // Loop through the supplied levels until the insertion would no longer be in the correct order
11679 while (insertIndex < orderedSubsetOfLevels.length &&
11680 areHierarchyLevelsOrdered(allLevels, orderedSubsetOfLevels[insertIndex], expr)) {
11681 insertIndex++;
11682 }
11683 return insertIndex;
11684 }
11685 SQHierarchyExprUtils.getInsertionIndex = getInsertionIndex;
11686 })(SQHierarchyExprUtils = data.SQHierarchyExprUtils || (data.SQHierarchyExprUtils = {}));
11687 var SQExprHierarchyToHierarchyLevelConverter;
11688 (function (SQExprHierarchyToHierarchyLevelConverter) {
11689 function convert(sqExpr, federatedSchema) {
11690 debug.assertValue(sqExpr, 'sqExpr');
11691 debug.assertValue(federatedSchema, 'federatedSchema');
11692 if (sqExpr instanceof data.SQHierarchyExpr) {
11693 var hierarchyExpr = sqExpr;
11694 var conceptualHierarchy = SQHierarchyExprUtils.getConceptualHierarchy(hierarchyExpr, federatedSchema);
11695 if (conceptualHierarchy)
11696 return _.map(conceptualHierarchy.levels, function (hierarchyLevel) { return data.SQExprBuilder.hierarchyLevel(sqExpr, hierarchyLevel.name); });
11697 }
11698 }
11699 SQExprHierarchyToHierarchyLevelConverter.convert = convert;
11700 })(SQExprHierarchyToHierarchyLevelConverter = data.SQExprHierarchyToHierarchyLevelConverter || (data.SQExprHierarchyToHierarchyLevelConverter = {}));
11701 var SQExprHierarchyLevelConverter;
11702 (function (SQExprHierarchyLevelConverter) {
11703 function expand(expr, schema) {
11704 debug.assertValue(expr, 'sqExpr');
11705 debug.assertValue(schema, 'federatedSchema');
11706 var exprs = [];
11707 if (expr instanceof data.SQHierarchyLevelExpr) {
11708 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
11709 if (fieldExpr.hierarchyLevel) {
11710 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
11711 var hierarchy = schema
11712 .schema(fieldExprItem.schema)
11713 .findHierarchy(fieldExprItem.entity, fieldExpr.hierarchyLevel.name);
11714 if (hierarchy) {
11715 var hierarchyLevels = hierarchy.levels;
11716 for (var _i = 0, hierarchyLevels_2 = hierarchyLevels; _i < hierarchyLevels_2.length; _i++) {
11717 var hierarchyLevel = hierarchyLevels_2[_i];
11718 if (hierarchyLevel.name === fieldExpr.hierarchyLevel.level) {
11719 exprs.push(expr);
11720 break;
11721 }
11722 else
11723 exprs.push(data.SQExprBuilder.hierarchyLevel(data.SQExprBuilder.hierarchy(data.SQExprBuilder.entity(fieldExprItem.schema, fieldExprItem.entity, fieldExprItem.entityVar), hierarchy.name), hierarchyLevel.name));
11724 }
11725 }
11726 }
11727 }
11728 if (!_.isEmpty(exprs))
11729 return exprs;
11730 }
11731 SQExprHierarchyLevelConverter.expand = expand;
11732 })(SQExprHierarchyLevelConverter || (SQExprHierarchyLevelConverter = {}));
11733 var SQExprVariationConverter;
11734 (function (SQExprVariationConverter) {
11735 function expand(expr, schema) {
11736 debug.assertValue(expr, 'sqExpr');
11737 debug.assertValue(schema, 'federatedSchema');
11738 var exprs;
11739 var conceptualProperty = expr.getConceptualProperty(schema);
11740 if (conceptualProperty) {
11741 var column = conceptualProperty.column;
11742 if (column && column.variations && column.variations.length > 0) {
11743 var variations = column.variations;
11744 // for SU11, we support only one variation
11745 debug.assert(variations.length === 1, "variations.length");
11746 var variation = variations[0];
11747 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
11748 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
11749 exprs = [];
11750 if (variation.defaultHierarchy) {
11751 var hierarchyExpr = data.SQExprBuilder.hierarchy(data.SQExprBuilder.propertyVariationSource(data.SQExprBuilder.entity(fieldExprItem.schema, fieldExprItem.entity, fieldExprItem.entityVar), variation.name, conceptualProperty.name), variation.defaultHierarchy.name);
11752 for (var _i = 0, _a = variation.defaultHierarchy.levels; _i < _a.length; _i++) {
11753 var level = _a[_i];
11754 exprs.push(data.SQExprBuilder.hierarchyLevel(hierarchyExpr, level.name));
11755 }
11756 }
11757 }
11758 }
11759 return exprs;
11760 }
11761 SQExprVariationConverter.expand = expand;
11762 })(SQExprVariationConverter || (SQExprVariationConverter = {}));
11763 })(data = powerbi.data || (powerbi.data = {}));
11764})(powerbi || (powerbi = {}));
11765/*
11766 * Power BI Visualizations
11767 *
11768 * Copyright (c) Microsoft Corporation
11769 * All rights reserved.
11770 * MIT License
11771 *
11772 * Permission is hereby granted, free of charge, to any person obtaining a copy
11773 * of this software and associated documentation files (the ""Software""), to deal
11774 * in the Software without restriction, including without limitation the rights
11775 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11776 * copies of the Software, and to permit persons to whom the Software is
11777 * furnished to do so, subject to the following conditions:
11778 *
11779 * The above copyright notice and this permission notice shall be included in
11780 * all copies or substantial portions of the Software.
11781 *
11782 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11783 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11784 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11785 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11786 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11787 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11788 * THE SOFTWARE.
11789 */
11790var powerbi;
11791(function (powerbi) {
11792 var data;
11793 (function (data) {
11794 ;
11795 var SQExprGroupUtils;
11796 (function (SQExprGroupUtils) {
11797 /** Group all projections. Eacch group can consist of either a single property, or a collection of hierarchy items. */
11798 function groupExprs(schema, exprs) {
11799 var groups = [];
11800 for (var i = 0, len = exprs.length; i < len; i++) {
11801 var expr = exprs[i];
11802 debug.assertValue(expr, "Expression not found");
11803 if (!(expr instanceof data.SQHierarchyLevelExpr)) {
11804 groups.push({ expr: expr, children: null, selectQueryIndex: i });
11805 }
11806 else {
11807 addChildToGroup(schema, groups, expr, i);
11808 }
11809 }
11810 return groups;
11811 }
11812 SQExprGroupUtils.groupExprs = groupExprs;
11813 function addChildToGroup(schema, groups, expr, selectQueryIndex) {
11814 // shouldAddExpressionToNewGroup is used to control whether we should add the passed expr to
11815 // a new Group or to the last Group
11816 var shouldAddExpressionToNewGroup = true;
11817 var exprSource = data.SQHierarchyExprUtils.getSourceVariationExpr(expr) || data.SQHierarchyExprUtils.getSourceHierarchy(expr);
11818 var lastGroup = _.last(groups);
11819 // The relevant group is always the last added. If it has the same source hierarchy,
11820 // and is properly ordered within that hierarchy, we will need to add to this group.
11821 if (lastGroup && lastGroup.children && data.SQExpr.equals(lastGroup.expr, exprSource)) {
11822 var expandedExpr = data.SQHierarchyExprUtils.expandExpr(schema, expr.arg);
11823 if (expandedExpr instanceof Array) {
11824 var allHierarchyLevels = expandedExpr;
11825 shouldAddExpressionToNewGroup = !data.SQHierarchyExprUtils.areHierarchyLevelsOrdered(allHierarchyLevels, _.last(lastGroup.children), expr);
11826 }
11827 }
11828 if (shouldAddExpressionToNewGroup)
11829 // Use the Sourcevariation as the expression for the group.
11830 groups.push({ expr: exprSource, children: [expr], selectQueryIndex: selectQueryIndex });
11831 else {
11832 debug.assertValue(lastGroup, 'There should be a group to add the variation to');
11833 debug.assertValue(lastGroup.children, 'The group should have children to add the variation to');
11834 lastGroup.children.push(expr);
11835 }
11836 }
11837 })(SQExprGroupUtils = data.SQExprGroupUtils || (data.SQExprGroupUtils = {}));
11838 })(data = powerbi.data || (powerbi.data = {}));
11839})(powerbi || (powerbi = {}));
11840/*
11841 * Power BI Visualizations
11842 *
11843 * Copyright (c) Microsoft Corporation
11844 * All rights reserved.
11845 * MIT License
11846 *
11847 * Permission is hereby granted, free of charge, to any person obtaining a copy
11848 * of this software and associated documentation files (the ""Software""), to deal
11849 * in the Software without restriction, including without limitation the rights
11850 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11851 * copies of the Software, and to permit persons to whom the Software is
11852 * furnished to do so, subject to the following conditions:
11853 *
11854 * The above copyright notice and this permission notice shall be included in
11855 * all copies or substantial portions of the Software.
11856 *
11857 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11858 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11859 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11860 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11861 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11862 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11863 * THE SOFTWARE.
11864 */
11865var powerbi;
11866(function (powerbi) {
11867 var data;
11868 (function (data) {
11869 var StringExtensions = jsCommon.StringExtensions;
11870 /** Represents an immutable expression within a SemanticQuery. */
11871 var SQExpr = (function () {
11872 function SQExpr(kind) {
11873 debug.assertValue(kind, 'kind');
11874 this._kind = kind;
11875 }
11876 SQExpr.equals = function (x, y, ignoreCase) {
11877 return SQExprEqualityVisitor.run(x, y, ignoreCase);
11878 };
11879 SQExpr.prototype.validate = function (schema, aggrUtils, errors) {
11880 var validator = new SQExprValidationVisitor(schema, aggrUtils, errors);
11881 this.accept(validator);
11882 return validator.errors;
11883 };
11884 SQExpr.prototype.accept = function (visitor, arg) {
11885 debug.assertFail('abstract method');
11886 return;
11887 };
11888 Object.defineProperty(SQExpr.prototype, "kind", {
11889 get: function () {
11890 return this._kind;
11891 },
11892 enumerable: true,
11893 configurable: true
11894 });
11895 SQExpr.isColumn = function (expr) {
11896 debug.assertValue(expr, 'expr');
11897 return expr.kind === 1 /* ColumnRef */;
11898 };
11899 SQExpr.isConstant = function (expr) {
11900 debug.assertValue(expr, 'expr');
11901 return expr.kind === 16 /* Constant */;
11902 };
11903 SQExpr.isEntity = function (expr) {
11904 debug.assertValue(expr, 'expr');
11905 return expr.kind === 0 /* Entity */;
11906 };
11907 SQExpr.isHierarchy = function (expr) {
11908 debug.assertValue(expr, 'expr');
11909 return expr.kind === 5 /* Hierarchy */;
11910 };
11911 SQExpr.isHierarchyLevel = function (expr) {
11912 debug.assertValue(expr, 'expr');
11913 return expr.kind === 6 /* HierarchyLevel */;
11914 };
11915 SQExpr.isAggregation = function (expr) {
11916 debug.assertValue(expr, 'expr');
11917 return expr.kind === 3 /* Aggregation */;
11918 };
11919 SQExpr.isMeasure = function (expr) {
11920 debug.assertValue(expr, 'expr');
11921 return expr.kind === 2 /* MeasureRef */;
11922 };
11923 SQExpr.isSelectRef = function (expr) {
11924 debug.assertValue(expr, 'expr');
11925 return expr.kind === 28 /* SelectRef */;
11926 };
11927 SQExpr.isResourcePackageItem = function (expr) {
11928 debug.assertValue(expr, 'expr');
11929 return expr.kind === 24 /* ResourcePackageItem */;
11930 };
11931 SQExpr.prototype.getMetadata = function (federatedSchema) {
11932 debug.assertValue(federatedSchema, 'federatedSchema');
11933 var field = data.SQExprConverter.asFieldPattern(this);
11934 if (!field)
11935 return;
11936 if (field.column || field.columnAggr || field.measure)
11937 return this.getMetadataForProperty(field, federatedSchema);
11938 if (field.hierarchyLevel || field.hierarchyLevelAggr)
11939 return this.getMetadataForHierarchyLevel(field, federatedSchema);
11940 if (field.columnHierarchyLevelVariation)
11941 return this.getMetadataForVariation(field, federatedSchema);
11942 if (field.percentOfGrandTotal)
11943 return this.getMetadataForPercentOfGrandTotal();
11944 return SQExpr.getMetadataForEntity(field, federatedSchema);
11945 };
11946 SQExpr.prototype.getDefaultAggregate = function (federatedSchema, forceAggregation) {
11947 if (forceAggregation === void 0) { forceAggregation = false; }
11948 debug.assertValue(federatedSchema, 'federatedSchema');
11949 var property = this.getConceptualProperty(federatedSchema) || this.getHierarchyLevelConceptualProperty(federatedSchema);
11950 if (!property)
11951 return;
11952 var aggregate;
11953 if (property && property.kind === 0 /* Column */) {
11954 var propertyDefaultAggregate = property.column ? property.column.defaultAggregate : null;
11955 if ((property.type.integer || property.type.numeric) &&
11956 propertyDefaultAggregate !== 1 /* None */) {
11957 aggregate = defaultAggregateToQueryAggregateFunction(propertyDefaultAggregate);
11958 if (aggregate === undefined)
11959 aggregate = defaultAggregateForDataType(property.type);
11960 }
11961 // If we haven't found an appropriate aggregate, and want to force aggregation anyway,
11962 // aggregate on CountNonNull.
11963 if (aggregate === undefined && forceAggregation) {
11964 aggregate = data.QueryAggregateFunction.CountNonNull;
11965 }
11966 }
11967 return aggregate;
11968 };
11969 /** Return the SQExpr[] of group on columns if it has group on keys otherwise return the SQExpr of the column.*/
11970 SQExpr.prototype.getKeyColumns = function (schema) {
11971 var columnRefExpr = SQExprColumnRefInfoVisitor.getColumnRefSQExpr(schema, this);
11972 if (!columnRefExpr)
11973 return;
11974 var keySQExprs = [];
11975 var keys = this.getPropertyKeys(schema);
11976 if (keys && keys.length > 0) {
11977 for (var i = 0, len = keys.length; i < len; i++) {
11978 keySQExprs.push(SQExprBuilder.columnRef(columnRefExpr.source, keys[i].name));
11979 }
11980 }
11981 else
11982 keySQExprs.push(columnRefExpr);
11983 return keySQExprs;
11984 };
11985 /** Returns a value indicating whether the expression would group on keys other than itself.*/
11986 SQExpr.prototype.hasGroupOnKeys = function (schema) {
11987 var columnRefExpr = SQExprColumnRefInfoVisitor.getColumnRefSQExpr(schema, this);
11988 if (!columnRefExpr)
11989 return;
11990 var keys = this.getPropertyKeys(schema);
11991 if (!keys || keys.length < 1)
11992 return false;
11993 if (keys.length > 1)
11994 return true;
11995 var keySqExpr = SQExprBuilder.columnRef(columnRefExpr.source, keys[0].name);
11996 return !SQExpr.equals(keySqExpr, this);
11997 };
11998 SQExpr.prototype.getPropertyKeys = function (schema) {
11999 var property = this.getConceptualProperty(schema) || this.getHierarchyLevelConceptualProperty(schema);
12000 if (!property)
12001 return;
12002 return property.column ? property.column.keys : undefined;
12003 };
12004 SQExpr.prototype.getConceptualProperty = function (federatedSchema) {
12005 var field = data.SQExprConverter.asFieldPattern(this);
12006 if (!field)
12007 return;
12008 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(field);
12009 var propertyName = data.FieldExprPattern.getPropertyName(field);
12010 if (propertyName)
12011 return federatedSchema
12012 .schema(fieldExprItem.schema)
12013 .findProperty(fieldExprItem.entity, propertyName);
12014 };
12015 SQExpr.prototype.getTargetEntityForVariation = function (federatedSchema, variationName) {
12016 var property = this.getConceptualProperty(federatedSchema);
12017 if (property && property.column && !_.isEmpty(property.column.variations)) {
12018 var variations = property.column.variations;
12019 for (var _i = 0, variations_2 = variations; _i < variations_2.length; _i++) {
12020 var variation = variations_2[_i];
12021 if (variation.name === variationName)
12022 return variation.navigationProperty.targetEntity.name;
12023 }
12024 }
12025 };
12026 SQExpr.prototype.getTargetEntity = function (federatedSchema) {
12027 return SQEntityExprInfoVisitor.getEntityExpr(federatedSchema, this);
12028 };
12029 SQExpr.prototype.getHierarchyLevelConceptualProperty = function (federatedSchema) {
12030 var field = data.SQExprConverter.asFieldPattern(this);
12031 if (!field)
12032 return;
12033 var fieldExprHierachyLevel = field.hierarchyLevel || field.hierarchyLevelAggr;
12034 if (fieldExprHierachyLevel) {
12035 var fieldExprEntity = data.FieldExprPattern.toFieldExprEntityItemPattern(field);
12036 var hierarchy = federatedSchema
12037 .schema(fieldExprEntity.schema)
12038 .findHierarchy(fieldExprEntity.entity, fieldExprHierachyLevel.name);
12039 if (hierarchy) {
12040 var hierarchyLevel = hierarchy.levels.withName(fieldExprHierachyLevel.level);
12041 if (hierarchyLevel)
12042 return hierarchyLevel.column;
12043 }
12044 }
12045 };
12046 SQExpr.prototype.getMetadataForVariation = function (field, federatedSchema) {
12047 debug.assertValue(field, 'field');
12048 debug.assertValue(federatedSchema, 'federatedSchema');
12049 var columnHierarchyLevelVariation = field.columnHierarchyLevelVariation;
12050 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(field);
12051 var sourceProperty = federatedSchema
12052 .schema(fieldExprItem.schema)
12053 .findProperty(fieldExprItem.entity, columnHierarchyLevelVariation.source.name);
12054 if (sourceProperty && sourceProperty.column && sourceProperty.column.variations) {
12055 for (var _i = 0, _a = sourceProperty.column.variations; _i < _a.length; _i++) {
12056 var variation = _a[_i];
12057 if (variation.defaultHierarchy && variation.defaultHierarchy.levels) {
12058 for (var _b = 0, _c = variation.defaultHierarchy.levels; _b < _c.length; _b++) {
12059 var level = _c[_b];
12060 if (level.name === columnHierarchyLevelVariation.level.level) {
12061 var property = level.column;
12062 return {
12063 kind: (property.kind === 1 /* Measure */) ? 1 /* Measure */ : 0 /* Column */,
12064 type: property.type,
12065 format: property.format,
12066 idOnEntityKey: property.column ? property.column.idOnEntityKey : false,
12067 defaultAggregate: property.column ? property.column.defaultAggregate : null
12068 };
12069 }
12070 }
12071 }
12072 }
12073 }
12074 };
12075 SQExpr.prototype.getMetadataForHierarchyLevel = function (field, federatedSchema) {
12076 debug.assertValue(field, 'field');
12077 debug.assertValue(federatedSchema, 'federatedSchema');
12078 var property = this.getHierarchyLevelConceptualProperty(federatedSchema);
12079 if (!property)
12080 return;
12081 return this.getPropertyMetadata(field, property);
12082 };
12083 SQExpr.prototype.getMetadataForPercentOfGrandTotal = function () {
12084 return {
12085 kind: 1 /* Measure */,
12086 format: '#,##0.##%',
12087 type: powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Double)
12088 };
12089 };
12090 SQExpr.prototype.getPropertyMetadata = function (field, property) {
12091 var format = property.format;
12092 var type = property.type;
12093 var columnAggregate = field.columnAggr || field.hierarchyLevelAggr;
12094 if (columnAggregate) {
12095 switch (columnAggregate.aggregate) {
12096 case data.QueryAggregateFunction.Count:
12097 case data.QueryAggregateFunction.CountNonNull:
12098 type = powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Integer);
12099 format = undefined;
12100 break;
12101 case data.QueryAggregateFunction.Avg:
12102 if (type.integer)
12103 type = powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Double);
12104 break;
12105 }
12106 }
12107 return {
12108 kind: (property.kind === 1 /* Measure */ || (columnAggregate && columnAggregate.aggregate !== undefined)) ? 1 /* Measure */ : 0 /* Column */,
12109 type: type,
12110 format: format,
12111 idOnEntityKey: property.column ? property.column.idOnEntityKey : false,
12112 aggregate: columnAggregate ? columnAggregate.aggregate : undefined,
12113 defaultAggregate: property.column ? property.column.defaultAggregate : null
12114 };
12115 };
12116 SQExpr.prototype.getMetadataForProperty = function (field, federatedSchema) {
12117 debug.assertValue(field, 'field');
12118 debug.assertValue(federatedSchema, 'federatedSchema');
12119 var property = this.getConceptualProperty(federatedSchema);
12120 if (!property)
12121 return;
12122 return this.getPropertyMetadata(field, property);
12123 };
12124 SQExpr.getMetadataForEntity = function (field, federatedSchema) {
12125 debug.assertValue(field, 'field');
12126 debug.assertValue(federatedSchema, 'federatedSchema');
12127 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(field);
12128 var entity = federatedSchema
12129 .schema(fieldExprItem.schema)
12130 .entities
12131 .withName(fieldExprItem.entity);
12132 if (!entity)
12133 return;
12134 // We only support count and countnonnull for entity.
12135 if (field.entityAggr) {
12136 switch (field.entityAggr.aggregate) {
12137 case data.QueryAggregateFunction.Count:
12138 case data.QueryAggregateFunction.CountNonNull:
12139 return {
12140 kind: 1 /* Measure */,
12141 type: powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Integer),
12142 format: undefined,
12143 idOnEntityKey: false,
12144 aggregate: field.entityAggr.aggregate
12145 };
12146 }
12147 }
12148 };
12149 return SQExpr;
12150 }());
12151 data.SQExpr = SQExpr;
12152 /** Note: Exported for testability */
12153 function defaultAggregateForDataType(type) {
12154 if (type.integer || type.numeric)
12155 return data.QueryAggregateFunction.Sum;
12156 return data.QueryAggregateFunction.Count;
12157 }
12158 data.defaultAggregateForDataType = defaultAggregateForDataType;
12159 /** Note: Exported for testability */
12160 function defaultAggregateToQueryAggregateFunction(aggregate) {
12161 switch (aggregate) {
12162 case 6 /* Average */:
12163 return data.QueryAggregateFunction.Avg;
12164 case 3 /* Count */:
12165 return data.QueryAggregateFunction.CountNonNull;
12166 case 7 /* DistinctCount */:
12167 return data.QueryAggregateFunction.Count;
12168 case 5 /* Max */:
12169 return data.QueryAggregateFunction.Max;
12170 case 4 /* Min */:
12171 return data.QueryAggregateFunction.Min;
12172 case 2 /* Sum */:
12173 return data.QueryAggregateFunction.Sum;
12174 default:
12175 return;
12176 }
12177 }
12178 data.defaultAggregateToQueryAggregateFunction = defaultAggregateToQueryAggregateFunction;
12179 var SQEntityExpr = (function (_super) {
12180 __extends(SQEntityExpr, _super);
12181 function SQEntityExpr(schema, entity, variable) {
12182 debug.assertValue(entity, 'entity');
12183 _super.call(this, 0 /* Entity */);
12184 this.schema = schema;
12185 this.entity = entity;
12186 if (variable)
12187 this.variable = variable;
12188 }
12189 SQEntityExpr.prototype.accept = function (visitor, arg) {
12190 return visitor.visitEntity(this, arg);
12191 };
12192 return SQEntityExpr;
12193 }(SQExpr));
12194 data.SQEntityExpr = SQEntityExpr;
12195 var SQArithmeticExpr = (function (_super) {
12196 __extends(SQArithmeticExpr, _super);
12197 function SQArithmeticExpr(left, right, operator) {
12198 debug.assertValue(left, 'left');
12199 debug.assertValue(right, 'right');
12200 debug.assertValue(operator, 'operator');
12201 _super.call(this, 22 /* Arithmetic */);
12202 this.left = left;
12203 this.right = right;
12204 this.operator = operator;
12205 }
12206 SQArithmeticExpr.prototype.accept = function (visitor, arg) {
12207 return visitor.visitArithmetic(this, arg);
12208 };
12209 return SQArithmeticExpr;
12210 }(SQExpr));
12211 data.SQArithmeticExpr = SQArithmeticExpr;
12212 var SQScopedEvalExpr = (function (_super) {
12213 __extends(SQScopedEvalExpr, _super);
12214 function SQScopedEvalExpr(expression, scope) {
12215 debug.assertValue(expression, 'expression');
12216 debug.assertValue(scope, 'scope');
12217 _super.call(this, 25 /* ScopedEval */);
12218 this.expression = expression;
12219 this.scope = scope;
12220 }
12221 SQScopedEvalExpr.prototype.accept = function (visitor, arg) {
12222 return visitor.visitScopedEval(this, arg);
12223 };
12224 SQScopedEvalExpr.prototype.getMetadata = function (federatedSchema) {
12225 return this.expression.getMetadata(federatedSchema);
12226 };
12227 return SQScopedEvalExpr;
12228 }(SQExpr));
12229 data.SQScopedEvalExpr = SQScopedEvalExpr;
12230 var SQPropRefExpr = (function (_super) {
12231 __extends(SQPropRefExpr, _super);
12232 function SQPropRefExpr(kind, source, ref) {
12233 debug.assertValue(kind, 'kind');
12234 debug.assertValue(source, 'source');
12235 debug.assertValue(ref, 'ref');
12236 _super.call(this, kind);
12237 this.source = source;
12238 this.ref = ref;
12239 }
12240 return SQPropRefExpr;
12241 }(SQExpr));
12242 data.SQPropRefExpr = SQPropRefExpr;
12243 var SQColumnRefExpr = (function (_super) {
12244 __extends(SQColumnRefExpr, _super);
12245 function SQColumnRefExpr(source, ref) {
12246 _super.call(this, 1 /* ColumnRef */, source, ref);
12247 }
12248 SQColumnRefExpr.prototype.accept = function (visitor, arg) {
12249 return visitor.visitColumnRef(this, arg);
12250 };
12251 return SQColumnRefExpr;
12252 }(SQPropRefExpr));
12253 data.SQColumnRefExpr = SQColumnRefExpr;
12254 var SQMeasureRefExpr = (function (_super) {
12255 __extends(SQMeasureRefExpr, _super);
12256 function SQMeasureRefExpr(source, ref) {
12257 _super.call(this, 2 /* MeasureRef */, source, ref);
12258 }
12259 SQMeasureRefExpr.prototype.accept = function (visitor, arg) {
12260 return visitor.visitMeasureRef(this, arg);
12261 };
12262 return SQMeasureRefExpr;
12263 }(SQPropRefExpr));
12264 data.SQMeasureRefExpr = SQMeasureRefExpr;
12265 var SQAggregationExpr = (function (_super) {
12266 __extends(SQAggregationExpr, _super);
12267 function SQAggregationExpr(arg, func) {
12268 debug.assertValue(arg, 'arg');
12269 debug.assertValue(func, 'func');
12270 _super.call(this, 3 /* Aggregation */);
12271 this.arg = arg;
12272 this.func = func;
12273 }
12274 SQAggregationExpr.prototype.accept = function (visitor, arg) {
12275 return visitor.visitAggr(this, arg);
12276 };
12277 return SQAggregationExpr;
12278 }(SQExpr));
12279 data.SQAggregationExpr = SQAggregationExpr;
12280 var SQPercentileExpr = (function (_super) {
12281 __extends(SQPercentileExpr, _super);
12282 function SQPercentileExpr(arg, k, exclusive) {
12283 debug.assertValue(arg, 'arg');
12284 debug.assertValue(k, 'k');
12285 debug.assert(0 <= k && k <= 1, '0 <= k && k <= 1');
12286 debug.assertValue(exclusive, 'exclusive');
12287 _super.call(this, 27 /* Percentile */);
12288 this.arg = arg;
12289 this.k = k;
12290 this.exclusive = exclusive;
12291 }
12292 SQPercentileExpr.prototype.getMetadata = function (federatedSchema) {
12293 debug.assertValue(federatedSchema, 'federatedSchema');
12294 var argMetadata = this.arg.getMetadata(federatedSchema);
12295 if (argMetadata) {
12296 return {
12297 kind: 1 /* Measure */,
12298 type: argMetadata.type,
12299 };
12300 }
12301 };
12302 SQPercentileExpr.prototype.accept = function (visitor, arg) {
12303 return visitor.visitPercentile(this, arg);
12304 };
12305 return SQPercentileExpr;
12306 }(SQExpr));
12307 data.SQPercentileExpr = SQPercentileExpr;
12308 var SQPropertyVariationSourceExpr = (function (_super) {
12309 __extends(SQPropertyVariationSourceExpr, _super);
12310 function SQPropertyVariationSourceExpr(arg, name, property) {
12311 debug.assertValue(arg, 'arg');
12312 debug.assertValue(name, 'name');
12313 debug.assertValue(property, 'property');
12314 _super.call(this, 4 /* PropertyVariationSource */);
12315 this.arg = arg;
12316 this.name = name;
12317 this.property = property;
12318 }
12319 SQPropertyVariationSourceExpr.prototype.accept = function (visitor, arg) {
12320 return visitor.visitPropertyVariationSource(this, arg);
12321 };
12322 return SQPropertyVariationSourceExpr;
12323 }(SQExpr));
12324 data.SQPropertyVariationSourceExpr = SQPropertyVariationSourceExpr;
12325 var SQHierarchyExpr = (function (_super) {
12326 __extends(SQHierarchyExpr, _super);
12327 function SQHierarchyExpr(arg, hierarchy) {
12328 debug.assertValue(arg, 'arg');
12329 debug.assertValue(hierarchy, 'hierarchy');
12330 _super.call(this, 5 /* Hierarchy */);
12331 this.arg = arg;
12332 this.hierarchy = hierarchy;
12333 }
12334 SQHierarchyExpr.prototype.accept = function (visitor, arg) {
12335 return visitor.visitHierarchy(this, arg);
12336 };
12337 return SQHierarchyExpr;
12338 }(SQExpr));
12339 data.SQHierarchyExpr = SQHierarchyExpr;
12340 var SQHierarchyLevelExpr = (function (_super) {
12341 __extends(SQHierarchyLevelExpr, _super);
12342 function SQHierarchyLevelExpr(arg, level) {
12343 debug.assertValue(arg, 'arg');
12344 debug.assertValue(level, 'level');
12345 _super.call(this, 6 /* HierarchyLevel */);
12346 this.arg = arg;
12347 this.level = level;
12348 }
12349 SQHierarchyLevelExpr.prototype.accept = function (visitor, arg) {
12350 return visitor.visitHierarchyLevel(this, arg);
12351 };
12352 return SQHierarchyLevelExpr;
12353 }(SQExpr));
12354 data.SQHierarchyLevelExpr = SQHierarchyLevelExpr;
12355 var SQSelectRefExpr = (function (_super) {
12356 __extends(SQSelectRefExpr, _super);
12357 function SQSelectRefExpr(expressionName) {
12358 debug.assertValue(expressionName, 'arg');
12359 _super.call(this, 28 /* SelectRef */);
12360 this.expressionName = expressionName;
12361 }
12362 SQSelectRefExpr.prototype.accept = function (visitor, arg) {
12363 return visitor.visitSelectRef(this, arg);
12364 };
12365 return SQSelectRefExpr;
12366 }(SQExpr));
12367 data.SQSelectRefExpr = SQSelectRefExpr;
12368 var SQAndExpr = (function (_super) {
12369 __extends(SQAndExpr, _super);
12370 function SQAndExpr(left, right) {
12371 debug.assertValue(left, 'left');
12372 debug.assertValue(right, 'right');
12373 _super.call(this, 7 /* And */);
12374 this.left = left;
12375 this.right = right;
12376 }
12377 SQAndExpr.prototype.accept = function (visitor, arg) {
12378 return visitor.visitAnd(this, arg);
12379 };
12380 return SQAndExpr;
12381 }(SQExpr));
12382 data.SQAndExpr = SQAndExpr;
12383 var SQBetweenExpr = (function (_super) {
12384 __extends(SQBetweenExpr, _super);
12385 function SQBetweenExpr(arg, lower, upper) {
12386 debug.assertValue(arg, 'arg');
12387 debug.assertValue(lower, 'lower');
12388 debug.assertValue(upper, 'upper');
12389 _super.call(this, 8 /* Between */);
12390 this.arg = arg;
12391 this.lower = lower;
12392 this.upper = upper;
12393 }
12394 SQBetweenExpr.prototype.accept = function (visitor, arg) {
12395 return visitor.visitBetween(this, arg);
12396 };
12397 return SQBetweenExpr;
12398 }(SQExpr));
12399 data.SQBetweenExpr = SQBetweenExpr;
12400 var SQInExpr = (function (_super) {
12401 __extends(SQInExpr, _super);
12402 function SQInExpr(args, values) {
12403 debug.assertValue(args, 'args');
12404 debug.assertValue(values, 'values');
12405 _super.call(this, 9 /* In */);
12406 this.args = args;
12407 this.values = values;
12408 }
12409 SQInExpr.prototype.accept = function (visitor, arg) {
12410 return visitor.visitIn(this, arg);
12411 };
12412 return SQInExpr;
12413 }(SQExpr));
12414 data.SQInExpr = SQInExpr;
12415 var SQOrExpr = (function (_super) {
12416 __extends(SQOrExpr, _super);
12417 function SQOrExpr(left, right) {
12418 debug.assertValue(left, 'left');
12419 debug.assertValue(right, 'right');
12420 _super.call(this, 10 /* Or */);
12421 this.left = left;
12422 this.right = right;
12423 }
12424 SQOrExpr.prototype.accept = function (visitor, arg) {
12425 return visitor.visitOr(this, arg);
12426 };
12427 return SQOrExpr;
12428 }(SQExpr));
12429 data.SQOrExpr = SQOrExpr;
12430 var SQCompareExpr = (function (_super) {
12431 __extends(SQCompareExpr, _super);
12432 function SQCompareExpr(comparison, left, right) {
12433 debug.assertValue(comparison, 'kind');
12434 debug.assertValue(left, 'left');
12435 debug.assertValue(right, 'right');
12436 _super.call(this, 12 /* Compare */);
12437 this.comparison = comparison;
12438 this.left = left;
12439 this.right = right;
12440 }
12441 SQCompareExpr.prototype.accept = function (visitor, arg) {
12442 return visitor.visitCompare(this, arg);
12443 };
12444 return SQCompareExpr;
12445 }(SQExpr));
12446 data.SQCompareExpr = SQCompareExpr;
12447 var SQContainsExpr = (function (_super) {
12448 __extends(SQContainsExpr, _super);
12449 function SQContainsExpr(left, right) {
12450 debug.assertValue(left, 'left');
12451 debug.assertValue(right, 'right');
12452 _super.call(this, 11 /* Contains */);
12453 this.left = left;
12454 this.right = right;
12455 }
12456 SQContainsExpr.prototype.accept = function (visitor, arg) {
12457 return visitor.visitContains(this, arg);
12458 };
12459 return SQContainsExpr;
12460 }(SQExpr));
12461 data.SQContainsExpr = SQContainsExpr;
12462 var SQStartsWithExpr = (function (_super) {
12463 __extends(SQStartsWithExpr, _super);
12464 function SQStartsWithExpr(left, right) {
12465 debug.assertValue(left, 'left');
12466 debug.assertValue(right, 'right');
12467 _super.call(this, 13 /* StartsWith */);
12468 this.left = left;
12469 this.right = right;
12470 }
12471 SQStartsWithExpr.prototype.accept = function (visitor, arg) {
12472 return visitor.visitStartsWith(this, arg);
12473 };
12474 return SQStartsWithExpr;
12475 }(SQExpr));
12476 data.SQStartsWithExpr = SQStartsWithExpr;
12477 var SQExistsExpr = (function (_super) {
12478 __extends(SQExistsExpr, _super);
12479 function SQExistsExpr(arg) {
12480 debug.assertValue(arg, 'arg');
12481 _super.call(this, 14 /* Exists */);
12482 this.arg = arg;
12483 }
12484 SQExistsExpr.prototype.accept = function (visitor, arg) {
12485 return visitor.visitExists(this, arg);
12486 };
12487 return SQExistsExpr;
12488 }(SQExpr));
12489 data.SQExistsExpr = SQExistsExpr;
12490 var SQNotExpr = (function (_super) {
12491 __extends(SQNotExpr, _super);
12492 function SQNotExpr(arg) {
12493 debug.assertValue(arg, 'arg');
12494 _super.call(this, 15 /* Not */);
12495 this.arg = arg;
12496 }
12497 SQNotExpr.prototype.accept = function (visitor, arg) {
12498 return visitor.visitNot(this, arg);
12499 };
12500 return SQNotExpr;
12501 }(SQExpr));
12502 data.SQNotExpr = SQNotExpr;
12503 var SQConstantExpr = (function (_super) {
12504 __extends(SQConstantExpr, _super);
12505 function SQConstantExpr(type, value, valueEncoded) {
12506 debug.assertValue(type, 'type');
12507 _super.call(this, 16 /* Constant */);
12508 this.type = type;
12509 this.value = value;
12510 this.valueEncoded = valueEncoded;
12511 }
12512 SQConstantExpr.prototype.accept = function (visitor, arg) {
12513 return visitor.visitConstant(this, arg);
12514 };
12515 SQConstantExpr.prototype.getMetadata = function (federatedSchema) {
12516 debug.assertValue(federatedSchema, 'federatedSchema');
12517 return {
12518 // Returning Measure as the kind for a SQConstantExpr is slightly ambiguous allowing the return object to conform to SQEXprMetadata.
12519 // A getType or similiar function in the future would be more appropriate.
12520 kind: 1 /* Measure */,
12521 type: this.type,
12522 };
12523 };
12524 return SQConstantExpr;
12525 }(SQExpr));
12526 data.SQConstantExpr = SQConstantExpr;
12527 var SQDateSpanExpr = (function (_super) {
12528 __extends(SQDateSpanExpr, _super);
12529 function SQDateSpanExpr(unit, arg) {
12530 debug.assertValue(unit, 'unit');
12531 debug.assertValue(arg, 'arg');
12532 _super.call(this, 17 /* DateSpan */);
12533 this.unit = unit;
12534 this.arg = arg;
12535 }
12536 SQDateSpanExpr.prototype.accept = function (visitor, arg) {
12537 return visitor.visitDateSpan(this, arg);
12538 };
12539 return SQDateSpanExpr;
12540 }(SQExpr));
12541 data.SQDateSpanExpr = SQDateSpanExpr;
12542 var SQDateAddExpr = (function (_super) {
12543 __extends(SQDateAddExpr, _super);
12544 function SQDateAddExpr(unit, amount, arg) {
12545 debug.assertValue(unit, 'unit');
12546 debug.assertValue(amount, 'amount');
12547 debug.assertValue(arg, 'arg');
12548 _super.call(this, 18 /* DateAdd */);
12549 this.unit = unit;
12550 this.arg = arg;
12551 this.amount = amount;
12552 }
12553 SQDateAddExpr.prototype.accept = function (visitor, arg) {
12554 return visitor.visitDateAdd(this, arg);
12555 };
12556 return SQDateAddExpr;
12557 }(SQExpr));
12558 data.SQDateAddExpr = SQDateAddExpr;
12559 var SQNowExpr = (function (_super) {
12560 __extends(SQNowExpr, _super);
12561 function SQNowExpr() {
12562 _super.call(this, 19 /* Now */);
12563 }
12564 SQNowExpr.prototype.accept = function (visitor, arg) {
12565 return visitor.visitNow(this, arg);
12566 };
12567 return SQNowExpr;
12568 }(SQExpr));
12569 data.SQNowExpr = SQNowExpr;
12570 var SQDefaultValueExpr = (function (_super) {
12571 __extends(SQDefaultValueExpr, _super);
12572 function SQDefaultValueExpr() {
12573 _super.call(this, 21 /* DefaultValue */);
12574 }
12575 SQDefaultValueExpr.prototype.accept = function (visitor, arg) {
12576 return visitor.visitDefaultValue(this, arg);
12577 };
12578 return SQDefaultValueExpr;
12579 }(SQExpr));
12580 data.SQDefaultValueExpr = SQDefaultValueExpr;
12581 var SQAnyValueExpr = (function (_super) {
12582 __extends(SQAnyValueExpr, _super);
12583 function SQAnyValueExpr() {
12584 _super.call(this, 20 /* AnyValue */);
12585 }
12586 SQAnyValueExpr.prototype.accept = function (visitor, arg) {
12587 return visitor.visitAnyValue(this, arg);
12588 };
12589 return SQAnyValueExpr;
12590 }(SQExpr));
12591 data.SQAnyValueExpr = SQAnyValueExpr;
12592 var SQFillRuleExpr = (function (_super) {
12593 __extends(SQFillRuleExpr, _super);
12594 function SQFillRuleExpr(input, fillRule) {
12595 debug.assertValue(input, 'input');
12596 debug.assertValue(fillRule, 'fillRule');
12597 _super.call(this, 23 /* FillRule */);
12598 this.input = input;
12599 this.rule = fillRule;
12600 }
12601 SQFillRuleExpr.prototype.accept = function (visitor, arg) {
12602 return visitor.visitFillRule(this, arg);
12603 };
12604 return SQFillRuleExpr;
12605 }(SQExpr));
12606 data.SQFillRuleExpr = SQFillRuleExpr;
12607 var SQResourcePackageItemExpr = (function (_super) {
12608 __extends(SQResourcePackageItemExpr, _super);
12609 function SQResourcePackageItemExpr(packageName, packageType, itemName) {
12610 debug.assertValue(packageName, 'packageName');
12611 debug.assertValue(itemName, 'itemName');
12612 _super.call(this, 24 /* ResourcePackageItem */);
12613 this.packageName = packageName;
12614 this.packageType = packageType;
12615 this.itemName = itemName;
12616 }
12617 SQResourcePackageItemExpr.prototype.accept = function (visitor, arg) {
12618 return visitor.visitResourcePackageItem(this, arg);
12619 };
12620 return SQResourcePackageItemExpr;
12621 }(SQExpr));
12622 data.SQResourcePackageItemExpr = SQResourcePackageItemExpr;
12623 /** Provides utilities for creating & manipulating expressions. */
12624 var SQExprBuilder;
12625 (function (SQExprBuilder) {
12626 function entity(schema, entity, variable) {
12627 return new SQEntityExpr(schema, entity, variable);
12628 }
12629 SQExprBuilder.entity = entity;
12630 function columnRef(source, prop) {
12631 return new SQColumnRefExpr(source, prop);
12632 }
12633 SQExprBuilder.columnRef = columnRef;
12634 function measureRef(source, prop) {
12635 return new SQMeasureRefExpr(source, prop);
12636 }
12637 SQExprBuilder.measureRef = measureRef;
12638 function aggregate(source, aggregate) {
12639 return new SQAggregationExpr(source, aggregate);
12640 }
12641 SQExprBuilder.aggregate = aggregate;
12642 function selectRef(expressionName) {
12643 return new SQSelectRefExpr(expressionName);
12644 }
12645 SQExprBuilder.selectRef = selectRef;
12646 function percentile(source, k, exclusive) {
12647 return new SQPercentileExpr(source, k, exclusive);
12648 }
12649 SQExprBuilder.percentile = percentile;
12650 function arithmetic(left, right, operator) {
12651 return new SQArithmeticExpr(left, right, operator);
12652 }
12653 SQExprBuilder.arithmetic = arithmetic;
12654 function scopedEval(expression, scope) {
12655 return new SQScopedEvalExpr(expression, scope);
12656 }
12657 SQExprBuilder.scopedEval = scopedEval;
12658 function hierarchy(source, hierarchy) {
12659 return new SQHierarchyExpr(source, hierarchy);
12660 }
12661 SQExprBuilder.hierarchy = hierarchy;
12662 function propertyVariationSource(source, name, property) {
12663 return new SQPropertyVariationSourceExpr(source, name, property);
12664 }
12665 SQExprBuilder.propertyVariationSource = propertyVariationSource;
12666 function hierarchyLevel(source, level) {
12667 return new SQHierarchyLevelExpr(source, level);
12668 }
12669 SQExprBuilder.hierarchyLevel = hierarchyLevel;
12670 function and(left, right) {
12671 if (!left)
12672 return right;
12673 if (!right)
12674 return left;
12675 return new SQAndExpr(left, right);
12676 }
12677 SQExprBuilder.and = and;
12678 function between(arg, lower, upper) {
12679 return new SQBetweenExpr(arg, lower, upper);
12680 }
12681 SQExprBuilder.between = between;
12682 function inExpr(args, values) {
12683 return new SQInExpr(args, values);
12684 }
12685 SQExprBuilder.inExpr = inExpr;
12686 function or(left, right) {
12687 if (!left)
12688 return right;
12689 if (!right)
12690 return left;
12691 if (left instanceof SQInExpr && right instanceof SQInExpr) {
12692 var inExpr_1 = tryUseInExprs(left, right);
12693 if (inExpr_1)
12694 return inExpr_1;
12695 }
12696 return new SQOrExpr(left, right);
12697 }
12698 SQExprBuilder.or = or;
12699 function tryUseInExprs(left, right) {
12700 if (!left.args || !right.args)
12701 return;
12702 var leftArgLen = left.args.length;
12703 var rightArgLen = right.args.length;
12704 if (leftArgLen !== rightArgLen)
12705 return;
12706 for (var i = 0; i < leftArgLen; ++i) {
12707 if (!SQExpr.equals(left.args[i], right.args[i]))
12708 return;
12709 }
12710 var combinedValues = left.values.concat(right.values);
12711 return SQExprBuilder.inExpr(left.args, combinedValues);
12712 }
12713 function compare(kind, left, right) {
12714 return new SQCompareExpr(kind, left, right);
12715 }
12716 SQExprBuilder.compare = compare;
12717 function contains(left, right) {
12718 return new SQContainsExpr(left, right);
12719 }
12720 SQExprBuilder.contains = contains;
12721 function exists(arg) {
12722 return new SQExistsExpr(arg);
12723 }
12724 SQExprBuilder.exists = exists;
12725 function equal(left, right) {
12726 return compare(data.QueryComparisonKind.Equal, left, right);
12727 }
12728 SQExprBuilder.equal = equal;
12729 function not(arg) {
12730 return new SQNotExpr(arg);
12731 }
12732 SQExprBuilder.not = not;
12733 function startsWith(left, right) {
12734 return new SQStartsWithExpr(left, right);
12735 }
12736 SQExprBuilder.startsWith = startsWith;
12737 function nullConstant() {
12738 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Null), null, data.PrimitiveValueEncoding.nullEncoding());
12739 }
12740 SQExprBuilder.nullConstant = nullConstant;
12741 function now() {
12742 return new SQNowExpr();
12743 }
12744 SQExprBuilder.now = now;
12745 function defaultValue() {
12746 return new SQDefaultValueExpr();
12747 }
12748 SQExprBuilder.defaultValue = defaultValue;
12749 function anyValue() {
12750 return new SQAnyValueExpr();
12751 }
12752 SQExprBuilder.anyValue = anyValue;
12753 function boolean(value) {
12754 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Boolean), value, data.PrimitiveValueEncoding.boolean(value));
12755 }
12756 SQExprBuilder.boolean = boolean;
12757 function dateAdd(unit, amount, arg) {
12758 return new SQDateAddExpr(unit, amount, arg);
12759 }
12760 SQExprBuilder.dateAdd = dateAdd;
12761 function dateTime(value, valueEncoded) {
12762 if (valueEncoded === undefined)
12763 valueEncoded = data.PrimitiveValueEncoding.dateTime(value);
12764 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.DateTime), value, valueEncoded);
12765 }
12766 SQExprBuilder.dateTime = dateTime;
12767 function dateSpan(unit, arg) {
12768 return new SQDateSpanExpr(unit, arg);
12769 }
12770 SQExprBuilder.dateSpan = dateSpan;
12771 function decimal(value, valueEncoded) {
12772 if (valueEncoded === undefined)
12773 valueEncoded = data.PrimitiveValueEncoding.decimal(value);
12774 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Decimal), value, valueEncoded);
12775 }
12776 SQExprBuilder.decimal = decimal;
12777 function double(value, valueEncoded) {
12778 if (valueEncoded === undefined)
12779 valueEncoded = data.PrimitiveValueEncoding.double(value);
12780 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Double), value, valueEncoded);
12781 }
12782 SQExprBuilder.double = double;
12783 function integer(value, valueEncoded) {
12784 if (valueEncoded === undefined)
12785 valueEncoded = data.PrimitiveValueEncoding.integer(value);
12786 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Integer), value, valueEncoded);
12787 }
12788 SQExprBuilder.integer = integer;
12789 function text(value, valueEncoded) {
12790 debug.assert(!valueEncoded || valueEncoded === data.PrimitiveValueEncoding.text(value), 'Incorrect encoded value specified.');
12791 return new SQConstantExpr(powerbi.ValueType.fromExtendedType(powerbi.ExtendedType.Text), value, valueEncoded || data.PrimitiveValueEncoding.text(value));
12792 }
12793 SQExprBuilder.text = text;
12794 /** Returns an SQExpr that evaluates to the constant value. */
12795 function typedConstant(value, type) {
12796 if (value == null)
12797 return nullConstant();
12798 if (_.isBoolean(value)) {
12799 return boolean(value);
12800 }
12801 if (_.isString(value)) {
12802 return text(value);
12803 }
12804 if (_.isNumber(value)) {
12805 if (type.integer && powerbi.Double.isInteger(value))
12806 return integer(value);
12807 return double(value);
12808 }
12809 if (value instanceof Date) {
12810 return dateTime(value);
12811 }
12812 }
12813 SQExprBuilder.typedConstant = typedConstant;
12814 function setAggregate(expr, aggregate) {
12815 return FieldExprChangeAggregateRewriter.rewrite(expr, aggregate);
12816 }
12817 SQExprBuilder.setAggregate = setAggregate;
12818 function removeAggregate(expr) {
12819 return FieldExprRemoveAggregateRewriter.rewrite(expr);
12820 }
12821 SQExprBuilder.removeAggregate = removeAggregate;
12822 function setPercentOfGrandTotal(expr) {
12823 return SQExprSetPercentOfGrandTotalRewriter.rewrite(expr);
12824 }
12825 SQExprBuilder.setPercentOfGrandTotal = setPercentOfGrandTotal;
12826 function removePercentOfGrandTotal(expr) {
12827 return SQExprRemovePercentOfGrandTotalRewriter.rewrite(expr);
12828 }
12829 SQExprBuilder.removePercentOfGrandTotal = removePercentOfGrandTotal;
12830 function removeEntityVariables(expr) {
12831 return SQExprRemoveEntityVariablesRewriter.rewrite(expr);
12832 }
12833 SQExprBuilder.removeEntityVariables = removeEntityVariables;
12834 function fillRule(expr, rule) {
12835 debug.assertValue(expr, 'expr');
12836 debug.assertValue(rule, 'rule');
12837 return new SQFillRuleExpr(expr, rule);
12838 }
12839 SQExprBuilder.fillRule = fillRule;
12840 function resourcePackageItem(packageName, packageType, itemName) {
12841 return new SQResourcePackageItemExpr(packageName, packageType, itemName);
12842 }
12843 SQExprBuilder.resourcePackageItem = resourcePackageItem;
12844 })(SQExprBuilder = data.SQExprBuilder || (data.SQExprBuilder = {}));
12845 /** Provides utilities for obtaining information about expressions. */
12846 var SQExprInfo;
12847 (function (SQExprInfo) {
12848 function getAggregate(expr) {
12849 return SQExprAggregateInfoVisitor.getAggregate(expr);
12850 }
12851 SQExprInfo.getAggregate = getAggregate;
12852 })(SQExprInfo = data.SQExprInfo || (data.SQExprInfo = {}));
12853 var SQExprEqualityVisitor = (function () {
12854 function SQExprEqualityVisitor(ignoreCase) {
12855 this.ignoreCase = ignoreCase;
12856 }
12857 SQExprEqualityVisitor.run = function (x, y, ignoreCase) {
12858 // Normalize falsy to null
12859 x = x || null;
12860 y = y || null;
12861 if (x === y)
12862 return true;
12863 if (!x !== !y)
12864 return false;
12865 debug.assertValue(x, 'x');
12866 debug.assertValue(y, 'y');
12867 if (ignoreCase)
12868 return x.accept(SQExprEqualityVisitor.ignoreCaseInstance, y);
12869 return x.accept(SQExprEqualityVisitor.instance, y);
12870 };
12871 SQExprEqualityVisitor.prototype.visitColumnRef = function (expr, comparand) {
12872 return comparand instanceof SQColumnRefExpr &&
12873 expr.ref === comparand.ref &&
12874 this.equals(expr.source, comparand.source);
12875 };
12876 SQExprEqualityVisitor.prototype.visitMeasureRef = function (expr, comparand) {
12877 return comparand instanceof SQMeasureRefExpr &&
12878 expr.ref === comparand.ref &&
12879 this.equals(expr.source, comparand.source);
12880 };
12881 SQExprEqualityVisitor.prototype.visitAggr = function (expr, comparand) {
12882 return comparand instanceof SQAggregationExpr &&
12883 expr.func === comparand.func &&
12884 this.equals(expr.arg, comparand.arg);
12885 };
12886 SQExprEqualityVisitor.prototype.visitPercentile = function (expr, comparand) {
12887 return comparand instanceof SQPercentileExpr &&
12888 expr.exclusive === comparand.exclusive &&
12889 expr.k === comparand.k &&
12890 this.equals(expr.arg, comparand.arg);
12891 };
12892 SQExprEqualityVisitor.prototype.visitHierarchy = function (expr, comparand) {
12893 return comparand instanceof SQHierarchyExpr &&
12894 expr.hierarchy === comparand.hierarchy &&
12895 this.equals(expr.arg, comparand.arg);
12896 };
12897 SQExprEqualityVisitor.prototype.visitHierarchyLevel = function (expr, comparand) {
12898 return comparand instanceof SQHierarchyLevelExpr &&
12899 expr.level === comparand.level &&
12900 this.equals(expr.arg, comparand.arg);
12901 };
12902 SQExprEqualityVisitor.prototype.visitPropertyVariationSource = function (expr, comparand) {
12903 return comparand instanceof SQPropertyVariationSourceExpr &&
12904 expr.name === comparand.name &&
12905 expr.property === comparand.property &&
12906 this.equals(expr.arg, comparand.arg);
12907 };
12908 SQExprEqualityVisitor.prototype.visitSelectRef = function (expr, comparand) {
12909 return comparand instanceof SQSelectRefExpr &&
12910 expr.expressionName === comparand.expressionName;
12911 };
12912 SQExprEqualityVisitor.prototype.visitBetween = function (expr, comparand) {
12913 return comparand instanceof SQBetweenExpr &&
12914 this.equals(expr.arg, comparand.arg) &&
12915 this.equals(expr.lower, comparand.lower) &&
12916 this.equals(expr.upper, comparand.upper);
12917 };
12918 SQExprEqualityVisitor.prototype.visitIn = function (expr, comparand) {
12919 if (!(comparand instanceof SQInExpr) || !this.equalsAll(expr.args, comparand.args))
12920 return false;
12921 var values = expr.values, compareValues = comparand.values;
12922 if (values.length !== compareValues.length)
12923 return false;
12924 for (var i = 0, len = values.length; i < len; i++) {
12925 if (!this.equalsAll(values[i], compareValues[i]))
12926 return false;
12927 }
12928 return true;
12929 };
12930 SQExprEqualityVisitor.prototype.visitEntity = function (expr, comparand) {
12931 return comparand instanceof SQEntityExpr &&
12932 expr.schema === comparand.schema &&
12933 expr.entity === comparand.entity &&
12934 this.optionalEqual(expr.variable, comparand.variable);
12935 };
12936 SQExprEqualityVisitor.prototype.visitAnd = function (expr, comparand) {
12937 return comparand instanceof SQAndExpr &&
12938 this.equals(expr.left, comparand.left) &&
12939 this.equals(expr.right, comparand.right);
12940 };
12941 SQExprEqualityVisitor.prototype.visitOr = function (expr, comparand) {
12942 return comparand instanceof SQOrExpr &&
12943 this.equals(expr.left, comparand.left) &&
12944 this.equals(expr.right, comparand.right);
12945 };
12946 SQExprEqualityVisitor.prototype.visitCompare = function (expr, comparand) {
12947 return comparand instanceof SQCompareExpr &&
12948 expr.comparison === comparand.comparison &&
12949 this.equals(expr.left, comparand.left) &&
12950 this.equals(expr.right, comparand.right);
12951 };
12952 SQExprEqualityVisitor.prototype.visitContains = function (expr, comparand) {
12953 return comparand instanceof SQContainsExpr &&
12954 this.equals(expr.left, comparand.left) &&
12955 this.equals(expr.right, comparand.right);
12956 };
12957 SQExprEqualityVisitor.prototype.visitDateSpan = function (expr, comparand) {
12958 return comparand instanceof SQDateSpanExpr &&
12959 expr.unit === comparand.unit &&
12960 this.equals(expr.arg, comparand.arg);
12961 };
12962 SQExprEqualityVisitor.prototype.visitDateAdd = function (expr, comparand) {
12963 return comparand instanceof SQDateAddExpr &&
12964 expr.unit === comparand.unit &&
12965 expr.amount === comparand.amount &&
12966 this.equals(expr.arg, comparand.arg);
12967 };
12968 SQExprEqualityVisitor.prototype.visitExists = function (expr, comparand) {
12969 return comparand instanceof SQExistsExpr &&
12970 this.equals(expr.arg, comparand.arg);
12971 };
12972 SQExprEqualityVisitor.prototype.visitNot = function (expr, comparand) {
12973 return comparand instanceof SQNotExpr &&
12974 this.equals(expr.arg, comparand.arg);
12975 };
12976 SQExprEqualityVisitor.prototype.visitNow = function (expr, comparand) {
12977 return comparand instanceof SQNowExpr;
12978 };
12979 SQExprEqualityVisitor.prototype.visitDefaultValue = function (expr, comparand) {
12980 return comparand instanceof SQDefaultValueExpr;
12981 };
12982 SQExprEqualityVisitor.prototype.visitAnyValue = function (expr, comparand) {
12983 return comparand instanceof SQAnyValueExpr;
12984 };
12985 SQExprEqualityVisitor.prototype.visitResourcePackageItem = function (expr, comparand) {
12986 return comparand instanceof SQResourcePackageItemExpr &&
12987 expr.packageName === comparand.packageName &&
12988 expr.packageType === comparand.packageType &&
12989 expr.itemName === comparand.itemName;
12990 };
12991 SQExprEqualityVisitor.prototype.visitStartsWith = function (expr, comparand) {
12992 return comparand instanceof SQStartsWithExpr &&
12993 this.equals(expr.left, comparand.left) &&
12994 this.equals(expr.right, comparand.right);
12995 };
12996 SQExprEqualityVisitor.prototype.visitConstant = function (expr, comparand) {
12997 if (comparand instanceof SQConstantExpr && expr.type === comparand.type)
12998 return expr.type.text && this.ignoreCase ?
12999 StringExtensions.equalIgnoreCase(expr.valueEncoded, comparand.valueEncoded) :
13000 expr.valueEncoded === comparand.valueEncoded;
13001 return false;
13002 };
13003 SQExprEqualityVisitor.prototype.visitFillRule = function (expr, comparand) {
13004 if (comparand instanceof SQFillRuleExpr && this.equals(expr.input, comparand.input)) {
13005 var leftRule = expr.rule, rightRule = comparand.rule;
13006 if (leftRule === rightRule)
13007 return true;
13008 var leftLinearGradient2 = leftRule.linearGradient2, rightLinearGradient2 = rightRule.linearGradient2;
13009 if (leftLinearGradient2 && rightLinearGradient2) {
13010 return this.visitLinearGradient2(leftLinearGradient2, rightLinearGradient2);
13011 }
13012 var leftLinearGradient3 = leftRule.linearGradient3, rightLinearGradient3 = rightRule.linearGradient3;
13013 if (leftLinearGradient3 && rightLinearGradient3) {
13014 return this.visitLinearGradient3(leftLinearGradient3, rightLinearGradient3);
13015 }
13016 }
13017 return false;
13018 };
13019 SQExprEqualityVisitor.prototype.visitLinearGradient2 = function (left2, right2) {
13020 debug.assertValue(left2, 'left2');
13021 debug.assertValue(right2, 'right2');
13022 return this.equalsFillRuleStop(left2.min, right2.min) &&
13023 this.equalsFillRuleStop(left2.max, right2.max);
13024 };
13025 SQExprEqualityVisitor.prototype.visitLinearGradient3 = function (left3, right3) {
13026 debug.assertValue(left3, 'left3');
13027 debug.assertValue(right3, 'right3');
13028 return this.equalsFillRuleStop(left3.min, right3.min) &&
13029 this.equalsFillRuleStop(left3.mid, right3.mid) &&
13030 this.equalsFillRuleStop(left3.max, right3.max);
13031 };
13032 SQExprEqualityVisitor.prototype.equalsFillRuleStop = function (stop1, stop2) {
13033 debug.assertValue(stop1, 'stop1');
13034 debug.assertValue(stop2, 'stop2');
13035 if (!this.equals(stop1.color, stop2.color))
13036 return false;
13037 if (!stop1.value)
13038 return stop1.value === stop2.value;
13039 return this.equals(stop1.value, stop2.value);
13040 };
13041 SQExprEqualityVisitor.prototype.visitArithmetic = function (expr, comparand) {
13042 return comparand instanceof SQArithmeticExpr &&
13043 expr.operator === comparand.operator &&
13044 this.equals(expr.left, comparand.left) &&
13045 this.equals(expr.right, comparand.right);
13046 };
13047 SQExprEqualityVisitor.prototype.visitScopedEval = function (expr, comparand) {
13048 return comparand instanceof SQScopedEvalExpr &&
13049 this.equals(expr.expression, comparand.expression) &&
13050 this.equalsAll(expr.scope, comparand.scope);
13051 };
13052 SQExprEqualityVisitor.prototype.optionalEqual = function (x, y) {
13053 // Only check equality if both values are specified.
13054 if (x && y)
13055 return x === y;
13056 return true;
13057 };
13058 SQExprEqualityVisitor.prototype.equals = function (x, y) {
13059 return x.accept(this, y);
13060 };
13061 SQExprEqualityVisitor.prototype.equalsAll = function (x, y) {
13062 var len = x.length;
13063 if (len !== y.length)
13064 return false;
13065 for (var i = 0; i < len; i++) {
13066 if (!this.equals(x[i], y[i]))
13067 return false;
13068 }
13069 return true;
13070 };
13071 SQExprEqualityVisitor.instance = new SQExprEqualityVisitor(/* ignoreCase */ false);
13072 SQExprEqualityVisitor.ignoreCaseInstance = new SQExprEqualityVisitor(true);
13073 return SQExprEqualityVisitor;
13074 }());
13075 /** Rewrites a root-level expression. */
13076 var SQExprRootRewriter = (function (_super) {
13077 __extends(SQExprRootRewriter, _super);
13078 function SQExprRootRewriter() {
13079 _super.apply(this, arguments);
13080 }
13081 SQExprRootRewriter.prototype.visitDefault = function (expr) {
13082 return expr;
13083 };
13084 return SQExprRootRewriter;
13085 }(data.DefaultSQExprVisitor));
13086 var SQExprValidationVisitor = (function (_super) {
13087 __extends(SQExprValidationVisitor, _super);
13088 function SQExprValidationVisitor(schema, aggrUtils, errors) {
13089 debug.assertValue(schema, 'schema');
13090 debug.assertValue(aggrUtils, 'aggrUtils');
13091 _super.call(this);
13092 this.schema = schema;
13093 this.aggrUtils = aggrUtils;
13094 if (errors)
13095 this.errors = errors;
13096 }
13097 SQExprValidationVisitor.prototype.visitIn = function (expr) {
13098 var inExpr = _super.prototype.visitIn.call(this, expr);
13099 var args = inExpr.args;
13100 var values = inExpr.values;
13101 for (var _i = 0, values_2 = values; _i < values_2.length; _i++) {
13102 var valueTuple = values_2[_i];
13103 debug.assert(valueTuple.length === args.length, 'args and value tuple are not the same length');
13104 for (var i = 0, len = valueTuple.length; i < len; ++i)
13105 this.validateCompatibleType(args[i], valueTuple[i]);
13106 }
13107 return inExpr;
13108 };
13109 SQExprValidationVisitor.prototype.visitCompare = function (expr) {
13110 var compareExpr = _super.prototype.visitCompare.call(this, expr);
13111 this.validateCompatibleType(compareExpr.left, compareExpr.right);
13112 return compareExpr;
13113 };
13114 SQExprValidationVisitor.prototype.visitColumnRef = function (expr) {
13115 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
13116 if (fieldExpr) {
13117 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
13118 var entity = this.validateEntity(fieldExprItem.schema, fieldExprItem.entity);
13119 if (entity) {
13120 var prop = entity.properties.withName(fieldExpr.column.name);
13121 if (!prop ||
13122 prop.kind !== 0 /* Column */ ||
13123 !this.isQueryable(fieldExpr))
13124 this.register(3 /* invalidColumnReference */);
13125 }
13126 }
13127 return expr;
13128 };
13129 SQExprValidationVisitor.prototype.visitMeasureRef = function (expr) {
13130 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
13131 if (fieldExpr) {
13132 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
13133 var entity = this.validateEntity(fieldExprItem.schema, fieldExprItem.entity);
13134 if (entity) {
13135 var prop = entity.properties.withName(fieldExpr.measure.name);
13136 if (!prop ||
13137 prop.kind !== 1 /* Measure */ ||
13138 !this.isQueryable(fieldExpr))
13139 this.register(4 /* invalidMeasureReference */);
13140 }
13141 }
13142 return expr;
13143 };
13144 SQExprValidationVisitor.prototype.visitAggr = function (expr) {
13145 var aggregateExpr = _super.prototype.visitAggr.call(this, expr);
13146 var columnRefExpr = SQExprColumnRefInfoVisitor.getColumnRefSQExpr(this.schema, aggregateExpr.arg);
13147 if (columnRefExpr) {
13148 if (!this.aggrUtils.isSupportedAggregate(expr, this.schema, expr.func, /*targetTypes*/ null))
13149 this.register(0 /* invalidAggregateFunction */);
13150 }
13151 return aggregateExpr;
13152 };
13153 SQExprValidationVisitor.prototype.visitHierarchy = function (expr) {
13154 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
13155 if (fieldExpr) {
13156 var fieldExprItem = fieldExpr.hierarchy;
13157 if (fieldExprItem) {
13158 this.validateHierarchy(fieldExprItem.schema, fieldExprItem.entity, fieldExprItem.name);
13159 }
13160 else {
13161 this.register(5 /* invalidHierarchyReference */);
13162 }
13163 }
13164 return expr;
13165 };
13166 SQExprValidationVisitor.prototype.visitHierarchyLevel = function (expr) {
13167 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
13168 if (fieldExpr) {
13169 var hierarchyLevelFieldExprItem = fieldExpr.hierarchyLevel;
13170 if (hierarchyLevelFieldExprItem) {
13171 this.validateHierarchyLevel(hierarchyLevelFieldExprItem.schema, hierarchyLevelFieldExprItem.entity, hierarchyLevelFieldExprItem.name, hierarchyLevelFieldExprItem.level);
13172 }
13173 else if (!fieldExpr.columnHierarchyLevelVariation) {
13174 this.register(6 /* invalidHierarchyLevelReference */);
13175 }
13176 }
13177 return expr;
13178 };
13179 SQExprValidationVisitor.prototype.visitPercentile = function (expr) {
13180 expr.arg.accept(this);
13181 if (_.isEmpty(this.errors)) {
13182 var argMetadata = expr.arg.getMetadata(this.schema);
13183 if (!argMetadata ||
13184 argMetadata.kind !== 0 /* Column */ ||
13185 !(argMetadata.type && (argMetadata.type.integer || argMetadata.type.numeric))) {
13186 this.register(10 /* invalidPercentileArgument */);
13187 }
13188 }
13189 return expr;
13190 };
13191 SQExprValidationVisitor.prototype.visitEntity = function (expr) {
13192 this.validateEntity(expr.schema, expr.entity);
13193 return expr;
13194 };
13195 SQExprValidationVisitor.prototype.visitContains = function (expr) {
13196 this.validateOperandsAndTypeForStartOrContains(expr.left, expr.right);
13197 return expr;
13198 };
13199 SQExprValidationVisitor.prototype.visitStartsWith = function (expr) {
13200 this.validateOperandsAndTypeForStartOrContains(expr.left, expr.right);
13201 return expr;
13202 };
13203 SQExprValidationVisitor.prototype.visitArithmetic = function (expr) {
13204 this.validateArithmeticTypes(expr.left, expr.right);
13205 return expr;
13206 };
13207 SQExprValidationVisitor.prototype.visitScopedEval = function (expr) {
13208 // No validation necessary
13209 return expr;
13210 };
13211 SQExprValidationVisitor.prototype.validateOperandsAndTypeForStartOrContains = function (left, right) {
13212 if (left instanceof SQColumnRefExpr) {
13213 this.visitColumnRef(left);
13214 }
13215 else if (left instanceof SQHierarchyLevelExpr) {
13216 this.visitHierarchyLevel(left);
13217 }
13218 else {
13219 this.register(7 /* invalidLeftOperandType */);
13220 }
13221 if (!(right instanceof SQConstantExpr) || !right.type.text)
13222 this.register(8 /* invalidRightOperandType */);
13223 else
13224 this.validateCompatibleType(left, right);
13225 };
13226 SQExprValidationVisitor.prototype.validateArithmeticTypes = function (left, right) {
13227 if (!data.SQExprUtils.supportsArithmetic(left, this.schema))
13228 this.register(7 /* invalidLeftOperandType */);
13229 if (!data.SQExprUtils.supportsArithmetic(right, this.schema))
13230 this.register(8 /* invalidRightOperandType */);
13231 };
13232 SQExprValidationVisitor.prototype.validateCompatibleType = function (left, right) {
13233 var leftMetadata = left.getMetadata(this.schema), leftType = leftMetadata && leftMetadata.type, rightMetadata = right.getMetadata(this.schema), rightType = rightMetadata && rightMetadata.type;
13234 if (leftType && rightType && !leftType.isCompatibleFrom(rightType))
13235 this.register(9 /* invalidValueType */);
13236 };
13237 SQExprValidationVisitor.prototype.validateEntity = function (schemaName, entityName) {
13238 var schema = this.schema.schema(schemaName);
13239 if (schema) {
13240 var entity = schema.entities.withName(entityName);
13241 if (entity)
13242 return entity;
13243 this.register(2 /* invalidEntityReference */);
13244 }
13245 else {
13246 this.register(1 /* invalidSchemaReference */);
13247 }
13248 };
13249 SQExprValidationVisitor.prototype.validateHierarchy = function (schemaName, entityName, hierarchyName) {
13250 var entity = this.validateEntity(schemaName, entityName);
13251 if (entity) {
13252 var hierarchy = entity.hierarchies.withName(hierarchyName);
13253 if (hierarchy)
13254 return hierarchy;
13255 this.register(5 /* invalidHierarchyReference */);
13256 }
13257 };
13258 SQExprValidationVisitor.prototype.validateHierarchyLevel = function (schemaName, entityName, hierarchyName, levelName) {
13259 var hierarchy = this.validateHierarchy(schemaName, entityName, hierarchyName);
13260 if (hierarchy) {
13261 var hierarchyLevel = hierarchy.levels.withName(levelName);
13262 if (hierarchyLevel)
13263 return hierarchyLevel;
13264 this.register(6 /* invalidHierarchyLevelReference */);
13265 }
13266 };
13267 SQExprValidationVisitor.prototype.register = function (error) {
13268 if (!this.errors)
13269 this.errors = [];
13270 this.errors.push(error);
13271 };
13272 SQExprValidationVisitor.prototype.isQueryable = function (fieldExpr) {
13273 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(fieldExpr);
13274 if (fieldExpr.hierarchyLevel || fieldExpr.hierarchyLevelAggr) {
13275 var hierarchyLevelConceptualProperty = data.SQHierarchyExprUtils.getConceptualHierarchyLevelFromExpr(this.schema, fieldExpr);
13276 return hierarchyLevelConceptualProperty && hierarchyLevelConceptualProperty.column.queryable !== 1 /* Error */;
13277 }
13278 return this.schema.schema(fieldExprItem.schema).findProperty(fieldExprItem.entity, data.FieldExprPattern.getPropertyName(fieldExpr)).queryable !== 1 /* Error */;
13279 };
13280 return SQExprValidationVisitor;
13281 }(data.SQExprRewriter));
13282 data.SQExprValidationVisitor = SQExprValidationVisitor;
13283 /** Returns an expression's aggregate function, or undefined if it doesn't have one. */
13284 var SQExprAggregateInfoVisitor = (function (_super) {
13285 __extends(SQExprAggregateInfoVisitor, _super);
13286 function SQExprAggregateInfoVisitor() {
13287 _super.apply(this, arguments);
13288 }
13289 SQExprAggregateInfoVisitor.prototype.visitAggr = function (expr) {
13290 return expr.func;
13291 };
13292 SQExprAggregateInfoVisitor.prototype.visitDefault = function (expr) {
13293 return;
13294 };
13295 SQExprAggregateInfoVisitor.getAggregate = function (expr) {
13296 var visitor = new SQExprAggregateInfoVisitor();
13297 return expr.accept(visitor);
13298 };
13299 return SQExprAggregateInfoVisitor;
13300 }(data.DefaultSQExprVisitor));
13301 /** Returns a SQExprColumnRef expression or undefined.*/
13302 var SQExprColumnRefInfoVisitor = (function (_super) {
13303 __extends(SQExprColumnRefInfoVisitor, _super);
13304 function SQExprColumnRefInfoVisitor(schema) {
13305 _super.call(this);
13306 this.schema = schema;
13307 }
13308 SQExprColumnRefInfoVisitor.prototype.visitColumnRef = function (expr) {
13309 return expr;
13310 };
13311 SQExprColumnRefInfoVisitor.prototype.visitHierarchyLevel = function (expr) {
13312 var ref = expr.level;
13313 var hierarchy = (expr.arg);
13314 var sourceExpr = hierarchy.accept(this);
13315 if (hierarchy && hierarchy.arg instanceof SQPropertyVariationSourceExpr) {
13316 var propertyVariationSource = hierarchy.arg;
13317 var targetEntity = sourceExpr.getTargetEntityForVariation(this.schema, propertyVariationSource.name);
13318 if (sourceExpr && targetEntity) {
13319 var schemaName = (sourceExpr.source).schema;
13320 var targetEntityExpr = SQExprBuilder.entity(schemaName, targetEntity);
13321 var schemaHierarchy = this.schema.schema(schemaName).findHierarchy(targetEntity, hierarchy.hierarchy);
13322 if (schemaHierarchy) {
13323 for (var _i = 0, _a = schemaHierarchy.levels; _i < _a.length; _i++) {
13324 var level = _a[_i];
13325 if (level.name === ref)
13326 return new SQColumnRefExpr(targetEntityExpr, level.column.name);
13327 }
13328 }
13329 }
13330 }
13331 else {
13332 var entityExpr = (hierarchy.arg);
13333 var hierarchyLevelRef = data.SQHierarchyExprUtils.getConceptualHierarchyLevel(this.schema, entityExpr.schema, entityExpr.entity, hierarchy.hierarchy, expr.level);
13334 if (hierarchyLevelRef)
13335 return new SQColumnRefExpr(hierarchy.arg, hierarchyLevelRef.column.name);
13336 }
13337 };
13338 SQExprColumnRefInfoVisitor.prototype.visitHierarchy = function (expr) {
13339 return expr.arg.accept(this);
13340 };
13341 SQExprColumnRefInfoVisitor.prototype.visitPropertyVariationSource = function (expr) {
13342 var propertyName = expr.property;
13343 return new SQColumnRefExpr(expr.arg, propertyName);
13344 };
13345 SQExprColumnRefInfoVisitor.prototype.visitAggr = function (expr) {
13346 return expr.arg.accept(this);
13347 };
13348 SQExprColumnRefInfoVisitor.prototype.visitDefault = function (expr) {
13349 return;
13350 };
13351 SQExprColumnRefInfoVisitor.getColumnRefSQExpr = function (schema, expr) {
13352 var visitor = new SQExprColumnRefInfoVisitor(schema);
13353 return expr.accept(visitor);
13354 };
13355 return SQExprColumnRefInfoVisitor;
13356 }(data.DefaultSQExprVisitor));
13357 /** Returns a SQEntityExpr expression or undefined.*/
13358 var SQEntityExprInfoVisitor = (function (_super) {
13359 __extends(SQEntityExprInfoVisitor, _super);
13360 function SQEntityExprInfoVisitor(schema) {
13361 _super.call(this);
13362 this.schema = schema;
13363 }
13364 SQEntityExprInfoVisitor.prototype.visitEntity = function (expr) {
13365 return expr;
13366 };
13367 SQEntityExprInfoVisitor.prototype.visitColumnRef = function (expr) {
13368 return SQEntityExprInfoVisitor.getEntity(expr);
13369 };
13370 SQEntityExprInfoVisitor.prototype.visitHierarchyLevel = function (expr) {
13371 var columnRef = SQEntityExprInfoVisitor.getColumnRefSQExpr(this.schema, expr);
13372 return SQEntityExprInfoVisitor.getEntity(columnRef);
13373 };
13374 SQEntityExprInfoVisitor.prototype.visitHierarchy = function (expr) {
13375 return expr.arg.accept(this);
13376 };
13377 SQEntityExprInfoVisitor.prototype.visitPropertyVariationSource = function (expr) {
13378 var columnRef = SQEntityExprInfoVisitor.getColumnRefSQExpr(this.schema, expr);
13379 return SQEntityExprInfoVisitor.getEntity(columnRef);
13380 };
13381 SQEntityExprInfoVisitor.prototype.visitAggr = function (expr) {
13382 var columnRef = SQEntityExprInfoVisitor.getColumnRefSQExpr(this.schema, expr);
13383 return SQEntityExprInfoVisitor.getEntity(columnRef);
13384 };
13385 SQEntityExprInfoVisitor.prototype.visitMeasureRef = function (expr) {
13386 return expr.source.accept(this);
13387 };
13388 SQEntityExprInfoVisitor.getColumnRefSQExpr = function (schema, expr) {
13389 var visitor = new SQExprColumnRefInfoVisitor(schema);
13390 return expr.accept(visitor);
13391 };
13392 SQEntityExprInfoVisitor.getEntity = function (columnRef) {
13393 var field = data.SQExprConverter.asFieldPattern(columnRef);
13394 var column = field.column;
13395 return SQExprBuilder.entity(column.schema, column.entity, column.entityVar);
13396 };
13397 SQEntityExprInfoVisitor.getEntityExpr = function (schema, expr) {
13398 var visitor = new SQEntityExprInfoVisitor(schema);
13399 return expr.accept(visitor);
13400 };
13401 return SQEntityExprInfoVisitor;
13402 }(data.DefaultSQExprVisitor));
13403 var SQExprChangeAggregateRewriter = (function (_super) {
13404 __extends(SQExprChangeAggregateRewriter, _super);
13405 function SQExprChangeAggregateRewriter(func) {
13406 debug.assertValue(func, 'func');
13407 _super.call(this);
13408 this.func = func;
13409 }
13410 SQExprChangeAggregateRewriter.prototype.visitAggr = function (expr) {
13411 if (expr.func === this.func)
13412 return expr;
13413 return new SQAggregationExpr(expr.arg, this.func);
13414 };
13415 SQExprChangeAggregateRewriter.prototype.visitColumnRef = function (expr) {
13416 return new SQAggregationExpr(expr, this.func);
13417 };
13418 SQExprChangeAggregateRewriter.rewrite = function (expr, func) {
13419 debug.assertValue(expr, 'expr');
13420 debug.assertValue(func, 'func');
13421 var rewriter = new SQExprChangeAggregateRewriter(func);
13422 return expr.accept(rewriter);
13423 };
13424 return SQExprChangeAggregateRewriter;
13425 }(SQExprRootRewriter));
13426 var FieldExprChangeAggregateRewriter = (function () {
13427 function FieldExprChangeAggregateRewriter(sqExpr, aggregate) {
13428 this.sqExpr = sqExpr;
13429 this.aggregate = aggregate;
13430 }
13431 FieldExprChangeAggregateRewriter.rewrite = function (sqExpr, aggregate) {
13432 return data.FieldExprPattern.visit(sqExpr, new FieldExprChangeAggregateRewriter(sqExpr, aggregate));
13433 };
13434 FieldExprChangeAggregateRewriter.prototype.visitPercentOfGrandTotal = function (pattern) {
13435 pattern.baseExpr = data.SQExprConverter.asFieldPattern(SQExprChangeAggregateRewriter.rewrite(SQExprBuilder.fieldExpr(pattern.baseExpr), this.aggregate));
13436 return SQExprBuilder.fieldExpr({ percentOfGrandTotal: pattern });
13437 };
13438 FieldExprChangeAggregateRewriter.prototype.visitColumn = function (column) {
13439 return this.defaultRewrite();
13440 };
13441 FieldExprChangeAggregateRewriter.prototype.visitColumnAggr = function (columnAggr) {
13442 return this.defaultRewrite();
13443 };
13444 FieldExprChangeAggregateRewriter.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
13445 return this.defaultRewrite();
13446 };
13447 FieldExprChangeAggregateRewriter.prototype.visitSelectRef = function (selectRef) {
13448 return this.defaultRewrite();
13449 };
13450 FieldExprChangeAggregateRewriter.prototype.visitEntity = function (entity) {
13451 return this.defaultRewrite();
13452 };
13453 FieldExprChangeAggregateRewriter.prototype.visitEntityAggr = function (entityAggr) {
13454 return this.defaultRewrite();
13455 };
13456 FieldExprChangeAggregateRewriter.prototype.visitHierarchy = function (hierarchy) {
13457 return this.defaultRewrite();
13458 };
13459 FieldExprChangeAggregateRewriter.prototype.visitHierarchyLevel = function (hierarchyLevel) {
13460 return this.defaultRewrite();
13461 };
13462 FieldExprChangeAggregateRewriter.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
13463 return this.defaultRewrite();
13464 };
13465 FieldExprChangeAggregateRewriter.prototype.visitMeasure = function (measure) {
13466 return this.defaultRewrite();
13467 };
13468 FieldExprChangeAggregateRewriter.prototype.visitPercentile = function (percentile) {
13469 return this.defaultRewrite();
13470 };
13471 FieldExprChangeAggregateRewriter.prototype.defaultRewrite = function () {
13472 return SQExprChangeAggregateRewriter.rewrite(this.sqExpr, this.aggregate);
13473 };
13474 return FieldExprChangeAggregateRewriter;
13475 }());
13476 var FieldExprRemoveAggregateRewriter = (function () {
13477 function FieldExprRemoveAggregateRewriter(sqExpr) {
13478 this.sqExpr = sqExpr;
13479 }
13480 FieldExprRemoveAggregateRewriter.rewrite = function (sqExpr) {
13481 return data.FieldExprPattern.visit(sqExpr, new FieldExprRemoveAggregateRewriter(sqExpr));
13482 };
13483 FieldExprRemoveAggregateRewriter.prototype.visitPercentOfGrandTotal = function (pattern) {
13484 return FieldExprRemoveAggregateRewriter.rewrite(SQExprBuilder.fieldExpr(pattern.baseExpr));
13485 };
13486 FieldExprRemoveAggregateRewriter.prototype.visitColumn = function (column) {
13487 return this.defaultRewrite();
13488 };
13489 FieldExprRemoveAggregateRewriter.prototype.visitColumnAggr = function (columnAggr) {
13490 return this.defaultRewrite();
13491 };
13492 FieldExprRemoveAggregateRewriter.prototype.visitColumnHierarchyLevelVariation = function (columnHierarchyLevelVariation) {
13493 return this.defaultRewrite();
13494 };
13495 FieldExprRemoveAggregateRewriter.prototype.visitSelectRef = function (selectRef) {
13496 return this.defaultRewrite();
13497 };
13498 FieldExprRemoveAggregateRewriter.prototype.visitEntity = function (entity) {
13499 return this.defaultRewrite();
13500 };
13501 FieldExprRemoveAggregateRewriter.prototype.visitEntityAggr = function (entityAggr) {
13502 return this.defaultRewrite();
13503 };
13504 FieldExprRemoveAggregateRewriter.prototype.visitHierarchy = function (hierarchy) {
13505 return this.defaultRewrite();
13506 };
13507 FieldExprRemoveAggregateRewriter.prototype.visitHierarchyLevel = function (hierarchyLevel) {
13508 return this.defaultRewrite();
13509 };
13510 FieldExprRemoveAggregateRewriter.prototype.visitHierarchyLevelAggr = function (hierarchyLevelAggr) {
13511 return this.defaultRewrite();
13512 };
13513 FieldExprRemoveAggregateRewriter.prototype.visitMeasure = function (measure) {
13514 return this.defaultRewrite();
13515 };
13516 FieldExprRemoveAggregateRewriter.prototype.visitPercentile = function (percentile) {
13517 return this.defaultRewrite();
13518 };
13519 FieldExprRemoveAggregateRewriter.prototype.defaultRewrite = function () {
13520 return SQExprRemoveAggregateRewriter.rewrite(this.sqExpr);
13521 };
13522 return FieldExprRemoveAggregateRewriter;
13523 }());
13524 var SQExprRemoveAggregateRewriter = (function (_super) {
13525 __extends(SQExprRemoveAggregateRewriter, _super);
13526 function SQExprRemoveAggregateRewriter() {
13527 _super.apply(this, arguments);
13528 }
13529 SQExprRemoveAggregateRewriter.prototype.visitAggr = function (expr) {
13530 return expr.arg;
13531 };
13532 SQExprRemoveAggregateRewriter.rewrite = function (expr) {
13533 debug.assertValue(expr, 'expr');
13534 return expr.accept(SQExprRemoveAggregateRewriter.instance);
13535 };
13536 SQExprRemoveAggregateRewriter.instance = new SQExprRemoveAggregateRewriter();
13537 return SQExprRemoveAggregateRewriter;
13538 }(SQExprRootRewriter));
13539 var SQExprRemoveEntityVariablesRewriter = (function (_super) {
13540 __extends(SQExprRemoveEntityVariablesRewriter, _super);
13541 function SQExprRemoveEntityVariablesRewriter() {
13542 _super.apply(this, arguments);
13543 }
13544 SQExprRemoveEntityVariablesRewriter.prototype.visitEntity = function (expr) {
13545 if (expr.variable)
13546 return SQExprBuilder.entity(expr.schema, expr.entity);
13547 return expr;
13548 };
13549 SQExprRemoveEntityVariablesRewriter.rewrite = function (expr) {
13550 debug.assertValue(expr, 'expr');
13551 return expr.accept(SQExprRemoveEntityVariablesRewriter.instance);
13552 };
13553 SQExprRemoveEntityVariablesRewriter.instance = new SQExprRemoveEntityVariablesRewriter();
13554 return SQExprRemoveEntityVariablesRewriter;
13555 }(data.SQExprRewriter));
13556 var SQExprRemovePercentOfGrandTotalRewriter = (function (_super) {
13557 __extends(SQExprRemovePercentOfGrandTotalRewriter, _super);
13558 function SQExprRemovePercentOfGrandTotalRewriter() {
13559 _super.apply(this, arguments);
13560 }
13561 SQExprRemovePercentOfGrandTotalRewriter.rewrite = function (expr) {
13562 debug.assertValue(expr, 'expr');
13563 return expr.accept(SQExprRemovePercentOfGrandTotalRewriter.instance);
13564 };
13565 SQExprRemovePercentOfGrandTotalRewriter.prototype.visitDefault = function (expr) {
13566 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
13567 if (fieldExpr && fieldExpr.percentOfGrandTotal)
13568 expr = SQExprBuilder.fieldExpr(fieldExpr.percentOfGrandTotal.baseExpr);
13569 return expr;
13570 };
13571 SQExprRemovePercentOfGrandTotalRewriter.instance = new SQExprRemovePercentOfGrandTotalRewriter();
13572 return SQExprRemovePercentOfGrandTotalRewriter;
13573 }(SQExprRootRewriter));
13574 var SQExprSetPercentOfGrandTotalRewriter = (function (_super) {
13575 __extends(SQExprSetPercentOfGrandTotalRewriter, _super);
13576 function SQExprSetPercentOfGrandTotalRewriter() {
13577 _super.apply(this, arguments);
13578 }
13579 SQExprSetPercentOfGrandTotalRewriter.rewrite = function (expr) {
13580 debug.assertValue(expr, 'expr');
13581 return expr.accept(SQExprSetPercentOfGrandTotalRewriter.instance);
13582 };
13583 SQExprSetPercentOfGrandTotalRewriter.prototype.visitDefault = function (expr) {
13584 var fieldExpr = data.SQExprConverter.asFieldPattern(expr);
13585 if (fieldExpr && !fieldExpr.percentOfGrandTotal)
13586 expr = SQExprBuilder.fieldExpr({ percentOfGrandTotal: { baseExpr: data.SQExprConverter.asFieldPattern(expr) } });
13587 return expr;
13588 };
13589 SQExprSetPercentOfGrandTotalRewriter.instance = new SQExprSetPercentOfGrandTotalRewriter();
13590 return SQExprSetPercentOfGrandTotalRewriter;
13591 }(SQExprRootRewriter));
13592 })(data = powerbi.data || (powerbi.data = {}));
13593})(powerbi || (powerbi = {}));
13594/*
13595 * Power BI Visualizations
13596 *
13597 * Copyright (c) Microsoft Corporation
13598 * All rights reserved.
13599 * MIT License
13600 *
13601 * Permission is hereby granted, free of charge, to any person obtaining a copy
13602 * of this software and associated documentation files (the ""Software""), to deal
13603 * in the Software without restriction, including without limitation the rights
13604 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13605 * copies of the Software, and to permit persons to whom the Software is
13606 * furnished to do so, subject to the following conditions:
13607 *
13608 * The above copyright notice and this permission notice shall be included in
13609 * all copies or substantial portions of the Software.
13610 *
13611 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13612 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13613 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13614 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13615 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
13616 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13617 * THE SOFTWARE.
13618 */
13619var powerbi;
13620(function (powerbi) {
13621 var data;
13622 (function (data) {
13623 var ArrayExtensions = jsCommon.ArrayExtensions;
13624 var StringExtensions = jsCommon.StringExtensions;
13625 var SQExprUtils;
13626 (function (SQExprUtils) {
13627 function supportsArithmetic(expr, schema) {
13628 var metadata = expr.getMetadata(schema), type = metadata && metadata.type;
13629 if (!metadata || !type) {
13630 return false;
13631 }
13632 return type.numeric || type.dateTime || type.duration;
13633 }
13634 SQExprUtils.supportsArithmetic = supportsArithmetic;
13635 function indexOfExpr(items, searchElement) {
13636 debug.assertValue(items, 'items');
13637 debug.assertValue(searchElement, 'searchElement');
13638 for (var i = 0, len = items.length; i < len; i++) {
13639 if (data.SQExpr.equals(items[i], searchElement))
13640 return i;
13641 }
13642 return -1;
13643 }
13644 SQExprUtils.indexOfExpr = indexOfExpr;
13645 function sequenceEqual(x, y) {
13646 debug.assertValue(x, 'x');
13647 debug.assertValue(y, 'y');
13648 var len = x.length;
13649 if (len !== y.length)
13650 return false;
13651 for (var i = 0; i < len; i++) {
13652 if (!data.SQExpr.equals(x[i], y[i]))
13653 return false;
13654 }
13655 return true;
13656 }
13657 SQExprUtils.sequenceEqual = sequenceEqual;
13658 function uniqueName(namedItems, expr, exprDefaultName) {
13659 debug.assertValue(namedItems, 'namedItems');
13660 // Determine all names
13661 var names = {};
13662 for (var i = 0, len = namedItems.length; i < len; i++)
13663 names[namedItems[i].name] = true;
13664 return StringExtensions.findUniqueName(names, exprDefaultName || defaultName(expr));
13665 }
13666 SQExprUtils.uniqueName = uniqueName;
13667 /** Generates a default expression name */
13668 function defaultName(expr, fallback) {
13669 if (fallback === void 0) { fallback = 'select'; }
13670 if (!expr)
13671 return fallback;
13672 return expr.accept(SQExprDefaultNameGenerator.instance, fallback);
13673 }
13674 SQExprUtils.defaultName = defaultName;
13675 /** Gets a value indicating whether the expr is a model measure or an aggregate. */
13676 function isMeasure(expr) {
13677 debug.assertValue(expr, 'expr');
13678 return expr.accept(IsMeasureVisitor.instance);
13679 }
13680 SQExprUtils.isMeasure = isMeasure;
13681 /** Gets a value indicating whether the expr is an AnyValue or equals comparison to AnyValue*/
13682 function isAnyValue(expr) {
13683 debug.assertValue(expr, 'expr');
13684 return expr.accept(IsAnyValueVisitor.instance);
13685 }
13686 SQExprUtils.isAnyValue = isAnyValue;
13687 /** Gets a value indicating whether the expr is a DefaultValue or equals comparison to DefaultValue*/
13688 function isDefaultValue(expr) {
13689 debug.assertValue(expr, 'expr');
13690 return expr.accept(IsDefaultValueVisitor.instance);
13691 }
13692 SQExprUtils.isDefaultValue = isDefaultValue;
13693 function discourageAggregation(expr, schema) {
13694 var capabilities = getSchemaCapabilities(expr, schema);
13695 return capabilities && capabilities.discourageQueryAggregateUsage;
13696 }
13697 SQExprUtils.discourageAggregation = discourageAggregation;
13698 function getAggregateBehavior(expr, schema) {
13699 debug.assertValue(expr, 'expr');
13700 debug.assertValue(schema, 'schema');
13701 var column = getConceptualColumn(expr, schema);
13702 if (column)
13703 return column.aggregateBehavior;
13704 }
13705 SQExprUtils.getAggregateBehavior = getAggregateBehavior;
13706 function getSchemaCapabilities(expr, schema) {
13707 debug.assertValue(expr, 'expr');
13708 debug.assertValue(schema, 'schema');
13709 var field = data.SQExprConverter.asFieldPattern(expr);
13710 if (!field)
13711 return;
13712 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(field);
13713 var conceptualSchema = schema.schema(fieldExprItem.schema);
13714 if (conceptualSchema)
13715 return conceptualSchema.capabilities;
13716 }
13717 SQExprUtils.getSchemaCapabilities = getSchemaCapabilities;
13718 function getKpiMetadata(expr, schema) {
13719 var kpiStatusProperty = getKpiStatusProperty(expr, schema);
13720 if (kpiStatusProperty)
13721 return kpiStatusProperty.kpiValue.measure.kpi.statusMetadata;
13722 var kpiTrendProperty = getKpiTrendProperty(expr, schema);
13723 if (kpiTrendProperty)
13724 return kpiTrendProperty.kpiValue.measure.kpi.trendMetadata;
13725 }
13726 SQExprUtils.getKpiMetadata = getKpiMetadata;
13727 function getConceptualEntity(entityExpr, schema) {
13728 debug.assertValue(entityExpr, 'entityExpr');
13729 var conceptualEntity = schema
13730 .schema(entityExpr.schema)
13731 .entities
13732 .withName(entityExpr.entity);
13733 return conceptualEntity;
13734 }
13735 SQExprUtils.getConceptualEntity = getConceptualEntity;
13736 function getKpiStatusProperty(expr, schema) {
13737 var property = expr.getConceptualProperty(schema);
13738 if (!property)
13739 return;
13740 var kpiValue = property.kpiValue;
13741 if (kpiValue && kpiValue.measure.kpi.status === property)
13742 return property;
13743 }
13744 function getKpiTrendProperty(expr, schema) {
13745 var property = expr.getConceptualProperty(schema);
13746 if (!property)
13747 return;
13748 var kpiValue = property.kpiValue;
13749 if (kpiValue && kpiValue.measure.kpi.trend === property)
13750 return property;
13751 }
13752 function getDefaultValue(fieldSQExpr, schema) {
13753 var column = getConceptualColumn(fieldSQExpr, schema);
13754 if (column)
13755 return column.defaultValue;
13756 }
13757 SQExprUtils.getDefaultValue = getDefaultValue;
13758 function getConceptualColumn(fieldSQExpr, schema) {
13759 if (!fieldSQExpr || !schema)
13760 return;
13761 var sqField = data.SQExprConverter.asFieldPattern(fieldSQExpr);
13762 if (!sqField)
13763 return;
13764 var column = sqField.column;
13765 if (column) {
13766 if (schema.schema(column.schema) && sqField.column.name) {
13767 var property = schema.schema(column.schema).findProperty(column.entity, sqField.column.name);
13768 if (property)
13769 return property.column;
13770 }
13771 }
13772 else {
13773 var hierarchyLevelField = sqField.hierarchyLevel;
13774 if (hierarchyLevelField) {
13775 var fieldExprItem = data.FieldExprPattern.toFieldExprEntityItemPattern(sqField);
13776 var schemaName = fieldExprItem.schema;
13777 if (schema.schema(schemaName)) {
13778 var hierarchy = schema.schema(schemaName)
13779 .findHierarchy(fieldExprItem.entity, hierarchyLevelField.name);
13780 if (hierarchy) {
13781 var hierarchyLevel = hierarchy.levels.withName(hierarchyLevelField.level);
13782 if (hierarchyLevel && hierarchyLevel.column)
13783 return hierarchyLevel.column.column;
13784 }
13785 }
13786 }
13787 }
13788 }
13789 function getDefaultValues(fieldSQExprs, schema) {
13790 if (_.isEmpty(fieldSQExprs) || !schema)
13791 return;
13792 var result = [];
13793 for (var _i = 0, fieldSQExprs_2 = fieldSQExprs; _i < fieldSQExprs_2.length; _i++) {
13794 var sqExpr = fieldSQExprs_2[_i];
13795 var defaultValue = getDefaultValue(sqExpr, schema);
13796 if (defaultValue)
13797 result.push(defaultValue);
13798 }
13799 return result;
13800 }
13801 SQExprUtils.getDefaultValues = getDefaultValues;
13802 /** Return compare or and expression for key value pairs. */
13803 function getDataViewScopeIdentityComparisonExpr(fieldsExpr, values) {
13804 debug.assert(fieldsExpr.length === values.length, "fileds and values need to be the same size");
13805 var compareExprs = [];
13806 for (var i = 0; i < fieldsExpr.length; i++) {
13807 compareExprs.push(data.SQExprBuilder.compare(data.QueryComparisonKind.Equal, fieldsExpr[i], values[i]));
13808 }
13809 if (_.isEmpty(compareExprs))
13810 return;
13811 var resultExpr;
13812 for (var _i = 0, compareExprs_1 = compareExprs; _i < compareExprs_1.length; _i++) {
13813 var compareExpr = compareExprs_1[_i];
13814 resultExpr = data.SQExprBuilder.and(resultExpr, compareExpr);
13815 }
13816 return resultExpr;
13817 }
13818 SQExprUtils.getDataViewScopeIdentityComparisonExpr = getDataViewScopeIdentityComparisonExpr;
13819 function getActiveTablesNames(queryDefn) {
13820 var tables = [];
13821 if (queryDefn) {
13822 var selectedItems = queryDefn.from();
13823 if (selectedItems !== undefined) {
13824 for (var _i = 0, _a = selectedItems.keys(); _i < _a.length; _i++) {
13825 var key = _a[_i];
13826 var entityObj = selectedItems.entity(key);
13827 if (tables.indexOf(entityObj.entity) < 0)
13828 tables.push(entityObj.entity);
13829 }
13830 }
13831 }
13832 return tables;
13833 }
13834 SQExprUtils.getActiveTablesNames = getActiveTablesNames;
13835 function isRelatedToMany(schema, sourceExpr, targetExpr) {
13836 return isRelated(schema, sourceExpr, targetExpr, 0 /* ZeroOrOne */, 2 /* Many */) ||
13837 isRelated(schema, targetExpr, sourceExpr, 2 /* Many */, 0 /* ZeroOrOne */);
13838 }
13839 SQExprUtils.isRelatedToMany = isRelatedToMany;
13840 function isRelatedToOne(schema, sourceExpr, targetExpr) {
13841 return isRelated(schema, sourceExpr, targetExpr, 2 /* Many */, 0 /* ZeroOrOne */) ||
13842 isRelated(schema, targetExpr, sourceExpr, 0 /* ZeroOrOne */, 2 /* Many */);
13843 }
13844 SQExprUtils.isRelatedToOne = isRelatedToOne;
13845 function isRelated(schema, sourceExpr, targetExpr, sourceMultiplicity, targetMultiplicity) {
13846 var source = SQExprUtils.getConceptualEntity(sourceExpr, schema);
13847 debug.assertValue(source, "could not resolve conceptual entity form sourceExpr.");
13848 if (_.isEmpty(source.navigationProperties))
13849 return false;
13850 var target = SQExprUtils.getConceptualEntity(targetExpr, schema);
13851 debug.assertValue(target, "could not resolve conceptual entity form targetExpr.");
13852 var queue = [];
13853 queue.push(source);
13854 // walk the relationship path from source.
13855 while (!_.isEmpty(queue)) {
13856 var current = queue.shift();
13857 var navProperties = current.navigationProperties;
13858 if (_.isEmpty(navProperties))
13859 continue;
13860 for (var _i = 0, navProperties_1 = navProperties; _i < navProperties_1.length; _i++) {
13861 var navProperty = navProperties_1[_i];
13862 if (!navProperty.isActive)
13863 continue;
13864 if (navProperty.targetMultiplicity === targetMultiplicity && navProperty.sourceMultiplicity === sourceMultiplicity) {
13865 if (navProperty.targetEntity === target)
13866 return true;
13867 queue.push(navProperty.targetEntity);
13868 }
13869 }
13870 }
13871 return false;
13872 }
13873 function isRelatedOneToOne(schema, sourceExpr, targetExpr) {
13874 var source = SQExprUtils.getConceptualEntity(sourceExpr, schema);
13875 debug.assertValue(source, "could not resolve conceptual entity form sourceExpr.");
13876 var target = SQExprUtils.getConceptualEntity(targetExpr, schema);
13877 debug.assertValue(target, "could not resolve conceptual entity form targetExpr.");
13878 var sourceNavigations = source.navigationProperties;
13879 var targetNavigations = target.navigationProperties;
13880 if (_.isEmpty(sourceNavigations) && _.isEmpty(targetNavigations))
13881 return false;
13882 return hasOneToOneNavigation(sourceNavigations, target) || hasOneToOneNavigation(targetNavigations, source);
13883 }
13884 SQExprUtils.isRelatedOneToOne = isRelatedOneToOne;
13885 function hasOneToOneNavigation(navigationProperties, targetEntity) {
13886 if (_.isEmpty(navigationProperties))
13887 return false;
13888 for (var _i = 0, navigationProperties_1 = navigationProperties; _i < navigationProperties_1.length; _i++) {
13889 var navigationProperty = navigationProperties_1[_i];
13890 if (!navigationProperty.isActive)
13891 continue;
13892 if (navigationProperty.targetEntity !== targetEntity)
13893 continue;
13894 if (navigationProperty.sourceMultiplicity === 0 /* ZeroOrOne */ &&
13895 navigationProperty.targetMultiplicity === 0 /* ZeroOrOne */) {
13896 return true;
13897 }
13898 }
13899 return false;
13900 }
13901 /** Performs a union of the 2 arrays with SQExpr.equals as comparator to skip duplicate items,
13902 and returns a new array. When available, we should use _.unionWith from lodash. */
13903 function concatUnique(leftExprs, rightExprs) {
13904 debug.assertValue(leftExprs, 'leftExprs');
13905 debug.assertValue(rightExprs, 'rightExprs');
13906 var concatExprs = ArrayExtensions.copy(leftExprs);
13907 for (var _i = 0, rightExprs_1 = rightExprs; _i < rightExprs_1.length; _i++) {
13908 var expr = rightExprs_1[_i];
13909 if (indexOfExpr(concatExprs, expr) === -1) {
13910 concatExprs.push(expr);
13911 }
13912 }
13913 return concatExprs;
13914 }
13915 SQExprUtils.concatUnique = concatUnique;
13916 var SQExprDefaultNameGenerator = (function (_super) {
13917 __extends(SQExprDefaultNameGenerator, _super);
13918 function SQExprDefaultNameGenerator() {
13919 _super.apply(this, arguments);
13920 }
13921 SQExprDefaultNameGenerator.prototype.visitEntity = function (expr) {
13922 return expr.entity;
13923 };
13924 SQExprDefaultNameGenerator.prototype.visitColumnRef = function (expr) {
13925 return expr.source.accept(this) + '.' + expr.ref;
13926 };
13927 SQExprDefaultNameGenerator.prototype.visitMeasureRef = function (expr, fallback) {
13928 return expr.source.accept(this) + '.' + expr.ref;
13929 };
13930 SQExprDefaultNameGenerator.prototype.visitAggr = function (expr, fallback) {
13931 return data.QueryAggregateFunction[expr.func] + '(' + expr.arg.accept(this) + ')';
13932 };
13933 SQExprDefaultNameGenerator.prototype.visitPercentile = function (expr, fallback) {
13934 var func = expr.exclusive
13935 ? 'Percentile.Exc('
13936 : 'Percentile.Inc(';
13937 return func + expr.arg.accept(this) + ', ' + expr.k + ')';
13938 };
13939 SQExprDefaultNameGenerator.prototype.visitArithmetic = function (expr, fallback) {
13940 return powerbi.data.getArithmeticOperatorName(expr.operator) + '(' + expr.left.accept(this) + ', ' + expr.right.accept(this) + ')';
13941 };
13942 SQExprDefaultNameGenerator.prototype.visitConstant = function (expr) {
13943 return 'const';
13944 };
13945 SQExprDefaultNameGenerator.prototype.visitDefault = function (expr, fallback) {
13946 return fallback || 'expr';
13947 };
13948 SQExprDefaultNameGenerator.instance = new SQExprDefaultNameGenerator();
13949 return SQExprDefaultNameGenerator;
13950 }(data.DefaultSQExprVisitorWithArg));
13951 var IsMeasureVisitor = (function (_super) {
13952 __extends(IsMeasureVisitor, _super);
13953 function IsMeasureVisitor() {
13954 _super.apply(this, arguments);
13955 }
13956 IsMeasureVisitor.prototype.visitMeasureRef = function (expr) {
13957 return true;
13958 };
13959 IsMeasureVisitor.prototype.visitAggr = function (expr) {
13960 return true;
13961 };
13962 IsMeasureVisitor.prototype.visitArithmetic = function (expr) {
13963 return true;
13964 };
13965 IsMeasureVisitor.prototype.visitDefault = function (expr) {
13966 return false;
13967 };
13968 IsMeasureVisitor.instance = new IsMeasureVisitor();
13969 return IsMeasureVisitor;
13970 }(data.DefaultSQExprVisitor));
13971 var IsDefaultValueVisitor = (function (_super) {
13972 __extends(IsDefaultValueVisitor, _super);
13973 function IsDefaultValueVisitor() {
13974 _super.apply(this, arguments);
13975 }
13976 IsDefaultValueVisitor.prototype.visitCompare = function (expr) {
13977 if (expr.comparison !== data.QueryComparisonKind.Equal)
13978 return false;
13979 return expr.right.accept(this);
13980 };
13981 IsDefaultValueVisitor.prototype.visitAnd = function (expr) {
13982 return expr.left.accept(this) && expr.right.accept(this);
13983 };
13984 IsDefaultValueVisitor.prototype.visitDefaultValue = function (expr) {
13985 return true;
13986 };
13987 IsDefaultValueVisitor.prototype.visitDefault = function (expr) {
13988 return false;
13989 };
13990 IsDefaultValueVisitor.instance = new IsDefaultValueVisitor();
13991 return IsDefaultValueVisitor;
13992 }(data.DefaultSQExprVisitor));
13993 var IsAnyValueVisitor = (function (_super) {
13994 __extends(IsAnyValueVisitor, _super);
13995 function IsAnyValueVisitor() {
13996 _super.apply(this, arguments);
13997 }
13998 IsAnyValueVisitor.prototype.visitCompare = function (expr) {
13999 if (expr.comparison !== data.QueryComparisonKind.Equal)
14000 return false;
14001 return expr.right.accept(this);
14002 };
14003 IsAnyValueVisitor.prototype.visitAnd = function (expr) {
14004 return expr.left.accept(this) && expr.right.accept(this);
14005 };
14006 IsAnyValueVisitor.prototype.visitAnyValue = function (expr) {
14007 return true;
14008 };
14009 IsAnyValueVisitor.prototype.visitDefault = function (expr) {
14010 return false;
14011 };
14012 IsAnyValueVisitor.instance = new IsAnyValueVisitor();
14013 return IsAnyValueVisitor;
14014 }(data.DefaultSQExprVisitor));
14015 })(SQExprUtils = data.SQExprUtils || (data.SQExprUtils = {}));
14016 })(data = powerbi.data || (powerbi.data = {}));
14017})(powerbi || (powerbi = {}));
14018/*
14019 * Power BI Visualizations
14020 *
14021 * Copyright (c) Microsoft Corporation
14022 * All rights reserved.
14023 * MIT License
14024 *
14025 * Permission is hereby granted, free of charge, to any person obtaining a copy
14026 * of this software and associated documentation files (the ""Software""), to deal
14027 * in the Software without restriction, including without limitation the rights
14028 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14029 * copies of the Software, and to permit persons to whom the Software is
14030 * furnished to do so, subject to the following conditions:
14031 *
14032 * The above copyright notice and this permission notice shall be included in
14033 * all copies or substantial portions of the Software.
14034 *
14035 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14036 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14037 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14038 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14039 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14040 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14041 * THE SOFTWARE.
14042 */
14043var powerbi;
14044(function (powerbi) {
14045 var data;
14046 (function (data) {
14047 var SemanticQueryRewriter = (function () {
14048 function SemanticQueryRewriter(exprRewriter) {
14049 this.exprRewriter = exprRewriter;
14050 }
14051 SemanticQueryRewriter.prototype.rewriteFrom = function (fromValue) {
14052 var fromContents = {};
14053 var originalFrom = fromValue, originalFromKeys = originalFrom.keys();
14054 for (var i = 0, len = originalFromKeys.length; i < len; i++) {
14055 var keyName = originalFromKeys[i], originalEntityRef = originalFrom.entity(keyName), originalEntityExpr = data.SQExprBuilder.entity(originalEntityRef.schema, originalEntityRef.entity, keyName), updatedEntityExpr = originalEntityExpr.accept(this.exprRewriter);
14056 fromContents[keyName] = {
14057 schema: updatedEntityExpr.schema,
14058 entity: updatedEntityExpr.entity,
14059 };
14060 }
14061 return new data.SQFrom(fromContents);
14062 };
14063 SemanticQueryRewriter.prototype.rewriteSelect = function (selectItems, from) {
14064 debug.assertValue(selectItems, 'selectItems');
14065 debug.assertValue(from, 'from');
14066 return this.rewriteNamedSQExpressions(selectItems, from);
14067 };
14068 SemanticQueryRewriter.prototype.rewriteGroupBy = function (groupByitems, from) {
14069 debug.assertAnyValue(groupByitems, 'groupByitems');
14070 debug.assertValue(from, 'from');
14071 if (_.isEmpty(groupByitems))
14072 return;
14073 return this.rewriteNamedSQExpressions(groupByitems, from);
14074 };
14075 SemanticQueryRewriter.prototype.rewriteNamedSQExpressions = function (expressions, from) {
14076 var _this = this;
14077 debug.assertValue(expressions, 'expressions');
14078 return _.map(expressions, function (item) {
14079 return {
14080 name: item.name,
14081 expr: data.SQExprRewriterWithSourceRenames.rewrite(item.expr.accept(_this.exprRewriter), from)
14082 };
14083 });
14084 };
14085 SemanticQueryRewriter.prototype.rewriteOrderBy = function (orderByItems, from) {
14086 debug.assertAnyValue(orderByItems, 'orderByItems');
14087 debug.assertValue(from, 'from');
14088 if (_.isEmpty(orderByItems))
14089 return;
14090 var orderBy = [];
14091 for (var i = 0, len = orderByItems.length; i < len; i++) {
14092 var item = orderByItems[i], updatedExpr = data.SQExprRewriterWithSourceRenames.rewrite(item.expr.accept(this.exprRewriter), from);
14093 orderBy.push({
14094 direction: item.direction,
14095 expr: updatedExpr,
14096 });
14097 }
14098 return orderBy;
14099 };
14100 SemanticQueryRewriter.prototype.rewriteWhere = function (whereItems, from) {
14101 var _this = this;
14102 debug.assertAnyValue(whereItems, 'whereItems');
14103 debug.assertValue(from, 'from');
14104 if (_.isEmpty(whereItems))
14105 return;
14106 var where = [];
14107 for (var i = 0, len = whereItems.length; i < len; i++) {
14108 var originalWhere = whereItems[i];
14109 var updatedWhere = {
14110 condition: data.SQExprRewriterWithSourceRenames.rewrite(originalWhere.condition.accept(this.exprRewriter), from),
14111 };
14112 if (originalWhere.target)
14113 updatedWhere.target = _.map(originalWhere.target, function (e) { return data.SQExprRewriterWithSourceRenames.rewrite(e.accept(_this.exprRewriter), from); });
14114 where.push(updatedWhere);
14115 }
14116 return where;
14117 };
14118 return SemanticQueryRewriter;
14119 }());
14120 data.SemanticQueryRewriter = SemanticQueryRewriter;
14121 })(data = powerbi.data || (powerbi.data = {}));
14122})(powerbi || (powerbi = {}));
14123/*
14124 * Power BI Visualizations
14125 *
14126 * Copyright (c) Microsoft Corporation
14127 * All rights reserved.
14128 * MIT License
14129 *
14130 * Permission is hereby granted, free of charge, to any person obtaining a copy
14131 * of this software and associated documentation files (the ""Software""), to deal
14132 * in the Software without restriction, including without limitation the rights
14133 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14134 * copies of the Software, and to permit persons to whom the Software is
14135 * furnished to do so, subject to the following conditions:
14136 *
14137 * The above copyright notice and this permission notice shall be included in
14138 * all copies or substantial portions of the Software.
14139 *
14140 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14141 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14142 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14143 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14144 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14145 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14146 * THE SOFTWARE.
14147 */
14148var powerbi;
14149(function (powerbi) {
14150 var data;
14151 (function (data) {
14152 var ArrayExtensions = jsCommon.ArrayExtensions;
14153 /**
14154 * Represents a semantic query that is:
14155 * 1) Round-trippable with a JSON QueryDefinition.
14156 * 2) Immutable
14157 * 3) Long-lived and does not have strong references to a conceptual model (only names).
14158 */
14159 var SemanticQuery = (function () {
14160 function SemanticQuery(from, where, orderBy, select, groupBy) {
14161 debug.assertValue(from, 'from');
14162 debug.assertValue(select, 'select');
14163 this.fromValue = from;
14164 this.whereItems = where;
14165 this.orderByItems = orderBy;
14166 this.selectItems = select;
14167 this.groupByItems = groupBy;
14168 }
14169 SemanticQuery.create = function () {
14170 if (!SemanticQuery.empty)
14171 SemanticQuery.empty = new SemanticQuery(new SQFrom(), null, null, [], null);
14172 return SemanticQuery.empty;
14173 };
14174 SemanticQuery.createWithTrimmedFrom = function (from, where, orderBy, select, groupBy) {
14175 var unreferencedKeyFinder = new UnreferencedKeyFinder(from.keys());
14176 // Where
14177 if (where) {
14178 for (var i = 0, len = where.length; i < len; i++) {
14179 var filter = where[i];
14180 filter.condition.accept(unreferencedKeyFinder);
14181 var filterTarget = filter.target;
14182 if (filterTarget) {
14183 for (var j = 0, jlen = filterTarget.length; j < jlen; j++)
14184 if (filterTarget[j])
14185 filterTarget[j].accept(unreferencedKeyFinder);
14186 }
14187 }
14188 }
14189 // OrderBy
14190 if (orderBy) {
14191 for (var i = 0, len = orderBy.length; i < len; i++)
14192 orderBy[i].expr.accept(unreferencedKeyFinder);
14193 }
14194 // Select
14195 for (var i = 0, len = select.length; i < len; i++)
14196 select[i].expr.accept(unreferencedKeyFinder);
14197 // GroupBy
14198 if (groupBy) {
14199 for (var i = 0, len = groupBy.length; i < len; i++)
14200 groupBy[i].expr.accept(unreferencedKeyFinder);
14201 }
14202 var unreferencedKeys = unreferencedKeyFinder.result();
14203 for (var i = 0, len = unreferencedKeys.length; i < len; i++)
14204 from.remove(unreferencedKeys[i]);
14205 return new SemanticQuery(from, where, orderBy, select, groupBy);
14206 };
14207 SemanticQuery.prototype.from = function () {
14208 return this.fromValue.clone();
14209 };
14210 SemanticQuery.prototype.select = function (values) {
14211 if (_.isEmpty(arguments))
14212 return this.getSelect();
14213 return this.setSelect(values);
14214 };
14215 SemanticQuery.prototype.getSelect = function () {
14216 return SemanticQuery.createNamedExpressionArray(this.selectItems);
14217 };
14218 SemanticQuery.createNamedExpressionArray = function (items) {
14219 return ArrayExtensions.extendWithName(_.map(items, function (s) {
14220 return {
14221 name: s.name,
14222 expr: s.expr,
14223 };
14224 }));
14225 };
14226 SemanticQuery.prototype.setSelect = function (values) {
14227 var from = this.fromValue.clone();
14228 var selectItems = SemanticQuery.rewriteExpressionsWithSourceRenames(values, from);
14229 return SemanticQuery.createWithTrimmedFrom(from, this.whereItems, this.orderByItems, selectItems, this.groupByItems);
14230 };
14231 SemanticQuery.rewriteExpressionsWithSourceRenames = function (values, from) {
14232 var items = [];
14233 for (var i = 0, len = values.length; i < len; i++) {
14234 var value = values[i];
14235 items.push({
14236 name: value.name,
14237 expr: SQExprRewriterWithSourceRenames.rewrite(value.expr, from)
14238 });
14239 }
14240 return items;
14241 };
14242 /** Removes the given expression from the select. */
14243 SemanticQuery.prototype.removeSelect = function (expr) {
14244 debug.assertValue(expr, 'expr');
14245 var originalItems = this.selectItems, selectItems = [];
14246 for (var i = 0, len = originalItems.length; i < len; i++) {
14247 var originalExpr = originalItems[i];
14248 if (data.SQExpr.equals(originalExpr.expr, expr))
14249 continue;
14250 selectItems.push(originalExpr);
14251 }
14252 return SemanticQuery.createWithTrimmedFrom(this.fromValue.clone(), this.whereItems, this.orderByItems, selectItems, this.groupByItems);
14253 };
14254 /** Removes the given expression from order by. */
14255 SemanticQuery.prototype.removeOrderBy = function (expr) {
14256 var sorts = this.orderBy();
14257 for (var i = sorts.length - 1; i >= 0; i--) {
14258 if (data.SQExpr.equals(sorts[i].expr, expr))
14259 sorts.splice(i, 1);
14260 }
14261 return SemanticQuery.createWithTrimmedFrom(this.fromValue.clone(), this.whereItems, sorts, this.selectItems, this.groupByItems);
14262 };
14263 SemanticQuery.prototype.selectNameOf = function (expr) {
14264 var index = data.SQExprUtils.indexOfExpr(_.map(this.selectItems, function (s) { return s.expr; }), expr);
14265 if (index >= 0)
14266 return this.selectItems[index].name;
14267 };
14268 SemanticQuery.prototype.setSelectAt = function (index, expr) {
14269 debug.assertValue(expr, 'expr');
14270 if (index >= this.selectItems.length)
14271 return;
14272 var select = this.select(), from = this.fromValue.clone(), originalName = select[index].name;
14273 select[index] = {
14274 name: originalName,
14275 expr: SQExprRewriterWithSourceRenames.rewrite(expr, from)
14276 };
14277 return SemanticQuery.createWithTrimmedFrom(from, this.whereItems, this.orderByItems, select, this.groupByItems);
14278 };
14279 /** Adds a the expression to the select clause. */
14280 SemanticQuery.prototype.addSelect = function (expr, exprName) {
14281 debug.assertValue(expr, 'expr');
14282 var selectItems = this.select(), from = this.fromValue.clone();
14283 selectItems.push(this.createNamedExpr(selectItems, from, expr, exprName));
14284 return SemanticQuery.createWithTrimmedFrom(from, this.whereItems, this.orderByItems, selectItems, this.groupByItems);
14285 };
14286 SemanticQuery.prototype.createNamedExpr = function (currentNames, from, expr, exprName) {
14287 return {
14288 name: data.SQExprUtils.uniqueName(currentNames, expr, exprName),
14289 expr: SQExprRewriterWithSourceRenames.rewrite(expr, from)
14290 };
14291 };
14292 SemanticQuery.prototype.groupBy = function (values) {
14293 if (_.isEmpty(arguments))
14294 return this.getGroupBy();
14295 return this.setGroupBy(values);
14296 };
14297 SemanticQuery.prototype.getGroupBy = function () {
14298 return SemanticQuery.createNamedExpressionArray(this.groupByItems);
14299 };
14300 SemanticQuery.prototype.setGroupBy = function (values) {
14301 var from = this.fromValue.clone();
14302 var groupByItems = SemanticQuery.rewriteExpressionsWithSourceRenames(values, from);
14303 return SemanticQuery.createWithTrimmedFrom(from, this.whereItems, this.orderByItems, this.selectItems, groupByItems);
14304 };
14305 SemanticQuery.prototype.addGroupBy = function (expr) {
14306 debug.assertValue(expr, 'expr');
14307 var groupByItems = this.groupBy(), from = this.fromValue.clone();
14308 groupByItems.push(this.createNamedExpr(groupByItems, from, expr));
14309 return SemanticQuery.createWithTrimmedFrom(from, this.whereItems, this.orderByItems, this.selectItems, groupByItems);
14310 };
14311 SemanticQuery.prototype.orderBy = function (values) {
14312 if (_.isEmpty(arguments))
14313 return this.getOrderBy();
14314 return this.setOrderBy(values);
14315 };
14316 SemanticQuery.prototype.getOrderBy = function () {
14317 var result = [];
14318 var orderBy = this.orderByItems;
14319 if (orderBy) {
14320 for (var i = 0, len = orderBy.length; i < len; i++) {
14321 var clause = orderBy[i];
14322 result.push({
14323 expr: clause.expr,
14324 direction: clause.direction,
14325 });
14326 }
14327 }
14328 return result;
14329 };
14330 SemanticQuery.prototype.setOrderBy = function (values) {
14331 debug.assertValue(values, 'values');
14332 var updatedOrderBy = [], from = this.fromValue.clone();
14333 for (var i = 0, len = values.length; i < len; i++) {
14334 var clause = values[i];
14335 updatedOrderBy.push({
14336 expr: SQExprRewriterWithSourceRenames.rewrite(clause.expr, from),
14337 direction: clause.direction,
14338 });
14339 }
14340 return SemanticQuery.createWithTrimmedFrom(from, this.whereItems, updatedOrderBy, this.selectItems, this.groupByItems);
14341 };
14342 SemanticQuery.prototype.where = function (values) {
14343 if (_.isEmpty(arguments))
14344 return this.getWhere();
14345 return this.setWhere(values);
14346 };
14347 SemanticQuery.prototype.getWhere = function () {
14348 var result = [];
14349 var whereItems = this.whereItems;
14350 if (whereItems) {
14351 for (var i = 0, len = whereItems.length; i < len; i++)
14352 result.push(whereItems[i]);
14353 }
14354 return result;
14355 };
14356 SemanticQuery.prototype.setWhere = function (values) {
14357 debug.assertValue(values, 'values');
14358 var updatedWhere = [], from = this.fromValue.clone();
14359 for (var i = 0, len = values.length; i < len; i++) {
14360 var filter = values[i];
14361 var updatedFilter = {
14362 condition: SQExprRewriterWithSourceRenames.rewrite(filter.condition, from),
14363 };
14364 var filterTarget = filter.target;
14365 if (filterTarget) {
14366 updatedFilter.target = [];
14367 for (var j = 0, jlen = filterTarget.length; j < jlen; j++)
14368 if (filterTarget[j]) {
14369 var updatedTarget = SQExprRewriterWithSourceRenames.rewrite(filterTarget[j], from);
14370 updatedFilter.target.push(updatedTarget);
14371 }
14372 }
14373 updatedWhere.push(updatedFilter);
14374 }
14375 return SemanticQuery.createWithTrimmedFrom(from, updatedWhere, this.orderByItems, this.selectItems, this.groupByItems);
14376 };
14377 SemanticQuery.prototype.addWhere = function (filter) {
14378 debug.assertValue(filter, 'filter');
14379 var updatedWhere = this.where(), incomingWhere = filter.where(), from = this.fromValue.clone();
14380 for (var i = 0, len = incomingWhere.length; i < len; i++) {
14381 var clause = incomingWhere[i];
14382 var updatedClause = {
14383 condition: SQExprRewriterWithSourceRenames.rewrite(clause.condition, from),
14384 };
14385 if (clause.target)
14386 updatedClause.target = _.map(clause.target, function (t) { return SQExprRewriterWithSourceRenames.rewrite(t, from); });
14387 updatedWhere.push(updatedClause);
14388 }
14389 return SemanticQuery.createWithTrimmedFrom(from, updatedWhere, this.orderByItems, this.selectItems, this.groupByItems);
14390 };
14391 SemanticQuery.prototype.rewrite = function (exprRewriter) {
14392 var rewriter = new data.SemanticQueryRewriter(exprRewriter);
14393 var from = rewriter.rewriteFrom(this.fromValue);
14394 var where = rewriter.rewriteWhere(this.whereItems, from);
14395 var orderBy = rewriter.rewriteOrderBy(this.orderByItems, from);
14396 var select = rewriter.rewriteSelect(this.selectItems, from);
14397 var groupBy = rewriter.rewriteGroupBy(this.groupByItems, from);
14398 return SemanticQuery.createWithTrimmedFrom(from, where, orderBy, select, groupBy);
14399 };
14400 return SemanticQuery;
14401 }());
14402 data.SemanticQuery = SemanticQuery;
14403 /** Represents a semantic filter condition. Round-trippable with a JSON FilterDefinition. Instances of this class are immutable. */
14404 var SemanticFilter = (function () {
14405 function SemanticFilter(from, where) {
14406 debug.assertValue(from, 'from');
14407 debug.assertValue(where, 'where');
14408 this.fromValue = from;
14409 this.whereItems = where;
14410 }
14411 SemanticFilter.fromSQExpr = function (contract) {
14412 debug.assertValue(contract, 'contract');
14413 var from = new SQFrom();
14414 var rewrittenContract = SQExprRewriterWithSourceRenames.rewrite(contract, from);
14415 // DEVNOTE targets of some filters are visual specific and will get resolved only during query generation.
14416 // Thus not setting a target here.
14417 var where = [{
14418 condition: rewrittenContract
14419 }];
14420 return new SemanticFilter(from, where);
14421 };
14422 SemanticFilter.getDefaultValueFilter = function (fieldSQExprs) {
14423 return SemanticFilter.getDataViewScopeIdentityComparisonFilters(fieldSQExprs, data.SQExprBuilder.defaultValue());
14424 };
14425 SemanticFilter.getAnyValueFilter = function (fieldSQExprs) {
14426 return SemanticFilter.getDataViewScopeIdentityComparisonFilters(fieldSQExprs, data.SQExprBuilder.anyValue());
14427 };
14428 SemanticFilter.getDataViewScopeIdentityComparisonFilters = function (fieldSQExprs, value) {
14429 debug.assertValue(fieldSQExprs, 'fieldSQExprs');
14430 debug.assertValue(value, 'value');
14431 if (fieldSQExprs instanceof Array) {
14432 var values = Array.apply(null, Array(fieldSQExprs.length)).map(function () { return value; });
14433 return SemanticFilter.fromSQExpr(data.SQExprUtils.getDataViewScopeIdentityComparisonExpr(fieldSQExprs, values));
14434 }
14435 return SemanticFilter.fromSQExpr(data.SQExprBuilder.equal(fieldSQExprs, value));
14436 };
14437 SemanticFilter.prototype.from = function () {
14438 return this.fromValue.clone();
14439 };
14440 SemanticFilter.prototype.conditions = function () {
14441 var expressions = [];
14442 var where = this.whereItems;
14443 for (var i = 0, len = where.length; i < len; i++) {
14444 var filter = where[i];
14445 expressions.push(filter.condition);
14446 }
14447 return expressions;
14448 };
14449 SemanticFilter.prototype.where = function () {
14450 var result = [];
14451 var whereItems = this.whereItems;
14452 for (var i = 0, len = whereItems.length; i < len; i++)
14453 result.push(whereItems[i]);
14454 return result;
14455 };
14456 SemanticFilter.prototype.rewrite = function (exprRewriter) {
14457 var rewriter = new data.SemanticQueryRewriter(exprRewriter);
14458 var from = rewriter.rewriteFrom(this.fromValue);
14459 var where = rewriter.rewriteWhere(this.whereItems, from);
14460 return new SemanticFilter(from, where);
14461 };
14462 SemanticFilter.prototype.validate = function (schema, aggrUtils, errors) {
14463 var validator = new data.SQExprValidationVisitor(schema, aggrUtils, errors);
14464 this.rewrite(validator);
14465 return validator.errors;
14466 };
14467 /** Merges a list of SemanticFilters into one. */
14468 SemanticFilter.merge = function (filters) {
14469 if (_.isEmpty(filters))
14470 return null;
14471 if (filters.length === 1)
14472 return filters[0];
14473 var firstFilter = filters[0];
14474 var from = firstFilter.from(), where = ArrayExtensions.take(firstFilter.whereItems, firstFilter.whereItems.length);
14475 for (var i = 1, len = filters.length; i < len; i++)
14476 SemanticFilter.applyFilter(filters[i], from, where);
14477 return new SemanticFilter(from, where);
14478 };
14479 SemanticFilter.isDefaultFilter = function (filter) {
14480 if (!filter || filter.where().length !== 1)
14481 return false;
14482 return data.SQExprUtils.isDefaultValue(filter.where()[0].condition);
14483 };
14484 SemanticFilter.isAnyFilter = function (filter) {
14485 if (!filter || filter.where().length !== 1)
14486 return false;
14487 return data.SQExprUtils.isAnyValue(filter.where()[0].condition);
14488 };
14489 SemanticFilter.isSameFilter = function (leftFilter, rightFilter) {
14490 if (jsCommon.JsonComparer.equals(leftFilter, rightFilter)) {
14491 return !((SemanticFilter.isDefaultFilter(leftFilter) && SemanticFilter.isAnyFilter(rightFilter))
14492 || (SemanticFilter.isAnyFilter(leftFilter) && SemanticFilter.isDefaultFilter(rightFilter)));
14493 }
14494 return false;
14495 };
14496 SemanticFilter.applyFilter = function (filter, from, where) {
14497 debug.assertValue(filter, 'filter');
14498 debug.assertValue(from, 'from');
14499 debug.assertValue(where, 'where');
14500 // Where
14501 var filterWhereItems = filter.whereItems;
14502 for (var i = 0; i < filterWhereItems.length; i++) {
14503 var filterWhereItem = filterWhereItems[i];
14504 var updatedWhereItem = {
14505 condition: SQExprRewriterWithSourceRenames.rewrite(filterWhereItem.condition, from),
14506 };
14507 if (filterWhereItem.target)
14508 updatedWhereItem.target = _.map(filterWhereItem.target, function (e) { return SQExprRewriterWithSourceRenames.rewrite(e, from); });
14509 where.push(updatedWhereItem);
14510 }
14511 };
14512 return SemanticFilter;
14513 }());
14514 data.SemanticFilter = SemanticFilter;
14515 /** Represents a SemanticQuery/SemanticFilter from clause. */
14516 var SQFrom = (function () {
14517 function SQFrom(items) {
14518 this.items = items || {};
14519 }
14520 SQFrom.prototype.keys = function () {
14521 return Object.keys(this.items);
14522 };
14523 SQFrom.prototype.entity = function (key) {
14524 return this.items[key];
14525 };
14526 SQFrom.prototype.ensureEntity = function (entity, desiredVariableName) {
14527 debug.assertValue(entity, 'entity');
14528 // 1) Reuse a reference to the entity among the already referenced
14529 var keys = this.keys();
14530 for (var i_1 = 0, len = keys.length; i_1 < len; i_1++) {
14531 var key = keys[i_1], item = this.items[key];
14532 if (item && entity.entity === item.entity && entity.schema === item.schema)
14533 return { name: key };
14534 }
14535 // 2) Add a reference to the entity
14536 var candidateName = desiredVariableName || this.candidateName(entity.entity), uniqueName = candidateName, i = 2;
14537 while (this.items[uniqueName]) {
14538 uniqueName = candidateName + i++;
14539 }
14540 this.items[uniqueName] = entity;
14541 return { name: uniqueName, new: true };
14542 };
14543 SQFrom.prototype.remove = function (key) {
14544 delete this.items[key];
14545 };
14546 /** Converts the entity name into a short reference name. Follows the Semantic Query convention of a short name. */
14547 SQFrom.prototype.candidateName = function (ref) {
14548 debug.assertValue(ref, 'ref');
14549 var idx = ref.lastIndexOf('.');
14550 if (idx >= 0 && (idx !== ref.length - 1))
14551 ref = ref.substr(idx + 1);
14552 return ref.substring(0, 1).toLowerCase();
14553 };
14554 SQFrom.prototype.clone = function () {
14555 // NOTE: consider deprecating this method and instead making QueryFrom be CopyOnWrite (currently we proactively clone).
14556 var cloned = new SQFrom();
14557 // NOTE: we use extend rather than prototypical inheritance on items because we use Object.keys.
14558 $.extend(cloned.items, this.items);
14559 return cloned;
14560 };
14561 return SQFrom;
14562 }());
14563 data.SQFrom = SQFrom;
14564 var SQExprRewriterWithSourceRenames = (function (_super) {
14565 __extends(SQExprRewriterWithSourceRenames, _super);
14566 function SQExprRewriterWithSourceRenames(renames) {
14567 debug.assertValue(renames, 'renames');
14568 _super.call(this);
14569 this.renames = renames;
14570 }
14571 SQExprRewriterWithSourceRenames.prototype.visitEntity = function (expr) {
14572 var updatedName = this.renames[expr.entity];
14573 if (updatedName)
14574 return new data.SQEntityExpr(expr.schema, expr.entity, updatedName);
14575 return _super.prototype.visitEntity.call(this, expr);
14576 };
14577 SQExprRewriterWithSourceRenames.prototype.rewriteFilter = function (filter) {
14578 debug.assertValue(filter, 'filter');
14579 var updatedTargets = undefined;
14580 if (filter.target)
14581 updatedTargets = this.rewriteArray(filter.target);
14582 var updatedCondition = filter.condition.accept(this);
14583 if (filter.condition === updatedCondition && filter.target === updatedTargets)
14584 return filter;
14585 var updatedFilter = {
14586 condition: updatedCondition,
14587 };
14588 if (updatedTargets)
14589 updatedFilter.target = updatedTargets;
14590 return updatedFilter;
14591 };
14592 SQExprRewriterWithSourceRenames.prototype.rewriteArray = function (exprs) {
14593 debug.assertValue(exprs, 'exprs');
14594 var updatedExprs;
14595 for (var i = 0, len = exprs.length; i < len; i++) {
14596 var expr = exprs[i], rewrittenExpr = expr.accept(this);
14597 if (expr !== rewrittenExpr && !updatedExprs)
14598 updatedExprs = ArrayExtensions.take(exprs, i);
14599 if (updatedExprs)
14600 updatedExprs.push(rewrittenExpr);
14601 }
14602 return updatedExprs || exprs;
14603 };
14604 SQExprRewriterWithSourceRenames.rewrite = function (expr, from) {
14605 debug.assertValue(expr, 'expr');
14606 debug.assertValue(from, 'from');
14607 var renames = QuerySourceRenameDetector.run(expr, from);
14608 var rewriter = new SQExprRewriterWithSourceRenames(renames);
14609 return expr.accept(rewriter);
14610 };
14611 return SQExprRewriterWithSourceRenames;
14612 }(data.SQExprRewriter));
14613 data.SQExprRewriterWithSourceRenames = SQExprRewriterWithSourceRenames;
14614 /** Responsible for updating a QueryFrom based on SQExpr references. */
14615 var QuerySourceRenameDetector = (function (_super) {
14616 __extends(QuerySourceRenameDetector, _super);
14617 function QuerySourceRenameDetector(from) {
14618 debug.assertValue(from, 'from');
14619 _super.call(this);
14620 this.from = from;
14621 this.renames = {};
14622 }
14623 QuerySourceRenameDetector.run = function (expr, from) {
14624 var detector = new QuerySourceRenameDetector(from);
14625 expr.accept(detector);
14626 return detector.renames;
14627 };
14628 QuerySourceRenameDetector.prototype.visitEntity = function (expr) {
14629 // TODO: Renames must take the schema into account, not just entity set name.
14630 var existingEntity = this.from.entity(expr.variable);
14631 if (existingEntity && existingEntity.schema === expr.schema && existingEntity.entity === expr.entity)
14632 return;
14633 var actualEntity = this.from.ensureEntity({
14634 schema: expr.schema,
14635 entity: expr.entity,
14636 }, expr.variable);
14637 this.renames[expr.entity] = actualEntity.name;
14638 };
14639 return QuerySourceRenameDetector;
14640 }(data.DefaultSQExprVisitorWithTraversal));
14641 /** Visitor for finding unreferenced sources. */
14642 var UnreferencedKeyFinder = (function (_super) {
14643 __extends(UnreferencedKeyFinder, _super);
14644 function UnreferencedKeyFinder(keys) {
14645 debug.assertValue(keys, 'keys');
14646 _super.call(this);
14647 this.keys = keys;
14648 }
14649 UnreferencedKeyFinder.prototype.visitEntity = function (expr) {
14650 var index = this.keys.indexOf(expr.variable);
14651 if (index >= 0)
14652 this.keys.splice(index, 1);
14653 };
14654 UnreferencedKeyFinder.prototype.result = function () {
14655 return this.keys;
14656 };
14657 return UnreferencedKeyFinder;
14658 }(data.DefaultSQExprVisitorWithTraversal));
14659 })(data = powerbi.data || (powerbi.data = {}));
14660})(powerbi || (powerbi = {}));
14661/*
14662 * Power BI Visualizations
14663 *
14664 * Copyright (c) Microsoft Corporation
14665 * All rights reserved.
14666 * MIT License
14667 *
14668 * Permission is hereby granted, free of charge, to any person obtaining a copy
14669 * of this software and associated documentation files (the ""Software""), to deal
14670 * in the Software without restriction, including without limitation the rights
14671 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14672 * copies of the Software, and to permit persons to whom the Software is
14673 * furnished to do so, subject to the following conditions:
14674 *
14675 * The above copyright notice and this permission notice shall be included in
14676 * all copies or substantial portions of the Software.
14677 *
14678 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14679 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14680 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14681 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14682 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14683 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14684 * THE SOFTWARE.
14685 */
14686var powerbi;
14687(function (powerbi) {
14688 var data;
14689 (function (data) {
14690 var DataViewTransform = powerbi.data.DataViewTransform;
14691 var SQExprBuilder = powerbi.data.SQExprBuilder;
14692 function createCategoricalDataViewBuilder() {
14693 return new CategoricalDataViewBuilder();
14694 }
14695 data.createCategoricalDataViewBuilder = createCategoricalDataViewBuilder;
14696 var CategoricalDataViewBuilder = (function () {
14697 function CategoricalDataViewBuilder() {
14698 this.categories = [];
14699 this.staticMeasureColumns = [];
14700 this.dynamicMeasureColumns = [];
14701 this.columnIndex = 0;
14702 }
14703 CategoricalDataViewBuilder.prototype.withCategory = function (options) {
14704 var categoryValues = options.values, identityFrom = options.identityFrom, type = options.source.type;
14705 var categoryColumn = {
14706 source: options.source,
14707 identityFields: options.identityFrom.fields,
14708 identity: options.identityFrom.identities || [],
14709 values: categoryValues,
14710 };
14711 if (!options.identityFrom.identities) {
14712 for (var categoryIndex = 0, categoryLength = categoryValues.length; categoryIndex < categoryLength; categoryIndex++) {
14713 categoryColumn.identity.push(getScopeIdentity(identityFrom, categoryIndex, categoryValues[categoryIndex], type));
14714 }
14715 }
14716 if (!this.categories)
14717 this.categories = [];
14718 this.categories.push(categoryColumn);
14719 return this;
14720 };
14721 CategoricalDataViewBuilder.prototype.withCategories = function (categories) {
14722 if (_.isEmpty(this.categories))
14723 this.categories = categories;
14724 else
14725 Array.prototype.push.apply(this.categories, categories);
14726 return this;
14727 };
14728 /**
14729 * Adds static series columns.
14730 *
14731 * Note that it is illegal to have both dynamic series and static series in a visual DataViewCategorical. It is only legal to have them both in
14732 * a query DataViewCategorical, where DataViewTransform is expected to split them up into separate visual DataViewCategorical objects.
14733 */
14734 CategoricalDataViewBuilder.prototype.withValues = function (options) {
14735 debug.assertValue(options, 'options');
14736 var columns = options.columns;
14737 debug.assertValue(columns, 'columns');
14738 for (var _i = 0, columns_8 = columns; _i < columns_8.length; _i++) {
14739 var column = columns_8[_i];
14740 this.staticMeasureColumns.push(column.source);
14741 }
14742 this.staticSeriesValues = columns;
14743 return this;
14744 };
14745 /**
14746 * Adds dynamic series columns.
14747 *
14748 * Note that it is illegal to have both dynamic series and static series in a visual DataViewCategorical. It is only legal to have them both in
14749 * a query DataViewCategorical, where DataViewTransform is expected to split them up into separate visual DataViewCategorical objects.
14750 */
14751 CategoricalDataViewBuilder.prototype.withGroupedValues = function (options) {
14752 debug.assertValue(options, 'options');
14753 var groupColumn = options.groupColumn;
14754 debug.assertValue(groupColumn, 'groupColumn');
14755 this.dynamicSeriesMetadata = {
14756 column: groupColumn.source,
14757 identityFrom: groupColumn.identityFrom,
14758 values: groupColumn.values,
14759 };
14760 var valueColumns = options.valueColumns;
14761 for (var _i = 0, valueColumns_1 = valueColumns; _i < valueColumns_1.length; _i++) {
14762 var valueColumn = valueColumns_1[_i];
14763 this.dynamicMeasureColumns.push(valueColumn.source);
14764 }
14765 this.dynamicSeriesValues = options.data;
14766 return this;
14767 };
14768 CategoricalDataViewBuilder.prototype.fillData = function (dataViewValues) {
14769 var categoryColumn = _.first(this.categories);
14770 var categoryLength = (categoryColumn && categoryColumn.values) ? categoryColumn.values.length : 1;
14771 if (this.hasDynamicSeries) {
14772 for (var seriesIndex = 0; seriesIndex < this.dynamicSeriesMetadata.values.length; seriesIndex++) {
14773 var seriesMeasures = this.dynamicSeriesValues[seriesIndex];
14774 debug.assert(seriesMeasures.length === this.dynamicMeasureColumns.length, 'seriesMeasures.length === this.dynamicMeasureColumns.length');
14775 for (var measureIndex = 0, measuresLen = this.dynamicMeasureColumns.length; measureIndex < measuresLen; measureIndex++) {
14776 var groupIndex = seriesIndex * measuresLen + measureIndex;
14777 applySeriesData(dataViewValues[groupIndex], seriesMeasures[measureIndex], categoryLength);
14778 }
14779 }
14780 }
14781 if (this.hasStaticSeries) {
14782 // Note: when the target categorical has both dynamic and static series, append static measures at the end of the values array.
14783 var staticColumnsStartingIndex = this.hasDynamicSeries ? (this.dynamicSeriesValues.length * this.dynamicMeasureColumns.length) : 0;
14784 for (var measureIndex = 0, measuresLen = this.staticMeasureColumns.length; measureIndex < measuresLen; measureIndex++) {
14785 applySeriesData(dataViewValues[staticColumnsStartingIndex + measureIndex], this.staticSeriesValues[measureIndex], categoryLength);
14786 }
14787 }
14788 };
14789 /**
14790 * Returns the DataView with metadata and DataViewCategorical.
14791 * Returns undefined if the combination of parameters is illegal, such as having both dynamic series and static series when building a visual DataView.
14792 */
14793 CategoricalDataViewBuilder.prototype.build = function () {
14794 var metadataColumns = [];
14795 var categorical = {};
14796 var categoryMetadata = this.categories;
14797 var dynamicSeriesMetadata = this.dynamicSeriesMetadata;
14798 // --- Build metadata columns and value groups ---
14799 for (var _i = 0, categoryMetadata_1 = categoryMetadata; _i < categoryMetadata_1.length; _i++) {
14800 var columnMetadata = categoryMetadata_1[_i];
14801 pushIfNotExists(metadataColumns, columnMetadata.source);
14802 }
14803 if (this.hasDynamicSeries) {
14804 // Dynamic series, or Dyanmic & Static series.
14805 pushIfNotExists(metadataColumns, dynamicSeriesMetadata.column);
14806 categorical.values = DataViewTransform.createValueColumns([], dynamicSeriesMetadata.identityFrom.fields, dynamicSeriesMetadata.column);
14807 // For each series value we will make one column per measure
14808 var seriesValues = dynamicSeriesMetadata.values;
14809 for (var seriesIndex = 0; seriesIndex < seriesValues.length; seriesIndex++) {
14810 var seriesValue = seriesValues[seriesIndex];
14811 var seriesIdentity = getScopeIdentity(dynamicSeriesMetadata.identityFrom, seriesIndex, seriesValue, dynamicSeriesMetadata.column.type);
14812 for (var _a = 0, _b = this.dynamicMeasureColumns; _a < _b.length; _a++) {
14813 var measure = _b[_a];
14814 var column = _.clone(measure);
14815 column.groupName = seriesValue;
14816 pushIfNotExists(metadataColumns, column);
14817 categorical.values.push({
14818 source: column,
14819 values: [],
14820 identity: seriesIdentity,
14821 });
14822 }
14823 }
14824 if (this.hasStaticSeries) {
14825 // IMPORTANT: In the Dyanmic & Static series case, the groups array shall not include any static group. This is to match the behavior of dsrReader.
14826 // Get the current return value of grouped() before adding static measure columns, an use that as the return value of this categorical.
14827 // Otherwise, the default behavior of DataViewValueColumns.grouped() from DataViewTransform.createValueColumns() is to create series groups from all measure columns.
14828 var dynamicSeriesGroups_1 = categorical.values.grouped();
14829 categorical.values.grouped = function () { return dynamicSeriesGroups_1; };
14830 this.appendStaticMeasureColumns(metadataColumns, categorical.values);
14831 }
14832 }
14833 else {
14834 // Static series only / no series
14835 categorical.values = DataViewTransform.createValueColumns();
14836 this.appendStaticMeasureColumns(metadataColumns, categorical.values);
14837 }
14838 var categories = this.categories;
14839 if (!_.isEmpty(categories))
14840 categorical.categories = categories;
14841 // --- Fill in data point values ---
14842 this.fillData(categorical.values);
14843 var dataView = {
14844 metadata: {
14845 columns: metadataColumns,
14846 },
14847 categorical: categorical,
14848 };
14849 if (this.isLegalDataView(dataView)) {
14850 return dataView;
14851 }
14852 };
14853 CategoricalDataViewBuilder.prototype.appendStaticMeasureColumns = function (metadataColumns, valueColumns) {
14854 debug.assertValue(metadataColumns, 'metadataColumns');
14855 debug.assertValue(valueColumns, 'valueColumns');
14856 if (!_.isEmpty(this.staticMeasureColumns)) {
14857 for (var _i = 0, _a = this.staticMeasureColumns; _i < _a.length; _i++) {
14858 var column = _a[_i];
14859 pushIfNotExists(metadataColumns, column);
14860 valueColumns.push({
14861 source: column,
14862 values: [],
14863 });
14864 }
14865 }
14866 };
14867 CategoricalDataViewBuilder.prototype.isLegalDataView = function (dataView) {
14868 if (this.hasDynamicSeries && this.hasStaticSeries && CategoricalDataViewBuilder.isVisualDataView(dataView.metadata.columns)) {
14869 // It is illegal to have both dynamic series and static series in a visual DataViewCategorical,
14870 // because the DataViewValueColumns interface today cannot express that 100% (see its 'source' property and return value of its 'grouped()' function).
14871 return false;
14872 }
14873 return true;
14874 };
14875 /**
14876 * This function infers that if any metdata column has 'queryName',
14877 * then the user of this builder is building a visual DataView (as opposed to query DataView).
14878 *
14879 * @param metadataColumns The complete collection of metadata columns in the categorical.
14880 */
14881 CategoricalDataViewBuilder.isVisualDataView = function (metadataColumns) {
14882 return !_.isEmpty(metadataColumns) &&
14883 _.any(metadataColumns, function (metadataColumn) { return !!metadataColumn.queryName; });
14884 };
14885 Object.defineProperty(CategoricalDataViewBuilder.prototype, "hasDynamicSeries", {
14886 get: function () {
14887 return !!this.dynamicSeriesMetadata; // In Map visual scenarios, you can have dynamic series without measure columns
14888 },
14889 enumerable: true,
14890 configurable: true
14891 });
14892 Object.defineProperty(CategoricalDataViewBuilder.prototype, "hasStaticSeries", {
14893 get: function () {
14894 return !!this.staticSeriesValues;
14895 },
14896 enumerable: true,
14897 configurable: true
14898 });
14899 return CategoricalDataViewBuilder;
14900 }());
14901 function getScopeIdentity(source, index, value, valueType) {
14902 var identities = source.identities;
14903 if (identities) {
14904 return identities[index];
14905 }
14906 debug.assert(source.fields && source.fields.length === 1, 'Inferring identity, expect exactly one field.');
14907 return data.createDataViewScopeIdentity(SQExprBuilder.equal(source.fields[0], SQExprBuilder.typedConstant(value, valueType)));
14908 }
14909 function pushIfNotExists(items, itemToAdd) {
14910 if (_.contains(items, itemToAdd))
14911 return;
14912 items.push(itemToAdd);
14913 }
14914 function applySeriesData(target, source, categoryLength) {
14915 debug.assertValue(target, 'target');
14916 debug.assertValue(source, 'source');
14917 debug.assertValue(categoryLength, 'categoryLength');
14918 var values = source.values;
14919 debug.assert(categoryLength === values.length, 'categoryLength === values.length');
14920 target.values = values;
14921 var highlights = source.highlights;
14922 if (highlights) {
14923 debug.assert(categoryLength === highlights.length, 'categoryLength === highlights.length');
14924 target.highlights = highlights;
14925 }
14926 var aggregates;
14927 if (source.minLocal !== undefined) {
14928 if (!aggregates)
14929 aggregates = {};
14930 aggregates.minLocal = source.minLocal;
14931 }
14932 if (source.maxLocal !== undefined) {
14933 if (!aggregates)
14934 aggregates = {};
14935 aggregates.maxLocal = source.maxLocal;
14936 }
14937 if (aggregates) {
14938 target.source.aggregates = aggregates;
14939 _.extend(target, aggregates);
14940 }
14941 }
14942 })(data = powerbi.data || (powerbi.data = {}));
14943})(powerbi || (powerbi = {}));
14944/*
14945 * Power BI Visualizations
14946 *
14947 * Copyright (c) Microsoft Corporation
14948 * All rights reserved.
14949 * MIT License
14950 *
14951 * Permission is hereby granted, free of charge, to any person obtaining a copy
14952 * of this software and associated documentation files (the ""Software""), to deal
14953 * in the Software without restriction, including without limitation the rights
14954 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14955 * copies of the Software, and to permit persons to whom the Software is
14956 * furnished to do so, subject to the following conditions:
14957 *
14958 * The above copyright notice and this permission notice shall be included in
14959 * all copies or substantial portions of the Software.
14960 *
14961 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14962 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14963 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14964 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14965 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14966 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14967 * THE SOFTWARE.
14968 */
14969var powerbi;
14970(function (powerbi) {
14971 var data;
14972 (function (data) {
14973 var SQExpr = powerbi.data.SQExpr;
14974 function createStaticEvalContext(colorAllocatorCache, dataView, selectTransforms) {
14975 return new StaticEvalContext(colorAllocatorCache || data.createColorAllocatorCache(), dataView || { metadata: { columns: [] } }, selectTransforms);
14976 }
14977 data.createStaticEvalContext = createStaticEvalContext;
14978 /**
14979 * Represents an eval context over a potentially empty DataView. Only static repetition data view objects
14980 * are supported.
14981 */
14982 var StaticEvalContext = (function () {
14983 function StaticEvalContext(colorAllocatorCache, dataView, selectTransforms) {
14984 debug.assertValue(colorAllocatorCache, 'colorAllocatorCache');
14985 debug.assertValue(dataView, 'dataView');
14986 debug.assertAnyValue(selectTransforms, 'selectTransforms');
14987 this.colorAllocatorCache = colorAllocatorCache;
14988 this.dataView = dataView;
14989 this.selectTransforms = selectTransforms;
14990 }
14991 StaticEvalContext.prototype.getColorAllocator = function (expr) {
14992 return this.colorAllocatorCache.get(expr);
14993 };
14994 StaticEvalContext.prototype.getExprValue = function (expr) {
14995 var dataView = this.dataView, selectTransforms = this.selectTransforms;
14996 if (dataView && dataView.table && selectTransforms)
14997 return getExprValueFromTable(expr, selectTransforms, dataView.table, /*rowIdx*/ 0);
14998 };
14999 StaticEvalContext.prototype.getRoleValue = function (roleName) {
15000 return;
15001 };
15002 return StaticEvalContext;
15003 }());
15004 function getExprValueFromTable(expr, selectTransforms, table, rowIdx) {
15005 debug.assertValue(expr, 'expr');
15006 debug.assertValue(selectTransforms, 'selectTransforms');
15007 debug.assertValue(table, 'table');
15008 debug.assertValue(rowIdx, 'rowIdx');
15009 var rows = table.rows;
15010 if (_.isEmpty(rows) || rows.length <= rowIdx)
15011 return;
15012 var targetExpr = getTargetExpr(expr, selectTransforms);
15013 var cols = table.columns;
15014 for (var selectIdx = 0, selectLen = selectTransforms.length; selectIdx < selectLen; selectIdx++) {
15015 var selectTransform = selectTransforms[selectIdx];
15016 if (!SQExpr.equals(selectTransform.expr, targetExpr) || !selectTransform.queryName)
15017 continue;
15018 for (var colIdx = 0, colLen = cols.length; colIdx < colLen; colIdx++) {
15019 if (selectIdx !== cols[colIdx].index)
15020 continue;
15021 return rows[rowIdx][colIdx];
15022 }
15023 }
15024 }
15025 data.getExprValueFromTable = getExprValueFromTable;
15026 function getTargetExpr(expr, selectTransforms) {
15027 if (SQExpr.isSelectRef(expr)) {
15028 for (var _i = 0, selectTransforms_2 = selectTransforms; _i < selectTransforms_2.length; _i++) {
15029 var selectTransform = selectTransforms_2[_i];
15030 if (selectTransform.queryName === expr.expressionName) {
15031 return selectTransform.expr;
15032 }
15033 }
15034 }
15035 return expr;
15036 }
15037 })(data = powerbi.data || (powerbi.data = {}));
15038})(powerbi || (powerbi = {}));
15039/*
15040 * Power BI Visualizations
15041 *
15042 * Copyright (c) Microsoft Corporation
15043 * All rights reserved.
15044 * MIT License
15045 *
15046 * Permission is hereby granted, free of charge, to any person obtaining a copy
15047 * of this software and associated documentation files (the ""Software""), to deal
15048 * in the Software without restriction, including without limitation the rights
15049 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15050 * copies of the Software, and to permit persons to whom the Software is
15051 * furnished to do so, subject to the following conditions:
15052 *
15053 * The above copyright notice and this permission notice shall be included in
15054 * all copies or substantial portions of the Software.
15055 *
15056 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15057 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15058 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15059 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15060 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15061 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15062 * THE SOFTWARE.
15063 */
15064var powerbi;
15065(function (powerbi) {
15066 var data;
15067 (function (data) {
15068 function createMatrixEvalContext(colorAllocatorProvider, dataViewMatrix) {
15069 // NOTE: Matrix context-sensitive evaluation is not yet implemented.
15070 return data.createStaticEvalContext(colorAllocatorProvider);
15071 }
15072 data.createMatrixEvalContext = createMatrixEvalContext;
15073 })(data = powerbi.data || (powerbi.data = {}));
15074})(powerbi || (powerbi = {}));
15075/*
15076 * Power BI Visualizations
15077 *
15078 * Copyright (c) Microsoft Corporation
15079 * All rights reserved.
15080 * MIT License
15081 *
15082 * Permission is hereby granted, free of charge, to any person obtaining a copy
15083 * of this software and associated documentation files (the ""Software""), to deal
15084 * in the Software without restriction, including without limitation the rights
15085 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15086 * copies of the Software, and to permit persons to whom the Software is
15087 * furnished to do so, subject to the following conditions:
15088 *
15089 * The above copyright notice and this permission notice shall be included in
15090 * all copies or substantial portions of the Software.
15091 *
15092 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15093 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15094 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15095 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15096 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15097 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15098 * THE SOFTWARE.
15099 */
15100var powerbi;
15101(function (powerbi_1) {
15102 var StringExtensions = jsCommon.StringExtensions;
15103 var Formatting = jsCommon.Formatting;
15104 var RegExpExtensions = jsCommon.RegExpExtensions;
15105 /** Formatting Encoder */
15106 var FormattingEncoder;
15107 (function (FormattingEncoder) {
15108 function preserveEscaped(format, specialChars) {
15109 // Unicode U+E000 - U+F8FF is a private area and so we can use the chars from the range to encode the escaped sequences
15110 var length = specialChars.length;
15111 for (var i = 0; i < length; i++) {
15112 var oldText = "\\" + specialChars[i];
15113 var newText = String.fromCharCode(0xE000 + i);
15114 format = StringExtensions.replaceAll(format, oldText, newText);
15115 }
15116 return format;
15117 }
15118 FormattingEncoder.preserveEscaped = preserveEscaped;
15119 function restoreEscaped(format, specialChars) {
15120 // After formatting is complete we should restore the encoded escaped chars into the unescaped chars
15121 var length = specialChars.length;
15122 for (var i = 0; i < length; i++) {
15123 var oldText = String.fromCharCode(0xE000 + i);
15124 var newText = specialChars[i];
15125 format = StringExtensions.replaceAll(format, oldText, newText);
15126 }
15127 return StringExtensions.replaceAll(format, "\\", "");
15128 }
15129 FormattingEncoder.restoreEscaped = restoreEscaped;
15130 function preserveLiterals(format, literals) {
15131 // Unicode U+E000 - U+F8FF is a private area and so we can use the chars from the range to encode the escaped sequences
15132 format = StringExtensions.replaceAll(format, "\"", "'");
15133 for (var i = 0;; i++) {
15134 var fromIndex = format.indexOf("'");
15135 if (fromIndex < 0) {
15136 break;
15137 }
15138 var toIndex = format.indexOf("'", fromIndex + 1);
15139 if (toIndex < 0) {
15140 break;
15141 }
15142 var literal = format.substring(fromIndex, toIndex + 1);
15143 literals.push(literal.substring(1, toIndex - fromIndex));
15144 var token = String.fromCharCode(0xE100 + i);
15145 format = format.replace(literal, token);
15146 }
15147 return format;
15148 }
15149 FormattingEncoder.preserveLiterals = preserveLiterals;
15150 function restoreLiterals(format, literals) {
15151 var count = literals.length;
15152 for (var i = 0; i < count; i++) {
15153 var token = String.fromCharCode(0xE100 + i);
15154 var literal = literals[i];
15155 format = format.replace(token, literal);
15156 }
15157 return format;
15158 }
15159 FormattingEncoder.restoreLiterals = restoreLiterals;
15160 })(FormattingEncoder || (FormattingEncoder = {}));
15161 var IndexedTokensRegex = /({{)|(}})|{(\d+[^}]*)}/g;
15162 var ZeroPlaceholder = '0';
15163 var DigitPlaceholder = '#';
15164 var ExponentialFormatChar = 'E';
15165 var NumericPlaceholders = [ZeroPlaceholder, DigitPlaceholder];
15166 var NumericPlaceholderRegex = new RegExp(NumericPlaceholders.join('|'), 'g');
15167 /** Formatting Service */
15168 var FormattingService = (function () {
15169 function FormattingService() {
15170 }
15171 FormattingService.prototype.formatValue = function (value, format, culture) {
15172 // Handle special cases
15173 if (value === undefined || value === null) {
15174 return '';
15175 }
15176 var gculture = this.getCulture(culture);
15177 if (DateTimeFormat.canFormat(value)) {
15178 // Dates
15179 return DateTimeFormat.format(value, format, gculture);
15180 }
15181 else if (NumberFormat.canFormat(value)) {
15182 // Numbers
15183 return NumberFormat.format(value, format, gculture);
15184 }
15185 else {
15186 // Other data types - return as string
15187 return value.toString();
15188 }
15189 };
15190 FormattingService.prototype.format = function (formatWithIndexedTokens, args, culture) {
15191 var _this = this;
15192 if (!formatWithIndexedTokens) {
15193 return "";
15194 }
15195 var result = formatWithIndexedTokens.replace(IndexedTokensRegex, function (match, left, right, argToken) {
15196 if (left) {
15197 return "{";
15198 }
15199 else if (right) {
15200 return "}";
15201 }
15202 else {
15203 var parts = argToken.split(":");
15204 var argIndex = parseInt(parts[0], 10);
15205 var argFormat = parts[1];
15206 return _this.formatValue(args[argIndex], argFormat, culture);
15207 }
15208 });
15209 return result;
15210 };
15211 FormattingService.prototype.isStandardNumberFormat = function (format) {
15212 return NumberFormat.isStandardFormat(format);
15213 };
15214 FormattingService.prototype.formatNumberWithCustomOverride = function (value, format, nonScientificOverrideFormat, culture) {
15215 var gculture = this.getCulture(culture);
15216 return NumberFormat.formatWithCustomOverride(value, format, nonScientificOverrideFormat, gculture);
15217 };
15218 FormattingService.prototype.dateFormatString = function (unit) {
15219 if (!this._dateTimeScaleFormatInfo)
15220 this.initialize();
15221 return this._dateTimeScaleFormatInfo.getFormatString(unit);
15222 };
15223 /**
15224 * Sets the current localization culture
15225 * @param cultureSelector - name of a culture: "en", "en-UK", "fr-FR" etc. (See National Language Support (NLS) for full lists. Use "default" for invariant culture).
15226 */
15227 FormattingService.prototype.setCurrentCulture = function (cultureSelector) {
15228 if (this._currentCultureSelector !== cultureSelector) {
15229 this._currentCulture = this.getCulture(cultureSelector);
15230 this._currentCultureSelector = cultureSelector;
15231 this._dateTimeScaleFormatInfo = new DateTimeScaleFormatInfo(this._currentCulture);
15232 }
15233 };
15234 /**
15235 * Gets the culture assotiated with the specified cultureSelector ("en", "en-US", "fr-FR" etc).
15236 * @param cultureSelector - name of a culture: "en", "en-UK", "fr-FR" etc. (See National Language Support (NLS) for full lists. Use "default" for invariant culture).
15237 * Exposing this function for testability of unsupported cultures
15238 */
15239 FormattingService.prototype.getCulture = function (cultureSelector) {
15240 if (cultureSelector == null) {
15241 if (this._currentCulture == null) {
15242 this.initialize();
15243 }
15244 return this._currentCulture;
15245 }
15246 else {
15247 var culture = Globalize.findClosestCulture(cultureSelector);
15248 if (!culture)
15249 culture = Globalize.culture("en-US");
15250 return culture;
15251 }
15252 };
15253 /** By default the Globalization module initializes to the culture/calendar provided in the language/culture URL params */
15254 FormattingService.prototype.initialize = function () {
15255 var cultureName = this.getCurrentCulture();
15256 this.setCurrentCulture(cultureName);
15257 var calendarName = this.getUrlParam("calendar");
15258 if (calendarName) {
15259 var culture = this._currentCulture;
15260 var c = culture.calendars[calendarName];
15261 if (c) {
15262 culture.calendar = c;
15263 }
15264 }
15265 };
15266 /**
15267 * Exposing this function for testability
15268 */
15269 FormattingService.prototype.getCurrentCulture = function () {
15270 var urlParam = this.getUrlParam("language");
15271 if (urlParam) {
15272 return urlParam;
15273 }
15274 if (powerbi && powerbi.common && powerbi.common.cultureInfo) {
15275 // Get cultureInfo set in powerbi
15276 return powerbi.common.cultureInfo;
15277 }
15278 return window.navigator.userLanguage || window.navigator["language"] || Globalize.culture().name;
15279 };
15280 /**
15281 * Exposing this function for testability
15282 * @param name: queryString name
15283 */
15284 FormattingService.prototype.getUrlParam = function (name) {
15285 var param = window.location.search.match(RegExp("[?&]" + name + "=([^&]*)"));
15286 return param ? param[1] : undefined;
15287 };
15288 return FormattingService;
15289 }());
15290 /**
15291 * DateTimeFormat module contains the static methods for formatting the DateTimes.
15292 * It extends the JQuery.Globalize functionality to support complete set of .NET
15293 * formatting expressions for dates.
15294 */
15295 var DateTimeFormat;
15296 (function (DateTimeFormat) {
15297 var _currentCachedFormat;
15298 var _currentCachedProcessedFormat;
15299 /** Evaluates if the value can be formatted using the NumberFormat */
15300 function canFormat(value) {
15301 var result = value instanceof Date;
15302 return result;
15303 }
15304 DateTimeFormat.canFormat = canFormat;
15305 /** Formats the date using provided format and culture */
15306 function format(value, format, culture) {
15307 format = format || "G";
15308 var isStandard = format.length === 1;
15309 try {
15310 if (isStandard) {
15311 return formatDateStandard(value, format, culture);
15312 }
15313 else {
15314 return formatDateCustom(value, format, culture);
15315 }
15316 }
15317 catch (e) {
15318 return formatDateStandard(value, "G", culture);
15319 }
15320 }
15321 DateTimeFormat.format = format;
15322 /** Formats the date using standard format expression */
15323 function formatDateStandard(value, format, culture) {
15324 // In order to provide parity with .NET we have to support additional set of DateTime patterns.
15325 var patterns = culture.calendar.patterns;
15326 // Extend supported set of patterns
15327 ensurePatterns(culture.calendar);
15328 // Handle extended set of formats
15329 var output = Formatting.findDateFormat(value, format, culture.name);
15330 if (output.format.length === 1)
15331 format = patterns[output.format];
15332 else
15333 format = output.format;
15334 //need to revisit when globalization is enabled
15335 culture = Globalize.culture("en-US");
15336 return Globalize.format(output.value, format, culture);
15337 }
15338 /** Formats the date using custom format expression */
15339 function formatDateCustom(value, format, culture) {
15340 var result;
15341 var literals = [];
15342 format = FormattingEncoder.preserveEscaped(format, "\\dfFghHKmstyz:/%'\"");
15343 format = FormattingEncoder.preserveLiterals(format, literals);
15344 format = StringExtensions.replaceAll(format, "\"", "'");
15345 if (format.indexOf("F") > -1) {
15346 // F is not supported so we need to replace the F with f based on the milliseconds
15347 // Replace all sequences of F longer than 3 with "FFF"
15348 format = StringExtensions.replaceAll(format, "FFFF", "FFF");
15349 // Based on milliseconds update the format to use fff
15350 var milliseconds = value.getMilliseconds();
15351 if (milliseconds % 10 >= 1) {
15352 format = StringExtensions.replaceAll(format, "FFF", "fff");
15353 }
15354 format = StringExtensions.replaceAll(format, "FFF", "FF");
15355 if ((milliseconds % 100) / 10 >= 1) {
15356 format = StringExtensions.replaceAll(format, "FF", "ff");
15357 }
15358 format = StringExtensions.replaceAll(format, "FF", "F");
15359 if ((milliseconds % 1000) / 100 >= 1) {
15360 format = StringExtensions.replaceAll(format, "F", "f");
15361 }
15362 format = StringExtensions.replaceAll(format, "F", "");
15363 if (format === "" || format === "%")
15364 return "";
15365 }
15366 format = processCustomDateTimeFormat(format);
15367 result = Globalize.format(value, format, culture);
15368 result = localize(result, culture.calendar);
15369 result = FormattingEncoder.restoreLiterals(result, literals);
15370 result = FormattingEncoder.restoreEscaped(result, "\\dfFghHKmstyz:/%'\"");
15371 return result;
15372 }
15373 /** Translates unsupported .NET custom format expressions to the custom expressions supported by JQuery.Globalize */
15374 function processCustomDateTimeFormat(format) {
15375 if (format === _currentCachedFormat) {
15376 return _currentCachedProcessedFormat;
15377 }
15378 _currentCachedFormat = format;
15379 format = Formatting.fixDateTimeFormat(format);
15380 _currentCachedProcessedFormat = format;
15381 return format;
15382 }
15383 /** Localizes the time separator symbol */
15384 function localize(value, dictionary) {
15385 var timeSeparator = dictionary[":"];
15386 if (timeSeparator === ":") {
15387 return value;
15388 }
15389 var result = "";
15390 var count = value.length;
15391 for (var i = 0; i < count; i++) {
15392 var char = value.charAt(i);
15393 switch (char) {
15394 case ":":
15395 result += timeSeparator;
15396 break;
15397 default:
15398 result += char;
15399 break;
15400 }
15401 }
15402 return result;
15403 }
15404 function ensurePatterns(calendar) {
15405 var patterns = calendar.patterns;
15406 if (patterns["g"] === undefined) {
15407 patterns["g"] = patterns["f"].replace(patterns["D"], patterns["d"]); // Generic: Short date, short time
15408 patterns["G"] = patterns["F"].replace(patterns["D"], patterns["d"]); // Generic: Short date, long time
15409 }
15410 }
15411 })(DateTimeFormat || (DateTimeFormat = {}));
15412 /**
15413 * NumberFormat module contains the static methods for formatting the numbers.
15414 * It extends the JQuery.Globalize functionality to support complete set of .NET
15415 * formatting expressions for numeric types including custom formats.
15416 */
15417 var NumberFormat;
15418 (function (NumberFormat) {
15419 var NonScientificFormatRegex = /^\{.+\}.*/;
15420 var NumericalPlaceHolderRegex = /\{.+\}/;
15421 var ScientificFormatRegex = /e[+-]*[0#]+/i;
15422 var StandardFormatRegex = /^[a-z]\d{0,2}$/i; // a letter + up to 2 digits for precision specifier
15423 var TrailingZerosRegex = /0+$/;
15424 var DecimalFormatRegex = /\.([0#]*)/g;
15425 var NumericFormatRegex = /[0#,\.]+[0,#]*/g;
15426 var LastNumericPlaceholderRegex = /(0|#)([^(0|#)]*)$/;
15427 var DecimalFormatCharacter = '.';
15428 NumberFormat.NumberFormatComponentsDelimeter = ';';
15429 function getNonScientificFormatWithPrecision(baseFormat, numericFormat) {
15430 if (!numericFormat || baseFormat === undefined)
15431 return baseFormat;
15432 var newFormat = "{0:" + numericFormat + "}";
15433 return baseFormat.replace("{0}", newFormat);
15434 }
15435 function getNumericFormat(value, baseFormat) {
15436 if (baseFormat == null)
15437 return baseFormat;
15438 if (hasFormatComponents(baseFormat)) {
15439 var _a = NumberFormat.getComponents(baseFormat), positive = _a.positive, negative = _a.negative, zero = _a.zero;
15440 if (value > 0)
15441 return getNumericFormatFromComponent(value, positive);
15442 else if (value === 0)
15443 return getNumericFormatFromComponent(value, zero);
15444 return getNumericFormatFromComponent(value, negative);
15445 }
15446 return getNumericFormatFromComponent(value, baseFormat);
15447 }
15448 NumberFormat.getNumericFormat = getNumericFormat;
15449 function getNumericFormatFromComponent(value, format) {
15450 var match = RegExpExtensions.run(NumericFormatRegex, format);
15451 if (match)
15452 return match[0];
15453 return format;
15454 }
15455 function addDecimalsToFormat(baseFormat, decimals, trailingZeros) {
15456 if (decimals == null)
15457 return baseFormat;
15458 // Default format string
15459 if (baseFormat == null)
15460 baseFormat = ZeroPlaceholder;
15461 if (hasFormatComponents(baseFormat)) {
15462 var _a = NumberFormat.getComponents(baseFormat), positive = _a.positive, negative = _a.negative, zero = _a.zero;
15463 var formats = [positive, negative, zero];
15464 for (var i = 0; i < formats.length; i++) {
15465 // Update format in formats array
15466 formats[i] = addDecimalsToFormatComponent(formats[i], decimals, trailingZeros);
15467 }
15468 return formats.join(NumberFormat.NumberFormatComponentsDelimeter);
15469 }
15470 return addDecimalsToFormatComponent(baseFormat, decimals, trailingZeros);
15471 }
15472 NumberFormat.addDecimalsToFormat = addDecimalsToFormat;
15473 function addDecimalsToFormatComponent(format, decimals, trailingZeros) {
15474 decimals = Math.abs(decimals);
15475 if (decimals >= 0) {
15476 var placeholder = trailingZeros ? ZeroPlaceholder : DigitPlaceholder;
15477 var decimalPlaceholders = StringExtensions.repeat(placeholder, Math.abs(decimals));
15478 var match = RegExpExtensions.run(DecimalFormatRegex, format);
15479 if (match) {
15480 var beforeDecimal = format.substr(0, match.index);
15481 var formatDecimal = format.substr(match.index + 1, match[1].length);
15482 var afterDecimal = format.substr(match.index + match[0].length);
15483 if (trailingZeros)
15484 // Use explicit decimals argument as placeholders
15485 formatDecimal = decimalPlaceholders;
15486 else {
15487 var decimalChange = decimalPlaceholders.length - formatDecimal.length;
15488 if (decimalChange > 0)
15489 // Append decimalPlaceholders to existing decimal portion of format string
15490 formatDecimal = formatDecimal + decimalPlaceholders.slice(-decimalChange);
15491 else if (decimalChange < 0)
15492 // Remove decimals from formatDecimal
15493 formatDecimal = formatDecimal.slice(0, decimalChange);
15494 }
15495 if (formatDecimal.length > 0)
15496 formatDecimal = DecimalFormatCharacter + formatDecimal;
15497 return beforeDecimal + formatDecimal + afterDecimal;
15498 }
15499 else if (decimalPlaceholders.length > 0)
15500 // Replace last numeric placeholder with decimal portion
15501 return format.replace(LastNumericPlaceholderRegex, '$1' + DecimalFormatCharacter + decimalPlaceholders);
15502 }
15503 return format;
15504 }
15505 function hasFormatComponents(format) {
15506 return format.indexOf(NumberFormat.NumberFormatComponentsDelimeter) !== -1;
15507 }
15508 NumberFormat.hasFormatComponents = hasFormatComponents;
15509 function getComponents(format) {
15510 var signFormat = {
15511 hasNegative: false,
15512 positive: format,
15513 negative: format,
15514 zero: format,
15515 };
15516 var signSpecificFormats = format.split(NumberFormat.NumberFormatComponentsDelimeter);
15517 var formatCount = signSpecificFormats.length;
15518 debug.assert(!(formatCount > 3), 'format string should be of form positive[;negative;zero]');
15519 if (formatCount > 1) {
15520 signFormat.hasNegative = true;
15521 signFormat.positive = signFormat.zero = signSpecificFormats[0];
15522 signFormat.negative = signSpecificFormats[1];
15523 if (formatCount > 2)
15524 signFormat.zero = signSpecificFormats[2];
15525 }
15526 return signFormat;
15527 }
15528 NumberFormat.getComponents = getComponents;
15529 var _lastCustomFormatMeta;
15530 /** Evaluates if the value can be formatted using the NumberFormat */
15531 function canFormat(value) {
15532 var result = typeof (value) === "number";
15533 return result;
15534 }
15535 NumberFormat.canFormat = canFormat;
15536 function isStandardFormat(format) {
15537 debug.assertValue(format, 'format');
15538 return StandardFormatRegex.test(format);
15539 }
15540 NumberFormat.isStandardFormat = isStandardFormat;
15541 /** Formats the number using specified format expression and culture */
15542 function format(value, format, culture) {
15543 format = format || "G";
15544 try {
15545 if (isStandardFormat(format))
15546 return formatNumberStandard(value, format, culture);
15547 return formatNumberCustom(value, format, culture);
15548 }
15549 catch (e) {
15550 return Globalize.format(value, undefined, culture);
15551 }
15552 }
15553 NumberFormat.format = format;
15554 /** Performs a custom format with a value override. Typically used for custom formats showing scaled values. */
15555 function formatWithCustomOverride(value, format, nonScientificOverrideFormat, culture) {
15556 debug.assertValue(value, 'value');
15557 debug.assertValue(format, 'format');
15558 debug.assertValue(nonScientificOverrideFormat, 'nonScientificOverrideFormat');
15559 debug.assertValue(culture, 'culture');
15560 debug.assert(!isStandardFormat(format), 'Standard format');
15561 return formatNumberCustom(value, format, culture, nonScientificOverrideFormat);
15562 }
15563 NumberFormat.formatWithCustomOverride = formatWithCustomOverride;
15564 /** Formats the number using standard format expression */
15565 function formatNumberStandard(value, format, culture) {
15566 var result;
15567 var precision = (format.length > 1 ? parseInt(format.substr(1, format.length - 1), 10) : undefined);
15568 var numberFormatInfo = culture.numberFormat;
15569 var formatChar = format.charAt(0);
15570 switch (formatChar) {
15571 case "e":
15572 case "E":
15573 if (precision === undefined) {
15574 precision = 6;
15575 }
15576 var mantissaDecimalDigits = StringExtensions.repeat("0", precision);
15577 format = "0." + mantissaDecimalDigits + formatChar + "+000";
15578 result = formatNumberCustom(value, format, culture);
15579 break;
15580 case "f":
15581 case "F":
15582 result = precision !== undefined ? value.toFixed(precision) : value.toFixed(numberFormatInfo.decimals);
15583 result = localize(result, numberFormatInfo);
15584 break;
15585 case "g":
15586 case "G":
15587 var abs = Math.abs(value);
15588 if (abs === 0 || (1E-4 <= abs && abs < 1E15)) {
15589 // For the range of 0.0001 to 1,000,000,000,000,000 - use the normal form
15590 result = precision !== undefined ? value.toPrecision(precision) : value.toString();
15591 }
15592 else {
15593 // Otherwise use exponential
15594 // Assert that value is a number and fall back on returning value if it is not
15595 debug.assert(typeof (value) === "number", "value must be a number");
15596 if (typeof (value) !== "number")
15597 return String(value);
15598 result = precision !== undefined ? value.toExponential(precision) : value.toExponential();
15599 result = result.replace("e", "E");
15600 }
15601 result = localize(result, numberFormatInfo);
15602 break;
15603 case "r":
15604 case "R":
15605 result = value.toString();
15606 result = localize(result, numberFormatInfo);
15607 break;
15608 case "x":
15609 case "X":
15610 result = value.toString(16);
15611 if (formatChar === "X") {
15612 result = result.toUpperCase();
15613 }
15614 if (precision !== undefined) {
15615 var actualPrecision = result.length;
15616 var isNegative = value < 0;
15617 if (isNegative) {
15618 actualPrecision--;
15619 }
15620 var paddingZerosCount = precision - actualPrecision;
15621 var paddingZeros = undefined;
15622 if (paddingZerosCount > 0) {
15623 paddingZeros = StringExtensions.repeat("0", paddingZerosCount);
15624 }
15625 if (isNegative) {
15626 result = "-" + paddingZeros + result.substr(1);
15627 }
15628 else {
15629 result = paddingZeros + result;
15630 }
15631 }
15632 result = localize(result, numberFormatInfo);
15633 break;
15634 default:
15635 result = Globalize.format(value, format, culture);
15636 }
15637 return result;
15638 }
15639 /** Formats the number using custom format expression */
15640 function formatNumberCustom(value, format, culture, nonScientificOverrideFormat) {
15641 var result;
15642 var numberFormatInfo = culture.numberFormat;
15643 if (isFinite(value)) {
15644 // Split format by positive[;negative;zero] pattern
15645 var formatComponents = getComponents(format);
15646 // Pick a format based on the sign of value
15647 if (value > 0) {
15648 format = formatComponents.positive;
15649 }
15650 else if (value === 0) {
15651 format = formatComponents.zero;
15652 }
15653 else {
15654 format = formatComponents.negative;
15655 }
15656 // Normalize value if we have an explicit negative format
15657 if (formatComponents.hasNegative)
15658 value = Math.abs(value);
15659 // Get format metadata
15660 var formatMeta = getCustomFormatMetadata(format, true /*calculatePrecision*/);
15661 // Preserve literals and escaped chars
15662 if (formatMeta.hasEscapes) {
15663 format = FormattingEncoder.preserveEscaped(format, "\\0#.,%‰");
15664 }
15665 var literals = [];
15666 if (formatMeta.hasQuotes) {
15667 format = FormattingEncoder.preserveLiterals(format, literals);
15668 }
15669 // Scientific format
15670 if (formatMeta.hasE && !nonScientificOverrideFormat) {
15671 var scientificMatch = RegExpExtensions.run(ScientificFormatRegex, format);
15672 if (scientificMatch) {
15673 // Case 2.1. Scientific custom format
15674 var formatM = format.substr(0, scientificMatch.index);
15675 var formatE = format.substr(scientificMatch.index + 2); // E(+|-)
15676 var precision = getCustomFormatPrecision(formatM, formatMeta);
15677 var scale = getCustomFormatScale(formatM, formatMeta);
15678 if (scale !== 1) {
15679 value = value * scale;
15680 }
15681 // Assert that value is a number and fall back on returning value if it is not
15682 debug.assert(typeof (value) === "number", "value must be a number");
15683 if (typeof (value) !== "number")
15684 return String(value);
15685 var s = value.toExponential(precision);
15686 var indexOfE = s.indexOf("e");
15687 var mantissa = s.substr(0, indexOfE);
15688 var exp = s.substr(indexOfE + 1);
15689 var resultM = fuseNumberWithCustomFormat(mantissa, formatM, numberFormatInfo);
15690 var resultE = fuseNumberWithCustomFormat(exp, formatE, numberFormatInfo);
15691 if (resultE.charAt(0) === "+" && scientificMatch[0].charAt(1) !== "+") {
15692 resultE = resultE.substr(1);
15693 }
15694 var e = scientificMatch[0].charAt(0);
15695 result = resultM + e + resultE;
15696 }
15697 }
15698 // Non scientific format
15699 if (result === undefined) {
15700 var valueFormatted = void 0;
15701 var isValueGlobalized = false;
15702 var precision = getCustomFormatPrecision(format, formatMeta);
15703 var scale = getCustomFormatScale(format, formatMeta);
15704 if (scale !== 1)
15705 value = value * scale;
15706 // Rounding
15707 value = parseFloat(toNonScientific(value, precision));
15708 if (nonScientificOverrideFormat) {
15709 // Get numeric format from format string
15710 var numericFormat = NumberFormat.getNumericFormat(value, format);
15711 // Add separators and decimalFormat to nonScientificFormat
15712 nonScientificOverrideFormat = getNonScientificFormatWithPrecision(nonScientificOverrideFormat, numericFormat);
15713 // Format the value
15714 valueFormatted = powerbi_1.formattingService.format(nonScientificOverrideFormat, [value], culture.name);
15715 isValueGlobalized = true;
15716 }
15717 else
15718 valueFormatted = toNonScientific(value, precision);
15719 result = fuseNumberWithCustomFormat(valueFormatted, format, numberFormatInfo, nonScientificOverrideFormat, isValueGlobalized);
15720 }
15721 if (formatMeta.hasQuotes) {
15722 result = FormattingEncoder.restoreLiterals(result, literals);
15723 }
15724 if (formatMeta.hasEscapes) {
15725 result = FormattingEncoder.restoreEscaped(result, "\\0#.,%‰");
15726 }
15727 _lastCustomFormatMeta = formatMeta;
15728 }
15729 else {
15730 return Globalize.format(value, undefined);
15731 }
15732 return result;
15733 }
15734 /** Returns string with the fixed point respresentation of the number */
15735 function toNonScientific(value, precision) {
15736 var result = "";
15737 var precisionZeros = 0;
15738 // Double precision numbers support actual 15-16 decimal digits of precision.
15739 if (precision > 16) {
15740 precisionZeros = precision - 16;
15741 precision = 16;
15742 }
15743 var digitsBeforeDecimalPoint = powerbi_1.Double.log10(Math.abs(value));
15744 if (digitsBeforeDecimalPoint < 16) {
15745 if (digitsBeforeDecimalPoint > 0) {
15746 var maxPrecision = 16 - digitsBeforeDecimalPoint;
15747 if (precision > maxPrecision) {
15748 precisionZeros += precision - maxPrecision;
15749 precision = maxPrecision;
15750 }
15751 }
15752 result = value.toFixed(precision);
15753 }
15754 else if (digitsBeforeDecimalPoint === 16) {
15755 result = value.toFixed(0);
15756 precisionZeros += precision;
15757 if (precisionZeros > 0) {
15758 result += ".";
15759 }
15760 }
15761 else {
15762 // Different browsers have different implementations of the toFixed().
15763 // In IE it returns fixed format no matter what's the number. In FF and Chrome the method returns exponential format for numbers greater than 1E21.
15764 // So we need to check for range and convert the to exponential with the max precision.
15765 // Then we convert exponential string to fixed by removing the dot and padding with "power" zeros.
15766 // Assert that value is a number and fall back on returning value if it is not
15767 debug.assert(typeof (value) === "number", "value must be a number");
15768 if (typeof (value) !== "number")
15769 return String(value);
15770 result = value.toExponential(15);
15771 var indexOfE = result.indexOf("e");
15772 if (indexOfE > 0) {
15773 var indexOfDot = result.indexOf(".");
15774 var mantissa = result.substr(0, indexOfE);
15775 var exp = result.substr(indexOfE + 1);
15776 var powerZeros = parseInt(exp, 10) - (mantissa.length - indexOfDot - 1);
15777 result = mantissa.replace(".", "") + StringExtensions.repeat("0", powerZeros);
15778 if (precision > 0) {
15779 result = result + "." + StringExtensions.repeat("0", precision);
15780 }
15781 }
15782 }
15783 if (precisionZeros > 0) {
15784 result = result + StringExtensions.repeat("0", precisionZeros);
15785 }
15786 return result;
15787 }
15788 /**
15789 * Returns the formatMetadata of the format
15790 * When calculating precision and scale, if format string of
15791 * positive[;negative;zero] => positive format will be used
15792 * @param (required) format - format string
15793 * @param (optional) calculatePrecision - calculate precision of positive format
15794 * @param (optional) calculateScale - calculate scale of positive format
15795 */
15796 function getCustomFormatMetadata(format, calculatePrecision, calculateScale) {
15797 if (_lastCustomFormatMeta !== undefined && format === _lastCustomFormatMeta.format) {
15798 return _lastCustomFormatMeta;
15799 }
15800 var result = {
15801 format: format,
15802 hasEscapes: false,
15803 hasQuotes: false,
15804 hasE: false,
15805 hasCommas: false,
15806 hasDots: false,
15807 hasPercent: false,
15808 hasPermile: false,
15809 precision: undefined,
15810 scale: undefined,
15811 };
15812 for (var i = 0, length_1 = format.length; i < length_1; i++) {
15813 var c = format.charAt(i);
15814 switch (c) {
15815 case "\\":
15816 result.hasEscapes = true;
15817 break;
15818 case "'":
15819 case "\"":
15820 result.hasQuotes = true;
15821 break;
15822 case "e":
15823 case "E":
15824 result.hasE = true;
15825 break;
15826 case ",":
15827 result.hasCommas = true;
15828 break;
15829 case ".":
15830 result.hasDots = true;
15831 break;
15832 case "%":
15833 result.hasPercent = true;
15834 break;
15835 case "‰":
15836 result.hasPermile = true;
15837 break;
15838 }
15839 }
15840 // Use positive format for calculating these values
15841 var formatComponents = getComponents(format);
15842 if (calculatePrecision)
15843 result.precision = getCustomFormatPrecision(formatComponents.positive, result);
15844 if (calculateScale)
15845 result.scale = getCustomFormatScale(formatComponents.positive, result);
15846 return result;
15847 }
15848 NumberFormat.getCustomFormatMetadata = getCustomFormatMetadata;
15849 /** Returns the decimal precision of format based on the number of # and 0 chars after the decimal point
15850 * Important: The input format string needs to be split to the appropriate pos/neg/zero portion to work correctly */
15851 function getCustomFormatPrecision(format, formatMeta) {
15852 if (formatMeta.precision > -1) {
15853 return formatMeta.precision;
15854 }
15855 var result = 0;
15856 if (formatMeta.hasDots) {
15857 var dotIndex = format.indexOf(".");
15858 if (dotIndex > -1) {
15859 var count = format.length;
15860 for (var i = dotIndex; i < count; i++) {
15861 var char = format.charAt(i);
15862 if (char.match(NumericPlaceholderRegex))
15863 result++;
15864 // 0.00E+0 :: Break before counting 0 in
15865 // exponential portion of format string
15866 if (char === ExponentialFormatChar)
15867 break;
15868 }
15869 result = Math.min(19, result);
15870 }
15871 }
15872 formatMeta.precision = result;
15873 return result;
15874 }
15875 /** Returns the scale factor of the format based on the "%" and scaling "," chars in the format */
15876 function getCustomFormatScale(format, formatMeta) {
15877 if (formatMeta.scale > -1) {
15878 return formatMeta.scale;
15879 }
15880 var result = 1;
15881 if (formatMeta.hasPercent && format.indexOf("%") > -1) {
15882 result = result * 100;
15883 }
15884 if (formatMeta.hasPermile && format.indexOf("‰") > -1) {
15885 result = result * 1000;
15886 }
15887 if (formatMeta.hasCommas) {
15888 var dotIndex = format.indexOf(".");
15889 if (dotIndex === -1) {
15890 dotIndex = format.length;
15891 }
15892 for (var i = dotIndex - 1; i > -1; i--) {
15893 var char = format.charAt(i);
15894 if (char === ",") {
15895 result = result / 1000;
15896 }
15897 else {
15898 break;
15899 }
15900 }
15901 }
15902 formatMeta.scale = result;
15903 return result;
15904 }
15905 function fuseNumberWithCustomFormat(value, format, numberFormatInfo, nonScientificOverrideFormat, isValueGlobalized) {
15906 var suppressModifyValue = !!nonScientificOverrideFormat;
15907 var formatParts = format.split(".", 2);
15908 if (formatParts.length === 2) {
15909 var wholeFormat = formatParts[0];
15910 var fractionFormat = formatParts[1];
15911 var displayUnit = "";
15912 // Remove display unit from value before splitting on "." as localized display units sometimes end with "."
15913 if (nonScientificOverrideFormat) {
15914 debug.assert(NonScientificFormatRegex.test(nonScientificOverrideFormat), "Number should always precede the display unit");
15915 displayUnit = nonScientificOverrideFormat.replace(NumericalPlaceHolderRegex, "");
15916 value = value.replace(displayUnit, "");
15917 }
15918 var globalizedDecimalSeparator = numberFormatInfo["."];
15919 var decimalSeparator = isValueGlobalized ? globalizedDecimalSeparator : ".";
15920 var valueParts = value.split(decimalSeparator, 2);
15921 var wholeValue = valueParts.length === 1 ? valueParts[0] + displayUnit : valueParts[0];
15922 var fractionValue = valueParts.length === 2 ? valueParts[1] + displayUnit : "";
15923 fractionValue = fractionValue.replace(TrailingZerosRegex, "");
15924 var wholeFormattedValue = fuseNumberWithCustomFormatLeft(wholeValue, wholeFormat, numberFormatInfo, suppressModifyValue);
15925 var fractionFormattedValue = fuseNumberWithCustomFormatRight(fractionValue, fractionFormat, suppressModifyValue);
15926 if (fractionFormattedValue.fmtOnly || fractionFormattedValue.value === "")
15927 return wholeFormattedValue + fractionFormattedValue.value;
15928 return wholeFormattedValue + globalizedDecimalSeparator + fractionFormattedValue.value;
15929 }
15930 return fuseNumberWithCustomFormatLeft(value, format, numberFormatInfo, suppressModifyValue);
15931 }
15932 function fuseNumberWithCustomFormatLeft(value, format, numberFormatInfo, suppressModifyValue) {
15933 var groupSymbolIndex = format.indexOf(",");
15934 var enableGroups = groupSymbolIndex > -1 && groupSymbolIndex < Math.max(format.lastIndexOf("0"), format.lastIndexOf("#")) && numberFormatInfo[","];
15935 var groupDigitCount = 0;
15936 var groupIndex = 0;
15937 var groupSizes = numberFormatInfo.groupSizes || [3];
15938 var groupSize = groupSizes[0];
15939 var groupSeparator = numberFormatInfo[","];
15940 var sign = "";
15941 var firstChar = value.charAt(0);
15942 if (firstChar === "+" || firstChar === "-") {
15943 sign = numberFormatInfo[firstChar];
15944 value = value.substr(1);
15945 }
15946 var isZero = value === "0";
15947 var result = "";
15948 var leftBuffer = "";
15949 var vi = value.length - 1;
15950 var fmtOnly = true;
15951 // Iterate through format chars and replace 0 and # with the digits from the value string
15952 for (var fi = format.length - 1; fi > -1; fi--) {
15953 var formatChar = format.charAt(fi);
15954 switch (formatChar) {
15955 case ZeroPlaceholder:
15956 case DigitPlaceholder:
15957 fmtOnly = false;
15958 if (leftBuffer !== "") {
15959 result = leftBuffer + result;
15960 leftBuffer = "";
15961 }
15962 if (!suppressModifyValue) {
15963 if (vi > -1 || formatChar === ZeroPlaceholder) {
15964 if (enableGroups) {
15965 // If the groups are enabled we'll need to keep track of the current group index and periodically insert group separator,
15966 if (groupDigitCount === groupSize) {
15967 result = groupSeparator + result;
15968 groupIndex++;
15969 if (groupIndex < groupSizes.length) {
15970 groupSize = groupSizes[groupIndex];
15971 }
15972 groupDigitCount = 1;
15973 }
15974 else {
15975 groupDigitCount++;
15976 }
15977 }
15978 }
15979 if (vi > -1) {
15980 if (isZero && formatChar === DigitPlaceholder) {
15981 }
15982 else {
15983 result = value.charAt(vi) + result;
15984 }
15985 vi--;
15986 }
15987 else if (formatChar !== DigitPlaceholder) {
15988 result = formatChar + result;
15989 }
15990 }
15991 break;
15992 case ",":
15993 // We should skip all the , chars
15994 break;
15995 default:
15996 leftBuffer = formatChar + leftBuffer;
15997 break;
15998 }
15999 }
16000 // If the value didn't fit into the number of zeros provided in the format then we should insert the missing part of the value into the result
16001 if (!suppressModifyValue) {
16002 if (vi > -1 && result !== "") {
16003 if (enableGroups) {
16004 while (vi > -1) {
16005 if (groupDigitCount === groupSize) {
16006 result = groupSeparator + result;
16007 groupIndex++;
16008 if (groupIndex < groupSizes.length) {
16009 groupSize = groupSizes[groupIndex];
16010 }
16011 groupDigitCount = 1;
16012 }
16013 else {
16014 groupDigitCount++;
16015 }
16016 result = value.charAt(vi) + result;
16017 vi--;
16018 }
16019 }
16020 else {
16021 result = value.substr(0, vi + 1) + result;
16022 }
16023 }
16024 // Insert sign in front of the leftBuffer and result
16025 return sign + leftBuffer + result;
16026 }
16027 if (fmtOnly)
16028 // If the format doesn't specify any digits to be displayed, then just return the format we've parsed up until now.
16029 return sign + leftBuffer + result;
16030 return sign + leftBuffer + value + result;
16031 }
16032 function fuseNumberWithCustomFormatRight(value, format, suppressModifyValue) {
16033 var vi = 0;
16034 var fCount = format.length;
16035 var vCount = value.length;
16036 if (suppressModifyValue) {
16037 debug.assert(fCount > 0, "Empty formatting string");
16038 var lastChar = format.charAt(fCount - 1);
16039 if (!lastChar.match(NumericPlaceholderRegex))
16040 return {
16041 value: value + lastChar,
16042 fmtOnly: value === "",
16043 };
16044 return {
16045 value: value,
16046 fmtOnly: value === "",
16047 };
16048 }
16049 var result = "", fmtOnly = true;
16050 for (var fi = 0; fi < fCount; fi++) {
16051 var formatChar = format.charAt(fi);
16052 if (vi < vCount) {
16053 switch (formatChar) {
16054 case ZeroPlaceholder:
16055 case DigitPlaceholder:
16056 result += value[vi++];
16057 fmtOnly = false;
16058 break;
16059 default:
16060 result += formatChar;
16061 }
16062 }
16063 else {
16064 if (formatChar !== DigitPlaceholder) {
16065 result += formatChar;
16066 fmtOnly = fmtOnly && (formatChar !== ZeroPlaceholder);
16067 }
16068 }
16069 }
16070 return {
16071 value: result,
16072 fmtOnly: fmtOnly,
16073 };
16074 }
16075 function localize(value, dictionary) {
16076 var plus = dictionary["+"];
16077 var minus = dictionary["-"];
16078 var dot = dictionary["."];
16079 var comma = dictionary[","];
16080 if (plus === "+" && minus === "-" && dot === "." && comma === ",") {
16081 return value;
16082 }
16083 var count = value.length;
16084 var result = "";
16085 for (var i = 0; i < count; i++) {
16086 var char = value.charAt(i);
16087 switch (char) {
16088 case "+":
16089 result = result + plus;
16090 break;
16091 case "-":
16092 result = result + minus;
16093 break;
16094 case ".":
16095 result = result + dot;
16096 break;
16097 case ",":
16098 result = result + comma;
16099 break;
16100 default:
16101 result = result + char;
16102 break;
16103 }
16104 }
16105 return result;
16106 }
16107 })(NumberFormat = powerbi_1.NumberFormat || (powerbi_1.NumberFormat = {}));
16108 /** DateTimeScaleFormatInfo is used to calculate and keep the Date formats used for different units supported by the DateTimeScaleModel */
16109 var DateTimeScaleFormatInfo = (function () {
16110 // Constructor
16111 /**
16112 * Creates new instance of the DateTimeScaleFormatInfo class.
16113 * @param culture - culture which calendar info is going to be used to derive the formats.
16114 */
16115 function DateTimeScaleFormatInfo(culture) {
16116 var calendar = culture.calendar;
16117 var patterns = calendar.patterns;
16118 var monthAbbreviations = calendar["months"]["namesAbbr"];
16119 var cultureHasMonthAbbr = monthAbbreviations && monthAbbreviations[0];
16120 var yearMonthPattern = patterns["Y"];
16121 var monthDayPattern = patterns["M"];
16122 var fullPattern = patterns["f"];
16123 var longTimePattern = patterns["T"];
16124 var shortTimePattern = patterns["t"];
16125 var separator = fullPattern.indexOf(",") > -1 ? ", " : " ";
16126 var hasYearSymbol = yearMonthPattern.indexOf("yyyy'") === 0 && yearMonthPattern.length > 6 && yearMonthPattern[6] === '\'';
16127 this.YearPattern = hasYearSymbol ? yearMonthPattern.substr(0, 7) : "yyyy";
16128 var yearPos = fullPattern.indexOf("yy");
16129 var monthPos = fullPattern.indexOf("MMMM");
16130 this.MonthPattern = cultureHasMonthAbbr && monthPos > -1 ? (yearPos > monthPos ? "MMM yyyy" : "yyyy MMM") : yearMonthPattern;
16131 this.DayPattern = cultureHasMonthAbbr ? monthDayPattern.replace("MMMM", "MMM") : monthDayPattern;
16132 var minutePos = fullPattern.indexOf("mm");
16133 var pmPos = fullPattern.indexOf("tt");
16134 var shortHourPattern = pmPos > -1 ? shortTimePattern.replace(":mm ", "") : shortTimePattern;
16135 this.HourPattern = yearPos < minutePos ? this.DayPattern + separator + shortHourPattern : shortHourPattern + separator + this.DayPattern;
16136 this.MinutePattern = shortTimePattern;
16137 this.SecondPattern = longTimePattern;
16138 this.MillisecondPattern = longTimePattern.replace("ss", "ss.fff");
16139 // Special cases
16140 switch (culture.name) {
16141 case "fi-FI":
16142 this.DayPattern = this.DayPattern.replace("'ta'", ""); // Fix for finish 'ta' suffix for month names.
16143 this.HourPattern = this.HourPattern.replace("'ta'", "");
16144 break;
16145 }
16146 }
16147 // Methods
16148 /**
16149 * Returns the format string of the provided DateTimeUnit.
16150 * @param unit - date or time unit
16151 */
16152 DateTimeScaleFormatInfo.prototype.getFormatString = function (unit) {
16153 switch (unit) {
16154 case powerbi_1.DateTimeUnit.Year:
16155 return this.YearPattern;
16156 case powerbi_1.DateTimeUnit.Month:
16157 return this.MonthPattern;
16158 case powerbi_1.DateTimeUnit.Week:
16159 case powerbi_1.DateTimeUnit.Day:
16160 return this.DayPattern;
16161 case powerbi_1.DateTimeUnit.Hour:
16162 return this.HourPattern;
16163 case powerbi_1.DateTimeUnit.Minute:
16164 return this.MinutePattern;
16165 case powerbi_1.DateTimeUnit.Second:
16166 return this.SecondPattern;
16167 case powerbi_1.DateTimeUnit.Millisecond:
16168 return this.MillisecondPattern;
16169 }
16170 debug.assertFail('Unexpected unit: ' + unit);
16171 };
16172 return DateTimeScaleFormatInfo;
16173 }());
16174 powerbi_1.formattingService = new FormattingService();
16175})(powerbi || (powerbi = {}));
16176/*
16177 * Power BI Visualizations
16178 *
16179 * Copyright (c) Microsoft Corporation
16180 * All rights reserved.
16181 * MIT License
16182 *
16183 * Permission is hereby granted, free of charge, to any person obtaining a copy
16184 * of this software and associated documentation files (the ""Software""), to deal
16185 * in the Software without restriction, including without limitation the rights
16186 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16187 * copies of the Software, and to permit persons to whom the Software is
16188 * furnished to do so, subject to the following conditions:
16189 *
16190 * The above copyright notice and this permission notice shall be included in
16191 * all copies or substantial portions of the Software.
16192 *
16193 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16194 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16195 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16196 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16197 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16198 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16199 * THE SOFTWARE.
16200 */
16201var powerbi;
16202(function (powerbi) {
16203 var data;
16204 (function (data) {
16205 /** Serializes SQExpr in a form optimized in-memory comparison, but not intended for storage on disk. */
16206 var SQExprShortSerializer;
16207 (function (SQExprShortSerializer) {
16208 function serialize(expr) {
16209 return JSON.stringify(expr.accept(SQExprSerializer.instance));
16210 }
16211 SQExprShortSerializer.serialize = serialize;
16212 function serializeArray(exprs) {
16213 var str = '[';
16214 for (var i = 0, len = exprs.length; i < len; i++) {
16215 if (i > 0)
16216 str += ',';
16217 str += SQExprShortSerializer.serialize(exprs[i]);
16218 }
16219 return str + ']';
16220 }
16221 SQExprShortSerializer.serializeArray = serializeArray;
16222 /** Responsible for serializing an SQExpr into a comparable string. */
16223 var SQExprSerializer = (function (_super) {
16224 __extends(SQExprSerializer, _super);
16225 function SQExprSerializer() {
16226 _super.apply(this, arguments);
16227 }
16228 SQExprSerializer.prototype.visitColumnRef = function (expr) {
16229 return {
16230 col: {
16231 s: expr.source.accept(this),
16232 r: expr.ref,
16233 }
16234 };
16235 };
16236 SQExprSerializer.prototype.visitMeasureRef = function (expr) {
16237 return {
16238 measure: {
16239 s: expr.source.accept(this),
16240 r: expr.ref,
16241 }
16242 };
16243 };
16244 SQExprSerializer.prototype.visitAggr = function (expr) {
16245 return {
16246 agg: {
16247 a: expr.arg.accept(this),
16248 f: expr.func,
16249 }
16250 };
16251 };
16252 SQExprSerializer.prototype.visitEntity = function (expr) {
16253 debug.assertValue(expr, 'expr');
16254 debug.assertValue(expr.entity, 'expr.entity');
16255 return {
16256 e: expr.entity
16257 };
16258 };
16259 SQExprSerializer.prototype.visitHierarchyLevel = function (expr) {
16260 return {
16261 h: expr.arg.accept(this),
16262 l: expr.level,
16263 };
16264 };
16265 SQExprSerializer.prototype.visitHierarchy = function (expr) {
16266 return {
16267 e: expr.arg.accept(this),
16268 h: expr.hierarchy,
16269 };
16270 };
16271 SQExprSerializer.prototype.visitPropertyVariationSource = function (expr) {
16272 return {
16273 e: expr.arg.accept(this),
16274 n: expr.name,
16275 p: expr.property,
16276 };
16277 };
16278 SQExprSerializer.prototype.visitAnd = function (expr) {
16279 debug.assertValue(expr, 'expr');
16280 return {
16281 and: {
16282 l: expr.left.accept(this),
16283 r: expr.right.accept(this),
16284 }
16285 };
16286 };
16287 SQExprSerializer.prototype.visitCompare = function (expr) {
16288 debug.assertValue(expr, 'expr');
16289 return {
16290 comp: {
16291 k: expr.comparison,
16292 l: expr.left.accept(this),
16293 r: expr.right.accept(this),
16294 }
16295 };
16296 };
16297 SQExprSerializer.prototype.visitConstant = function (expr) {
16298 debug.assertValue(expr, 'expr');
16299 return {
16300 const: {
16301 t: expr.type.primitiveType,
16302 v: expr.value,
16303 }
16304 };
16305 };
16306 SQExprSerializer.prototype.visitArithmetic = function (expr) {
16307 debug.assertValue(expr, 'expr');
16308 return {
16309 arithmetic: {
16310 o: expr.operator,
16311 l: expr.left.accept(this),
16312 r: expr.right.accept(this)
16313 }
16314 };
16315 };
16316 SQExprSerializer.prototype.visitScopedEval = function (expr) {
16317 debug.assertValue(expr, 'expr');
16318 return {
16319 scopedEval: {
16320 e: expr.expression.accept(this),
16321 s: serializeArray(expr.scope)
16322 }
16323 };
16324 };
16325 SQExprSerializer.prototype.visitDefault = function (expr) {
16326 debug.assertFail('Unexpected expression type found in DataViewScopeIdentity.');
16327 return;
16328 };
16329 SQExprSerializer.instance = new SQExprSerializer();
16330 return SQExprSerializer;
16331 }(data.DefaultSQExprVisitor));
16332 })(SQExprShortSerializer = data.SQExprShortSerializer || (data.SQExprShortSerializer = {}));
16333 })(data = powerbi.data || (powerbi.data = {}));
16334})(powerbi || (powerbi = {}));
16335/*
16336 * Power BI Visualizations
16337 *
16338 * Copyright (c) Microsoft Corporation
16339 * All rights reserved.
16340 * MIT License
16341 *
16342 * Permission is hereby granted, free of charge, to any person obtaining a copy
16343 * of this software and associated documentation files (the ""Software""), to deal
16344 * in the Software without restriction, including without limitation the rights
16345 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16346 * copies of the Software, and to permit persons to whom the Software is
16347 * furnished to do so, subject to the following conditions:
16348 *
16349 * The above copyright notice and this permission notice shall be included in
16350 * all copies or substantial portions of the Software.
16351 *
16352 * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16353 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16354 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16355 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16356 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16357 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16358 * THE SOFTWARE.
16359 */
16360var powerbi;
16361(function (powerbi) {
16362 var visuals;
16363 (function (visuals) {
16364 var Selector = powerbi.data.Selector;
16365 /**
16366 * A combination of identifiers used to uniquely identify
16367 * data points and their bound geometry.
16368 */
16369 var SelectionId = (function () {
16370 function SelectionId(selector, highlight) {
16371 this.selector = selector;
16372 this.highlight = highlight;
16373 this.key = JSON.stringify({ selector: selector ? Selector.getKey(selector) : null, highlight: highlight });
16374 this.keyWithoutHighlight = JSON.stringify({ selector: selector ? Selector.getKey(selector) : null });
16375 }
16376 SelectionId.prototype.equals = function (other) {
16377 if (!this.selector || !other.selector) {
16378 return (!this.selector === !other.selector) && this.highlight === other.highlight;
16379 }
16380 return this.highlight === other.highlight && Selector.equals(this.selector, other.selector);
16381 };
16382 /**
16383 * Checks equality against other for all identifiers existing in this.
16384 */
16385 SelectionId.prototype.includes = function (other, ignoreHighlight) {
16386 if (ignoreHighlight === void 0) { ignoreHighlight = false; }
16387 var thisSelector = this.selector;
16388 var otherSelector = other.selector;
16389 if (!thisSelector || !otherSelector) {
16390 return false;
16391 }
16392 var thisData = thisSelector.data;
16393 var otherData = otherSelector.data;
16394 if (!thisData && (thisSelector.metadata && thisSelector.metadata !== otherSelector.metadata))
16395 return false;
16396 if (!ignoreHighlight && this.highlight !== other.highlight)
16397 return false;
16398 if (thisData) {
16399 if (!otherData)
16400 return false;
16401 if (thisData.length > 0) {
16402 for (var i = 0, ilen = thisData.length; i < ilen; i++) {
16403 var thisValue = thisData[i];
16404 if (!otherData.some(function (otherValue) { return powerbi.DataViewScopeIdentity.equals(thisValue, otherValue); }))
16405 return false;
16406 }
16407 }
16408 }
16409 return true;
16410 };
16411 SelectionId.prototype.getKey = function () {
16412 return this.key;
16413 };
16414 SelectionId.prototype.getKeyWithoutHighlight = function () {
16415 return this.keyWithoutHighlight;
16416 };
16417 SelectionId.prototype.hasIdentity = function () {
16418 return (this.selector && !!this.selector.data);
16419 };
16420 SelectionId.prototype.getSelector = function () {
16421 return this.selector;
16422 };
16423 SelectionId.prototype.getSelectorsByColumn = function () {
16424 return this.selectorsByColumn;
16425 };
16426 SelectionId.createNull = function (highlight) {
16427 if (highlight === void 0) { highlight = false; }
16428 return new SelectionId(null, highlight);
16429 };
16430 SelectionId.createWithId = function (id, highlight) {
16431 if (highlight === void 0) { highlight = false; }
16432 var selector = null;
16433 if (id) {
16434 selector = {
16435 data: [id]
16436 };
16437 }
16438 return new SelectionId(selector, highlight);
16439 };
16440 SelectionId.createWithMeasure = function (measureId, highlight) {
16441 if (highlight === void 0) { highlight = false; }
16442 debug.assertValue(measureId, 'measureId');
16443 var selector = {
16444 metadata: measureId
16445 };
16446 var selectionId = new SelectionId(selector, highlight);
16447 selectionId.selectorsByColumn = { metadata: measureId };
16448 return selectionId;
16449 };
16450 SelectionId.createWithIdAndMeasure = function (id, measureId, highlight) {
16451 if (highlight === void 0) { highlight = false; }
16452 var selector = {};
16453 if (id) {
16454 selector.data = [id];
16455 }
16456 if (measureId)
16457 selector.metadata = measureId;
16458 if (!id && !measureId)
16459 selector = null;
16460 var selectionId = new SelectionId(selector, highlight);
16461 return selectionId;
16462 };
16463 SelectionId.createWithIdAndMeasureAndCategory = function (id, measureId, queryName, highlight) {
16464 if (highlight === void 0) { highlight = false; }
16465 var selectionId = this.createWithIdAndMeasure(id, measureId, highlight);
16466 if (selectionId.selector) {
16467 selectionId.selectorsByColumn = {};
16468 if (id && queryName) {
16469 selectionId.selectorsByColumn.dataMap = {};
16470 selectionId.selectorsByColumn.dataMap[queryName] = id;
16471 }
16472 if (measureId)
16473 selectionId.selectorsByColumn.metadata = measureId;
16474 }
16475 return selectionId;
16476 };
16477 SelectionId.createWithIds = function (id1, id2, highlight) {
16478 if (highlight === void 0) { highlight = false; }
16479 var selector = null;
16480 var selectorData = SelectionId.idArray(id1, id2);
16481 if (selectorData)
16482 selector = { data: selectorData };
16483 return new SelectionId(selector, highlight);
16484 };
16485 SelectionId.createWithIdsAndMeasure = function (id1, id2, measureId, highlight) {
16486 if (highlight === void 0) { highlight = false; }
16487 var selector = {};
16488 var selectorData = SelectionId.idArray(id1, id2);
16489 if (selectorData)
16490 selector.data = selectorData;
16491 if (measureId)
16492 selector.metadata = measureId;
16493 if (!id1 && !id2 && !measureId)
16494 selector = null;
16495 return new SelectionId(selector, highlight);
16496 };
16497 SelectionId.createWithSelectorForColumnAndMeasure = function (dataMap, measureId, highlight) {
16498 if (highlight === void 0) { highlight = false; }
16499 var selectionId;
16500 var keys = Object.keys(dataMap);
16501 if (keys.length === 2) {
16502 selectionId = this.createWithIdsAndMeasure(dataMap[keys[0]], dataMap[keys[1]], measureId, highlight);
16503 }
16504 else if (keys.length === 1) {
16505 selectionId = this.createWithIdsAndMeasure(dataMap[keys[0]], null, measureId, highlight);
16506 }
16507 else {
16508 selectionId = this.createWithIdsAndMeasure(null, null, measureId, highlight);
16509 }
16510 var selectorsByColumn = {};
16511 if (!_.isEmpty(dataMap))
16512 selectorsByColumn.dataMap = dataMap;
16513 if (measureId)
16514 selectorsByColumn.metadata = measureId;
16515 if (!dataMap && !measureId)
16516 selectorsByColumn = null;
16517 selectionId.selectorsByColumn = selectorsByColumn;
16518 return selectionId;
16519 };
16520 SelectionId.createWithHighlight = function (original) {
16521 debug.assertValue(original, 'original');
16522 debug.assert(!original.highlight, '!original.highlight');
16523 var newId = new SelectionId(original.getSelector(), /*highlight*/ true);
16524 newId.selectorsByColumn = original.selectorsByColumn;
16525 return newId;
16526 };
16527 SelectionId.idArray = function (id1, id2) {
16528 if (id1 || id2) {
16529 var data_4 = [];
16530 if (id1)
16531 data_4.push(id1);
16532 if (id2 && id2 !== id1)
16533 data_4.push(id2);
16534 return data_4;
16535 }
16536 };
16537 return SelectionId;
16538 }());
16539 visuals.SelectionId = SelectionId;
16540 /**
16541 * This class is designed to simplify the creation of SelectionId objects
16542 * It allows chaining to build up an object before calling 'create' to build a SelectionId
16543 */
16544 var SelectionIdBuilder = (function () {
16545 function SelectionIdBuilder() {
16546 }
16547 SelectionIdBuilder.builder = function () {
16548 return new SelectionIdBuilder();
16549 };
16550 SelectionIdBuilder.prototype.withCategory = function (categoryColumn, index) {
16551 if (categoryColumn && categoryColumn.source && categoryColumn.source.queryName && categoryColumn.identity)
16552 this.ensureDataMap()[categoryColumn.source.queryName] = categoryColumn.identity[index];
16553 return this;
16554 };
16555 SelectionIdBuilder.prototype.withSeries = function (seriesColumn, valueColumn) {
16556 if (seriesColumn && seriesColumn.source && seriesColumn.source.queryName && valueColumn)
16557 this.ensureDataMap()[seriesColumn.source.queryName] = valueColumn.identity;
16558 return this;
16559 };
16560 SelectionIdBuilder.prototype.withMeasure = function (measureId) {
16561 this.measure = measureId;
16562 return this;
16563 };
16564 SelectionIdBuilder.prototype.createSelectionId = function () {
16565 return SelectionId.createWithSelectorForColumnAndMeasure(this.ensureDataMap(), this.measure);
16566 };
16567 SelectionIdBuilder.prototype.ensureDataMap = function () {
16568 if (!this.dataMap)
16569 this.dataMap = {};
16570 return this.dataMap;
16571 };
16572 return SelectionIdBuilder;
16573 }());
16574 visuals.SelectionIdBuilder = SelectionIdBuilder;
16575 })(visuals = powerbi.visuals || (powerbi.visuals = {}));
16576})(powerbi || (powerbi = {}));
16577
16578//# sourceMappingURL=VisualsData.js.map