You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pinot.apache.org by GitBox <gi...@apache.org> on 2019/01/08 18:15:08 UTC

[GitHub] apucher closed pull request #3663: [TE] rootcause - fix slider and offset quirks

apucher closed pull request #3663: [TE] rootcause - fix slider and offset quirks
URL: https://github.com/apache/incubator-pinot/pull/3663
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range/component.js b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range/component.js
index 0367de61d3..a766beeb31 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range/component.js
+++ b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range/component.js
@@ -4,6 +4,7 @@ import $ from 'jquery';
 import {
   makeTime
 } from 'thirdeye-frontend/utils/rca-utils';
+import _ from 'lodash';
 
 // TODO consolidate rootcause-select-comparison-range2, rootcause-slider
 
@@ -35,8 +36,7 @@ export default Component.extend({
   compareMode: null, // ""
   onChange: null, // func (start, end, compareMode)
   slider: null,
-  originalMinInvestigatePeriod: null,
-  originalMaxInvestigatePeriod: null,
+  sliderOptionsCache: null,
 
   rangeOptions: {
     'Last hour': [makeTime().subtract(1, 'hours').startOf('hour'), makeTime().startOf('hours').add(1, 'hours')],
@@ -68,19 +68,19 @@ export default Component.extend({
     }
   ],
 
-  minDisplayWindow: computed('displayRange.[]', function() {//display window start - slider
+  minDisplayWindow: computed('displayRange', function() {//display window start - slider
     return makeTime(this.get('displayRange')[0]);
   }),
 
-  maxDisplayWindow: computed('displayRange.[]', function() {//display window end - slider
+  maxDisplayWindow: computed('displayRange', function() {//display window end - slider
     return makeTime(this.get('displayRange')[1]);
   }),
 
-  minInvestigatePeriod: computed('anomalyRange.[]', function() {//Investigation period start - slider
+  minInvestigatePeriod: computed('anomalyRange', function() {//Investigation period start - slider
     return makeTime(this.get('anomalyRange')[0]);
   }),
 
-  maxInvestigatePeriod: computed('anomalyRange.[]', function() {//Investigation period - slider
+  maxInvestigatePeriod: computed('anomalyRange', function() {//Investigation period - slider
     return makeTime(this.get('anomalyRange')[1]);
   }),
 
@@ -88,12 +88,11 @@ export default Component.extend({
     return namedToEpocMapping[this.get('granularity')];
   }),
 
-
-  startFormatted: computed('anomalyRange.[]', function() {//investigation start
+  startFormatted: computed('anomalyRange', function() {//investigation start
     return makeTime(this.get('anomalyRange')[0]).format(serverDateFormat);
   }),
 
-  endFormatted: computed('anomalyRange.[]', function() {//investigation end
+  endFormatted: computed('anomalyRange', function() {//investigation end
     return makeTime(this.get('anomalyRange')[1]).format(serverDateFormat);
   }),
 
@@ -101,8 +100,13 @@ export default Component.extend({
     return makeTime().startOf('hour').add(1, 'hours').format(serverDateFormat);
   }),
 
-  compareModeFormatted: computed('compareMode', function() {
-    return this.get('compareMode');
+  compareModeFormatted: computed('compareMode', {
+    get () {
+      return this.get('compareMode');
+    },
+    set () {
+      // ignore to prevent override
+    }
   }),
 
   /**
@@ -112,7 +116,8 @@ export default Component.extend({
     this._super(...arguments);
     let $range = $('.js-range-slider');
     const timeFormat = this.get('timeFormat');
-    const { compareMode, onChange } = this.getProperties('compareMode', 'onChange');
+    const { onChange } = this.getProperties('onChange');
+    const $$ = this;
 
     $range.ionRangeSlider({
       type: 'double',
@@ -129,7 +134,7 @@ export default Component.extend({
       },
       onFinish: function (data) {
         // Update the display window's investigation period on the chart
-        onChange(makeTime(data.from).valueOf(), makeTime(data.to).valueOf(), compareMode);
+        onChange(makeTime(data.from).valueOf(), makeTime(data.to).valueOf(), $$.get('compareMode'));
       }
     });
 
@@ -148,37 +153,24 @@ export default Component.extend({
       // granularityOneWay: this.get('granularity')
     });
 
-    // Save original investigation periods
-    this.setProperties({
-      originalMinInvestigatePeriod: this.get('minInvestigatePeriod'),
-      originalMaxInvestigatePeriod: this.get('maxInvestigatePeriod')
-    });
-
     // Update the slider, by calling it's update method
-    this.get('slider').update({
+    const sliderOptionsCache = this.get('sliderOptionsCache');
+
+    const sliderOptions = {
       step: this.get('granularityOneWay'),
       min: this.get('minDisplayWindow').format('x'),
-      max: this.get('maxDisplayWindow').format('x')
-    });
+      max: this.get('maxDisplayWindow').format('x'),
+      from: this.get('minInvestigatePeriod').format('x'),
+      to: this.get('maxInvestigatePeriod').format('x')
+    };
+
+    if (!_.isEqual(sliderOptions, sliderOptionsCache)) {
+      this.get('slider').update(sliderOptions);
+      this.set('sliderOptionsCache', sliderOptions);
+    }
   },
 
   actions: {
-    onRange(start, end) {
-      const { compareMode, onChange } = this.getProperties('compareMode', 'onChange');
-
-      // Update anomalyRange for computed to recalculate
-      this.set('anomalyRange', [makeTime(start).valueOf(), makeTime(end).valueOf()]);
-
-      // Investigation period changed on date picker. Update the slider's min and max.
-      this.get('slider').update({
-        from: this.get('minInvestigatePeriod').format('x'),
-        to: this.get('maxInvestigatePeriod').format('x')
-      });
-
-      // Update the display window's investigation period on the chart
-      onChange(makeTime(start).valueOf(), makeTime(end).valueOf(), compareMode);
-    },
-
     onPickerRange(type, time) {
       const { compareMode, onChange } = this.getProperties('compareMode', 'onChange');
 
@@ -189,10 +181,6 @@ export default Component.extend({
       // Update for the date picker to be in sync
       this.set('anomalyRange', [makeTime(start).valueOf(), makeTime(end).valueOf()]);
 
-      // Investigation period changed on date picker. Update the slider's min and max.
-      let sliderOptions = type === 'start' ? { from: this.get('minInvestigatePeriod').format('x') } : { to: this.get('maxInvestigatePeriod').format('x') };
-      this.get('slider').update(sliderOptions);
-
       // Update the display window's investiation period on the chart
       onChange(makeTime(start).valueOf(), makeTime(end).valueOf(), compareMode);
     },
@@ -200,24 +188,6 @@ export default Component.extend({
     onCompareMode(compareMode) {
       const { anomalyRange, onChange } = this.getProperties('anomalyRange', 'onChange');
       onChange(anomalyRange[0], anomalyRange[1], compareMode);
-    },
-
-    resetSlider() {
-      const slider = this.get('slider');
-      // RESET - reset slider to it's first values
-      slider.reset();
-      // get original investigation periods
-      this.setProperties({
-        minInvestigatePeriod: this.get('originalMinInvestigatePeriod'),
-        maxInvestigatePeriod: this.get('originalMaxInvestigatePeriod')
-      });
-
-      // Update the slider, by calling it's update method
-      this.get('slider').update({
-        from: this.get('minInvestigatePeriod').format('x'),
-        to: this.get('maxInvestigatePeriod').format('x')
-      });
     }
-
   }
 });
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range2/component.js b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range2/component.js
deleted file mode 100644
index 4c8f32ae55..0000000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range2/component.js
+++ /dev/null
@@ -1,216 +0,0 @@
-import { computed } from '@ember/object';
-import Component from '@ember/component';
-import $ from 'jquery';
-import {
-  makeTime,
-  dateFormatFull
-} from 'thirdeye-frontend/utils/rca-utils';
-
-// TODO merge this with rootcause-select-comparison-range
-
-/**
- * Date format the date picker component expects
- * @type String
- *
- */
-const serverDateFormat = 'YYYY-MM-DD HH:mm';
-
-/**
- * @summary Mapping between values that are named on the backend to epoc time value in millis
- * @type {Object}
- * @example  `1_HOURS=3600000=1hr , 1800000=30mins` etc since we using epoc time values in millis
- */
-const namedToEpocMapping = {
-  '5_MINUTES': 300000,
-  '15_MINUTES': 900000,
-  '30_MINUTES': 1800000,
-  '1_HOURS': 3600000,
-  '3_HOURS': 10800000,
-  '1_DAYS': 86400000
-};
-
-
-export default Component.extend({
-  timeFormat: "MMM D, hh:mm a z",//slider
-  range: null, // [0, 0]
-  compareMode: null, // ""
-  onChange: null, // func (start, end, compareMode)
-  slider: null,
-  originalMinInvestigatePeriod: null,
-  originalMaxInvestigatePeriod: null,
-
-  rangeOptions: {
-    'Last hour': [makeTime().subtract(1, 'hours').startOf('hour'), makeTime().startOf('hours').add(1, 'hours')],
-    'Last 3 hours': [makeTime().subtract(3, 'hours').startOf('hour'), makeTime().startOf('hours').add(1, 'hours')],
-    'Last 6 hours': [makeTime().subtract(6, 'hours').startOf('hour'), makeTime().startOf('hours').add(1, 'hours')],
-    'Last 24 hours': [makeTime().subtract(24, 'hours').startOf('hour'), makeTime().startOf('hours').add(1, 'hours')]
-  },
-
-  compareModeOptions: [
-    'WoW',
-    'Wo2W',
-    'Wo3W',
-    'Wo4W',
-    'mean4w',
-    'median4w',
-    'min4w',
-    'max4w',
-    'predicted',
-    'none'
-  ],
-
-  minDisplayWindow: computed('displayRange.[]', function() {//display window start - slider
-    return makeTime(this.get('displayRange')[0]);
-  }),
-
-  maxDisplayWindow: computed('displayRange.[]', function() {//display window end - slider
-    return makeTime(this.get('displayRange')[1]);
-  }),
-
-  minInvestigatePeriod: computed('anomalyRange.[]', function() {//Investigation period start - slider
-    return makeTime(this.get('anomalyRange')[0]);
-  }),
-
-  maxInvestigatePeriod: computed('anomalyRange.[]', function() {//Investigation period - slider
-    return makeTime(this.get('anomalyRange')[1]);
-  }),
-
-  granularityOneWay: computed('granularity', function() {
-    return namedToEpocMapping[this.get('granularity')];
-  }),
-
-
-  startFormatted: computed('anomalyRange.[]', function() {//investigation start
-    return makeTime(this.get('anomalyRange')[0]).format(serverDateFormat);
-  }),
-
-  endFormatted: computed('anomalyRange.[]', function() {//investigation end
-    return makeTime(this.get('anomalyRange')[1]).format(serverDateFormat);
-  }),
-
-  maxDateFormatted: computed(function() {
-    return makeTime().startOf('hour').add(1, 'hours').format(serverDateFormat);
-  }),
-
-  compareModeFormatted: computed('compareMode', function() {
-    return this.get('compareMode');
-  }),
-
-  /**
-   * Default after elements are inserted
-   */
-  didInsertElement() {
-    this._super(...arguments);
-    let $range = $('.js-range-slider');
-    const timeFormat = this.get('timeFormat');
-    const { compareMode, onChange } = this.getProperties('compareMode', 'onChange');
-
-    $range.ionRangeSlider({
-      type: 'double',
-      grid: true,
-      grid_num: 1,
-      hide_min_max: true,
-      step: this.get('granularityOneWay'),
-      min: this.get('minDisplayWindow').format('x'),
-      max: this.get('maxDisplayWindow').format('x'),
-      from: this.get('minInvestigatePeriod').format('x'),
-      to: this.get('maxInvestigatePeriod').format('x'),
-      prettify: function (num) {
-        return makeTime(num).format(timeFormat);
-      },
-      onFinish: function (data) {
-        // Update the display window's investigation period on the chart
-        onChange(makeTime(data.from).valueOf(), makeTime(data.to).valueOf(), compareMode);
-      }
-    });
-
-    // Save slider instance to var
-    this.set('slider', $range.data('ionRangeSlider'));
-  },
-
-  didRender() {
-    this._super(...arguments);
-
-    // Set oneway assignment from these existing CPs
-    this.setProperties({
-      startFormattedOneWay: this.get('startFormatted'),
-      endFormattedOneWay: this.get('endFormatted'),
-      maxDateFormattedOneWay: this.get('maxDateFormatted'),
-      // granularityOneWay: this.get('granularity')
-    });
-
-    // Save original investigation periods
-    this.setProperties({
-      originalMinInvestigatePeriod: this.get('minInvestigatePeriod'),
-      originalMaxInvestigatePeriod: this.get('maxInvestigatePeriod')
-    });
-
-    // Update the slider, by calling it's update method
-    if (this.get('slider')) {
-      this.get('slider').update({
-        step: this.get('granularityOneWay'),
-        min: this.get('minDisplayWindow').format('x'),
-        max: this.get('maxDisplayWindow').format('x')
-      });
-    }
-  },
-
-  actions: {
-    onRange(start, end) {
-      const { compareMode, onChange } = this.getProperties('compareMode', 'onChange');
-
-      // Update anomalyRange for computed to recalculate
-      this.set('anomalyRange', [makeTime(start).valueOf(), makeTime(end).valueOf()]);
-
-      // Investigation period changed on date picker. Update the slider's min and max.
-      this.get('slider').update({
-        from: this.get('minInvestigatePeriod').format('x'),
-        to: this.get('maxInvestigatePeriod').format('x')
-      });
-
-      // Update the display window's investiation period on the chart
-      onChange(makeTime(start).valueOf(), makeTime(end).valueOf(), compareMode);
-    },
-
-    onPickerRange(type, time) {
-      const { compareMode, onChange } = this.getProperties('compareMode', 'onChange');
-
-      // Update anomalyRange for computed to recalculate
-      const start = type === 'start' ? makeTime(time).valueOf() : this.get('minInvestigatePeriod').valueOf();
-      const end = type === 'start' ? this.get('maxInvestigatePeriod').valueOf() : makeTime(time).valueOf();
-
-      // Update for the date picker to be in sync
-      this.set('anomalyRange', [makeTime(start).valueOf(), makeTime(end).valueOf()]);
-
-      // Investigation period changed on date picker. Update the slider's min and max.
-      let sliderOptions = type === 'start' ? { from: this.get('minInvestigatePeriod').format('x') } : { to: this.get('maxInvestigatePeriod').format('x') };
-      this.get('slider').update(sliderOptions);
-
-      // Update the display window's investiation period on the chart
-      onChange(makeTime(start).valueOf(), makeTime(end).valueOf(), compareMode);
-    },
-
-    onCompareMode(compareMode) {
-      const { anomalyRange, onChange } = this.getProperties('anomalyRange', 'onChange');
-      onChange(anomalyRange[0], anomalyRange[1], compareMode);
-    },
-
-    resetSlider() {
-      const slider = this.get('slider');
-      // RESET - reset slider to it's first values
-      slider.reset();
-      // get original investigation periods
-      this.setProperties({
-        minInvestigatePeriod: this.get('originalMinInvestigatePeriod'),
-        maxInvestigatePeriod: this.get('originalMaxInvestigatePeriod')
-      });
-
-      // Update the slider, by calling it's update method
-      this.get('slider').update({
-        from: this.get('minInvestigatePeriod').format('x'),
-        to: this.get('maxInvestigatePeriod').format('x')
-      });
-    }
-
-  }
-});
diff --git a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range2/template.hbs b/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range2/template.hbs
deleted file mode 100644
index 88caf8bdd8..0000000000
--- a/thirdeye/thirdeye-frontend/app/pods/components/rootcause-select-comparison-range2/template.hbs
+++ /dev/null
@@ -1,74 +0,0 @@
-<div class="col-xs-3">
-  <label class="te-label te-label--small">Baseline
-    <span>
-      <i class="glyphicon glyphicon-question-sign"></i>
-      {{#tooltip-on-element class="te-tooltip"}}
-        This is the compare mode for computing the baseline in the charts above and below. For example, "Wo2W" uses data from the analysis period shifted by two weeks.
-      {{/tooltip-on-element}}
-    </span>
-  </label>
-  {{#power-select
-    selected=compareModeFormatted
-    options=compareModeOptions
-    searchEnabled=false
-    triggerId="select-compare-mode"
-    onchange=(action "onCompareMode")
-  as |mode|
-  }}
-    {{mode}}
-  {{/power-select}}
-</div>
-<div class="col-xs-9">
-  <!-- Investigation range slider -->
-  <div class="date-slider date-slider--offset" style="position: relative;top: 20px;">
-    <div class="date-slider__picker">
-      <div class="date-slider__picker-item">
-        <label class="te-label te-label--small">Investigation Period
-          <span>
-            <i class="glyphicon glyphicon-question-sign"></i>
-            {{#tooltip-on-element class="te-tooltip"}}
-              Typically, this is your anomaly period. It is highlighted in orange in the graph above. It also affects the data in views below.
-            {{/tooltip-on-element}}
-          </span>
-        </label>
-      </div>
-      <div class="date-slider__picker-item">
-        {{date-range-picker
-          class="te-range-picker te-range-picker__from"
-          singleDatePicker=true
-          showDropdowns=true
-          timePicker=true
-          timePicker24Hour=true
-          timePickerIncrement=5
-          start=startFormattedOneWay
-          end=startFormattedOneWay
-          maxDate=maxDateFormatted
-          ranges=rangeOptions
-          format=timeFormat
-          serverFormat="YYYY-MM-DD HH:mm"
-          applyAction=(action "onPickerRange" "start")
-        }}
-      </div>
-      <div class="date-slider__picker-item">
-        <label class="te-label te-label--small">to</label>
-      </div>
-      <div class="date-slider__picker-item">
-        {{date-range-picker
-          class="te-range-picker te-range-picker__to"
-          singleDatePicker=true
-          showDropdowns=true
-          timePicker=true
-          timePicker24Hour=true
-          timePickerIncrement=5
-          start=endFormattedOneWay
-          end=endFormattedOneWay
-          maxDate=maxDateFormatted
-          ranges=rangeOptions
-          format=timeFormat
-          serverFormat="YYYY-MM-DD HH:mm"
-          applyAction=(action "onPickerRange" "end")
-        }}
-      </div>
-    </div>
-  </div>
-</div>
diff --git a/thirdeye/thirdeye-frontend/app/utils/rca-utils.js b/thirdeye/thirdeye-frontend/app/utils/rca-utils.js
index 151eaaebb8..4c2103c1c6 100644
--- a/thirdeye/thirdeye-frontend/app/utils/rca-utils.js
+++ b/thirdeye/thirdeye-frontend/app/utils/rca-utils.js
@@ -376,48 +376,62 @@ export function filterPrefix(urns, prefixes) {
 }
 
 /**
- * Converts a time range tuple to another time range with a given offset
+ * Converts a time range tuple to another time range with a given offset (in Pacific time zone)
  *
  * @param {Array} range time range tuple [start, end]
  * @param {string} offset time offset ('current', 'baseline', 'wo1w', 'wo2w', 'wo3w', 'wo4w)
  * @returns {Array} offset time range tuple
  */
 export function toBaselineRange(range, offset) {
-  const offsetWeeks = {
-    current: 0,
-    none: 0,
-    predicted: 0,
-    wow: 1,
-    wo1w: 1,
-    wo2w: 2,
-    wo3w: 3,
-    wo4w: 4,
-    mean4w: 1, // default. not fully supported by backend yet
-    median4w: 1, // default. not fully supported by backend yet
-    min4w: 1, // default. not fully supported by backend yet
-    max4w: 1, // default. not fully supported by backend yet
-    ho1h: 1,
-    ho2h: 1,
-    ho3h: 1,
-    median4h: 1,
-    mean4h: 1,
-    do1d: 1,
-    do2d: 1,
-    do3d: 1,
-    median4d: 1,
-    mean4d: 1,
-    mo1m: 1,
-    mo2m: 1,
-    mo3m: 1,
-    median4m: 1,
-    mean4m: 1
+  const timeOffset = {
+    current: [0, 'weeks'],
+    predicted: [0, 'weeks'], // no backend support
+    none: [0, 'weeks'], // no backend support
+
+    wow: [1, 'weeks'],
+    wo1w: [1, 'weeks'],
+    wo2w: [2, 'weeks'],
+    wo3w: [3, 'weeks'],
+    wo4w: [4, 'weeks'],
+    mean4w: [1, 'weeks'], // no backend support
+    median4w: [1, 'weeks'], // no backend support
+    min4w: [1, 'weeks'], // no backend support
+    max4w: [1, 'weeks'], // no backend support
+
+    ho1h: [1, 'hours'],
+    ho2h: [2, 'hours'],
+    ho3h: [3, 'hours'],
+    ho6h: [6, 'hours'],
+    median6h: [1, 'hours'], // no backend support
+    mean6h: [1, 'hours'], // no backend support
+    min6h: [1, 'hours'], // no backend support
+    max6h: [1, 'hours'], // no backend support
+
+    do1d: [1, 'days'],
+    do2d: [2, 'days'],
+    do3d: [3, 'days'],
+    do4d: [4, 'days'],
+    median4d: [1, 'days'], // no backend support
+    mean4d: [1, 'days'], // no backend support
+    min4d: [1, 'days'], // no backend support
+    max4d: [1, 'days'], // no backend support
+
+    mo1m: [1, 'months'],
+    mo2m: [2, 'months'],
+    mo3m: [3, 'months'],
+    mo6m: [6, 'months'],
+    median6m: [1, 'months'], // no backend support
+    mean6m: [1, 'months'], // no backend support
+    min6m: [1, 'months'], // no backend support
+    max6m: [1, 'months'] // no backend support
+
   }[offset.toLowerCase()];
 
-  if (offsetWeeks === 0) {
+  if (!timeOffset || timeOffset[0] === 0) {
     return range;
   }
 
-  const start = makeTime(range[0]).subtract(offsetWeeks, 'weeks').valueOf();
+  const start = makeTime(range[0]).subtract(timeOffset[0], timeOffset[1]).valueOf();
   const end = start + (range[1] - range[0]);
 
   return [start, end];


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@pinot.apache.org
For additional commands, e-mail: dev-help@pinot.apache.org