b66a7696c223e1592f52a7472bcc29be22a6bf3b52189404c48768e2d55466ac20ad8d4e90579a533621670dabceca645eae8473c89efb0ff73efed5c5a0d4 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import { OptionDataValue, DimensionLoose, Dictionary } from './types.js';
  2. import { HashMap } from 'zrender/lib/core/util.js';
  3. import { RawValueParserType, RelationalOperator } from '../data/helper/dataValueHelper.js';
  4. /**
  5. * The structured expression considered:
  6. * (1) Literal simplicity
  7. * (2) Sementic displayed clearly
  8. *
  9. * Sementic supports:
  10. * (1) relational expression
  11. * (2) logical expression
  12. *
  13. * For example:
  14. * ```js
  15. * {
  16. * and: [{
  17. * or: [{
  18. * dimension: 'Year', gt: 2012, lt: 2019
  19. * }, {
  20. * dimension: 'Year', '>': 2002, '<=': 2009
  21. * }]
  22. * }, {
  23. * dimension: 'Product', eq: 'Tofu'
  24. * }]
  25. * }
  26. *
  27. * { dimension: 'Product', eq: 'Tofu' }
  28. *
  29. * {
  30. * or: [
  31. * { dimension: 'Product', value: 'Tofu' },
  32. * { dimension: 'Product', value: 'Biscuit' }
  33. * ]
  34. * }
  35. *
  36. * {
  37. * and: [true]
  38. * }
  39. * ```
  40. *
  41. * [PARSER]
  42. * In an relation expression object, we can specify some built-in parsers:
  43. * ```js
  44. * // Trim if string
  45. * {
  46. * parser: 'trim',
  47. * eq: 'Flowers'
  48. * }
  49. * // Parse as time and enable arithmetic relation comparison.
  50. * {
  51. * parser: 'time',
  52. * lt: '2012-12-12'
  53. * }
  54. * // Normalize number-like string and make '-' to Null.
  55. * {
  56. * parser: 'time',
  57. * lt: '2012-12-12'
  58. * }
  59. * // Normalize to number:
  60. * // + number-like string (like ' 123 ') can be converted to a number.
  61. * // + where null/undefined or other string will be converted to NaN.
  62. * {
  63. * parser: 'number',
  64. * eq: 2011
  65. * }
  66. * // RegExp, include the feature in SQL: `like '%xxx%'`.
  67. * {
  68. * reg: /^asdf$/
  69. * }
  70. * {
  71. * reg: '^asdf$' // Serializable reg exp, will be `new RegExp(...)`
  72. * }
  73. * ```
  74. *
  75. *
  76. * [EMPTY_RULE]
  77. * (1) If a relational expression set value as `null`/`undefined` like:
  78. * `{ dimension: 'Product', lt: undefined }`,
  79. * The result will be `false` rather than `true`.
  80. * Consider the case like "filter condition", return all result when null/undefined
  81. * is probably not expected and even dangours.
  82. * (2) If a relational expression has no operator like:
  83. * `{ dimension: 'Product' }`,
  84. * An error will be thrown. Because it is probably a mistake.
  85. * (3) If a logical expression has no children like
  86. * `{ and: undefined }` or `{ and: [] }`,
  87. * An error will be thrown. Because it is probably an mistake.
  88. * (4) If intending have a condition that always `true` or always `false`,
  89. * Use `true` or `flase`.
  90. * The entire condition can be `true`/`false`,
  91. * or also can be `{ and: [true] }`, `{ or: [false] }`
  92. */
  93. /**
  94. * Date string and ordinal string can be accepted.
  95. */
  96. interface RelationalExpressionOptionByOp extends Record<RelationalOperator, OptionDataValue> {
  97. reg?: RegExp | string;
  98. }
  99. declare const RELATIONAL_EXPRESSION_OP_ALIAS_MAP: {
  100. readonly value: "eq";
  101. readonly '<': "lt";
  102. readonly '<=': "lte";
  103. readonly '>': "gt";
  104. readonly '>=': "gte";
  105. readonly '=': "eq";
  106. readonly '!=': "ne";
  107. readonly '<>': "ne";
  108. };
  109. declare type RelationalExpressionOptionByOpAlias = Record<keyof typeof RELATIONAL_EXPRESSION_OP_ALIAS_MAP, OptionDataValue>;
  110. interface RelationalExpressionOption extends RelationalExpressionOptionByOp, RelationalExpressionOptionByOpAlias {
  111. dimension?: DimensionLoose;
  112. parser?: RawValueParserType;
  113. }
  114. interface LogicalExpressionOption {
  115. and?: LogicalExpressionSubOption[];
  116. or?: LogicalExpressionSubOption[];
  117. not?: LogicalExpressionSubOption;
  118. }
  119. declare type LogicalExpressionSubOption = LogicalExpressionOption | RelationalExpressionOption | TrueFalseExpressionOption;
  120. export declare type TrueExpressionOption = true;
  121. export declare type FalseExpressionOption = false;
  122. export declare type TrueFalseExpressionOption = TrueExpressionOption | FalseExpressionOption;
  123. export declare type ConditionalExpressionOption = LogicalExpressionOption | RelationalExpressionOption | TrueFalseExpressionOption;
  124. declare type ValueGetterParam = Dictionary<unknown>;
  125. export interface ConditionalExpressionValueGetterParamGetter<VGP extends ValueGetterParam = ValueGetterParam> {
  126. (relExpOption: RelationalExpressionOption): VGP;
  127. }
  128. export interface ConditionalExpressionValueGetter<VGP extends ValueGetterParam = ValueGetterParam> {
  129. (param: VGP): OptionDataValue;
  130. }
  131. declare class ConditionalExpressionParsed {
  132. private _cond;
  133. constructor(exprOption: ConditionalExpressionOption, getters: ConditionalGetters);
  134. evaluate(): boolean;
  135. }
  136. interface ConditionalGetters<VGP extends ValueGetterParam = ValueGetterParam> {
  137. prepareGetValue: ConditionalExpressionValueGetterParamGetter<VGP>;
  138. getValue: ConditionalExpressionValueGetter<VGP>;
  139. valueGetterAttrMap: HashMap<boolean, string>;
  140. }
  141. export declare function parseConditionalExpression<VGP extends ValueGetterParam = ValueGetterParam>(exprOption: ConditionalExpressionOption, getters: ConditionalGetters<VGP>): ConditionalExpressionParsed;
  142. export {};