<commit_before>
var mfoPjax = {};

(function () {

    mfoPjax.init = init;
    mfoPjax.onError = onError;
    mfoPjax.load = load;
    mfoPjax.addOverlay = addOverlay;
    mfoPjax.removeOverlay = removeOverlay;

    var lastButton = null;

    function init() {

        $(document).on('click', '[data-pjax] a', onNavigate);
        $(document).on('submit', '[data-pjax] form', onSubmitForm);
        $(window).on('popstate', onPopState);
        $(document).on('click', 'input[type=submit], button', onSubmitClicked);

    }

    function onSubmitClicked(e) {

        if (lastButton) {
            lastButton.removeAttr('clicked');
        }

        lastButton = $(e.currentTarget);
        lastButton.attr('clicked', 'true');

    }

    function onNavigate(e) {

        var anchor = $(e.currentTarget);

        if (anchor.attr('data-nopjax')) {
            return;
        }

        var container = anchor.closest('[data-pjax]');
        var url = anchor.attr('href');

        if (!url || url.substr(0, 1) === '#') {
            return;
        }

        if (!container.attr('id')) {
            container.attr('id', 'pjax_' + new Date().valueOf());
        }

        if (url.toLowerCase().substr(0, 7) === 'http://' || url.toLowerCase().substr(0, 8) === 'https://') {
            return; // we don't pjax external links
        }

        var context = {
            anchor: anchor,
            url: url,
            verb: 'GET',
            container: container
        };

        container.trigger("pjax:navigate", context);

        if (context.cancel === true) {
            return;
        }

        if (history.state === null || history.state.containerId !== container.attr('id')) {
            var state = history.state || {};
            state.url = location.pathname + location.search + location.hash;
            state.containerId = container.attr('id');
            history.replaceState(state, null, '');
        }

        mfoPjax.load(context, navigateSuccess);
        e.preventDefault();

    }

    function onSubmitForm(e) {

        var form = $(e.currentTarget);

        var clickedButton = form.find('*[clicked=true]');

        if (clickedButton.attr('data-nopjax')) {
            return;
        }

        var container = form.closest('[data-pjax]');
        var data = form.serialize();

        if (clickedButton.length > 0) {
            data += '&' + clickedButton.attr('name') + '=' + clickedButton.attr('value');
        }

        var context = {
            form: form,
            url: form.attr('action') || location.pathname + location.search + location.hash,
            data: data,
            verb: form.attr('method') || 'POST',
            container: container
        };

        container.trigger("pjax:submitform", context);

        if (context.cancel === true) {
            return;
        }

        mfoPjax.load(context, navigateSuccess);
        e.preventDefault();
    }

    function onPopState(e) {

        var popState = e.originalEvent.state;

        if (popState === null || !popState.containerId) {
            return;
        }

        var container = $('#' + popState.containerId);

        if (container.length === 0) {
            // no container - just refresh the page
            location.reload();
            return;
        }

        var context = {
            verb: 'GET',
            url: popState.url,
            container: container
        };

        mfoPjax.load(context, function (context, data) {
            render(container, data);
        });
    }

    function onError(jqXHR, textStatus, errorThrown, context, callback) {
        // default is to do nothing if there was no response (and return false) and
        // to display the error otherwise (and return true)
        // clients can change pjax.onError to their requirements

        if (!jqXHR.responseText) {
            return false;
        }

        callback(context, jqXHR.responseText, textStatus, jqXHR);
        return true;
    }

    function navigateSuccess(context, data, textStatus, jqXHR) {

        var container = context.container;
        render(container, data);

        if (context.noPushState === true) {
            return;
        }

        var url = stripInternalParams(jqXHR.getResponseHeader('X-PJAX-URL') || context.url);

        if (url !== location.href) {
            history.pushState({ url: url, containerId: context.container.attr('id') }, null, url);
        }
    }

    function stripInternalParams(url) {
        return url.replace(/([?&])(_pjax|_)=[^&]*/g, '');
    }

    function render(container, data) {

        container.html(data);

        var pjaxContent = container.children(':first');
        document.title = pjaxContent.attr('data-title');

    }

    function addOverlay(fadeTime1, fadeTime2) {

        return $('

').css({
            'opacity': '0',
            'margin': '0',
            'border': '0',
            'position': 'fixed',
            'top': 0,
            'left': 0,
            'width': '100%',
            'height': '100%',
            'z-index': 10000
        })
            .fadeTo(fadeTime1 || 100, 0)
            .fadeTo(fadeTime2 || 1500, 0.2)
            .appendTo('body');

    }

    function removeOverlay(overlay) {

        overlay.stop(true)
            .fadeTo(50, 0, function () {
                overlay.remove();
            });

    }

    function load(context, callback) {

        callback = callback || navigateSuccess;

        var overlay = mfoPjax.addOverlay()
            .css('cursor', 'wait');

        var headers = {
            'X-PJAX': 'true',
            'X-PJAX-URL': context.url
        };

        $.extend(headers, context.headers);

        $.ajax({
            headers: headers,
            cache: false,
            type: context.verb,
            url: context.url,
            data: context.data,
            timeout: 29000,
            dataType: 'html',
            success: function (data, textStatus, jqXHR) {
                mfoPjax.removeOverlay(overlay);
                callback(context, data, textStatus, jqXHR);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                mfoPjax.removeOverlay(overlay);
                mfoPjax.onError(jqXHR, textStatus, errorThrown, context, callback);
            }
        });

    }

}());
<commit_msg>Corrected dialog title when using nested dialogs<commit_after>
var mfoPjax = {};

(function () {

    mfoPjax.init = init;
    mfoPjax.onError = onError;
    mfoPjax.load = load;
    mfoPjax.addOverlay = addOverlay;
    mfoPjax.removeOverlay = removeOverlay;

    var lastButton = null;

    function init() {

        $(document).on('click', '[data-pjax] a', onNavigate);
        $(document).on('submit', '[data-pjax] form', onSubmitForm);
        $(window).on('popstate', onPopState);
        $(document).on('click', 'input[type=submit], button', onSubmitClicked);

    }

    function onSubmitClicked(e) {

        if (lastButton) {
            lastButton.removeAttr('clicked');
        }

        lastButton = $(e.currentTarget);
        lastButton.attr('clicked', 'true');

    }

    function onNavigate(e) {

        var anchor = $(e.currentTarget);

        if (anchor.attr('data-nopjax')) {
            return;
        }

        var container = anchor.closest('[data-pjax]');
        var url = anchor.attr('href');

        if (!url || url.substr(0, 1) === '#') {
            return;
        }

        if (!container.attr('id')) {
            container.attr('id', 'pjax_' + new Date().valueOf());
        }

        if (url.toLowerCase().substr(0, 7) === 'http://' || url.toLowerCase().substr(0, 8) === 'https://') {
            return; // we don't pjax external links
        }

        var context = {
            anchor: anchor,
            url: url,
            verb: 'GET',
            container: container
        };

        container.trigger("pjax:navigate", context);

        if (context.cancel === true) {
            return;
        }

        if (history.state === null || history.state.containerId !== container.attr('id')) {
            var state = history.state || {};
            state.url = location.pathname + location.search + location.hash;
            state.containerId = container.attr('id');
            history.replaceState(state, null, '');
        }

        mfoPjax.load(context, navigateSuccess);
        e.preventDefault();

    }

    function onSubmitForm(e) {

        var form = $(e.currentTarget);

        var clickedButton = form.find('*[clicked=true]');

        if (clickedButton.attr('data-nopjax')) {
            return;
        }

        var container = form.closest('[data-pjax]');
        var data = form.serialize();

        if (clickedButton.length > 0) {
            data += '&' + clickedButton.attr('name') + '=' + clickedButton.attr('value');
        }

        var context = {
            form: form,
            url: form.attr('action') || location.pathname + location.search + location.hash,
            data: data,
            verb: form.attr('method') || 'POST',
            container: container
        };

        container.trigger("pjax:submitform", context);

        if (context.cancel === true) {
            return;
        }

        mfoPjax.load(context, navigateSuccess);
        e.preventDefault();
    }

    function onPopState(e) {

        var popState = e.originalEvent.state;

        if (popState === null || !popState.containerId) {
            return;
        }

        var container = $('#' + popState.containerId);

        if (container.length === 0) {
            // no container - just refresh the page
            location.reload();
            return;
        }

        var context = {
            verb: 'GET',
            url: popState.url,
            container: container
        };

        mfoPjax.load(context, function (context, data) {
            render(context, data);
        });
    }

    function onError(jqXHR, textStatus, errorThrown, context, callback) {
        // default is to do nothing if there was no response (and return false) and
        // to display the error otherwise (and return true)
        // clients can change pjax.onError to their requirements

        if (!jqXHR.responseText) {
            return false;
        }

        callback(context, jqXHR.responseText, textStatus, jqXHR);
        return true;
    }

    function navigateSuccess(context, data, textStatus, jqXHR) {

        render(context, data);

        if (context.noPushState === true) {
            return;
        }

        var url = stripInternalParams(jqXHR.getResponseHeader('X-PJAX-URL') || context.url);

        if (url !== location.href) {
            history.pushState({ url: url, containerId: context.container.attr('id') }, null, url);
        }
    }

    function stripInternalParams(url) {
        return url.replace(/([?&])(_pjax|_)=[^&]*/g, '');
    }

    function render(context, data) {

        var container = context.container;
        container.html(data);

        if (context.noPushState !== true) {
            var pjaxContent = container.children(':first');
            var title = pjaxContent.attr('data-title');
            document.title = title;
        }

    }

    function addOverlay(fadeTime1, fadeTime2) {

        return $('

').css({
            'opacity': '0',
            'margin': '0',
            'border': '0',
            'position': 'fixed',
            'top': 0,
            'left': 0,
            'width': '100%',
            'height': '100%',
            'z-index': 10000
        })
            .fadeTo(fadeTime1 || 100, 0)
            .fadeTo(fadeTime2 || 1500, 0.2)
            .appendTo('body');

    }

    function removeOverlay(overlay) {

        overlay.stop(true)
            .fadeTo(50, 0, function () {
                overlay.remove();
            });

    }

    function load(context, callback) {

        callback = callback || navigateSuccess;

        var overlay = mfoPjax.addOverlay()
            .css('cursor', 'wait');

        var headers = {
            'X-PJAX': 'true',
            'X-PJAX-URL': context.url
        };

        $.extend(headers, context.headers);

        $.ajax({
            headers: headers,
            cache: false,
            type: context.verb,
            url: context.url,
            data: context.data,
            timeout: 29000,
            dataType: 'html',
            success: function (data, textStatus, jqXHR) {
                mfoPjax.removeOverlay(overlay);
                callback(context, data, textStatus, jqXHR);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                mfoPjax.removeOverlay(overlay);
                mfoPjax.onError(jqXHR, textStatus, errorThrown, context, callback);
            }
        });

    }

}());
<|endoftext|>


<commit_before>import React from 'react';
// import styled from 'styled-components';
import FlexRowContentCenter from 'components/FlexRowContentCenter';
import { Icon, Button } from 'antd-mobile';

function WelcomeMessage(props) {
  const { style } = props;
  return (

活动规则

分享邀请到微信朋友圈立即获得5元现金红包

      <FlexRowContentCenter style={{ marginTop: '0.3rem' }}>
        <Icon type={require('icons/ali/喇叭.svg')} color="#ff5c5d" />

好消息：

若有好友通过您的分享加入健康商信，您还可以领取到更多红包~

      </FlexRowContentCenter>
      <FlexRowContentCenter>
        <Button
          style={{
            marginTop: '0.5rem',
            width: '6.75rem',
            borderRadius: '0.42rem',
            color: '#ff5c5d',
            fontWeight: 'bold',
          }}
          onClick={() => {
            // android && android.showPopupWindow();
            WebViewJavascriptBridge && WebViewJavascriptBridge.showShare();
          }}
        >
        立即分享到朋友圈
        </Button>
      </FlexRowContentCenter>

  );
}

WelcomeMessage.propTypes = {

};

export default WelcomeMessage;
<commit_msg>. update check logic for bridge call fn<commit_after>import React from 'react';
// import styled from 'styled-components';

import brower from 'utils/brower';

import FlexRowContentCenter from 'components/FlexRowContentCenter';
import { Icon, Button } from 'antd-mobile';

function WelcomeMessage(props) {
  const { style } = props;
  return (

活动规则

分享邀请到微信朋友圈立即获得5元现金红包

      <FlexRowContentCenter style={{ marginTop: '0.3rem' }}>
        <Icon type={require('icons/ali/喇叭.svg')} color="#ff5c5d" />

好消息：

若有好友通过您的分享加入健康商信，您还可以领取到更多红包~

      </FlexRowContentCenter>
      <FlexRowContentCenter>
        <Button
          style={{
            marginTop: '0.5rem',
            width: '6.75rem',
            borderRadius: '0.42rem',
            color: '#ff5c5d',
            fontWeight: 'bold',
          }}
          onClick={() => {
            if (brower.checkIfIOS()) {
              WebViewJavascriptBridge && WebViewJavascriptBridge.showShare();
            } else {
              android && android.showPopupWindow();
            }
          }}
        >
        立即分享到朋友圈
        </Button>
      </FlexRowContentCenter>

  );
}

WelcomeMessage.propTypes = {

};

export default WelcomeMessage;
<|endoftext|>


<commit_before>import { createSelector, createStructuredSelector } from 'reselect';
import flatten from 'lodash/flatten';
import isEmpty from 'lodash/isEmpty';

import { getTileGeoJSON } from './components/recent-imagery/recent-imagery-selectors';
import { initialState } from './reducers';

// get list data
const getMapUrlState = state =>
  (state.location && state.location.query && state.location.query.map) || null;
const getDatasets = state => state.datasets.datasets;
const getLatest = state => state.latest.data;
const getLoading = state =>
  state.datasets.loading ||
  state.geostore.loading ||
  state.map.loading ||
  state.latest.loading;
const getGeostore = state => state.geostore.geostore || null;
const getQuery = state => (state.location && state.location.query) || null;
const selectEmbed = state =>
  (state.location &&
    state.location.pathname &&
    state.location.pathname.includes('embed')) ||
  null;
const selectLocation = state =>
  (state.location && state.location.payload) || null;
// analysis selects
const selectAnalysisSettings = state =>
  state.location && state.location.query && state.location.query.analysis;
const selectWidgetActiveSettings = state => state.widgets.settings;
// popup interactons
const selectSelectedInteractionId = state => state.popup.selected;
const selectInteractions = state => state.popup.interactions;
const selectMenuSection = state =>
  state.location.query &&
  state.location.query.menu &&
  state.location.query.menu.menuSection;

// get all map settings
export const getMapSettings = createSelector([getMapUrlState], urlState => ({
  ...initialState.settings,
  ...urlState
}));

// get single map settings
export const getBasemap = createSelector(
  getMapSettings,
  settings => settings.basemap
);

export const getMapZoom = createSelector(
  getMapSettings,
  settings => settings.zoom
);

export const getLabels = createSelector(
  getMapSettings,
  settings => settings.label
);

export const getDraw = createSelector(
  [getMapSettings, selectAnalysisSettings],
  (settings, analysisSettings) => settings.draw && analysisSettings.showDraw
);

export const getBbox = createSelector(
  getMapSettings,
  settings => settings.bbox
);

export const getHidePanels = createSelector(
  getMapSettings,
  settings => settings.hidePanels
);

export const getCanBound = createSelector(
  getMapSettings,
  settings => settings.canBound
);

export const getMapOptions = createSelector(getMapSettings, settings => {
  if (!settings) return null;
  const {
    center,
    zoom,
    minZoom,
    maxZoom,
    zoomControl,
    basemap,
    label,
    attributionControl
  } = settings;
  return {
    center,
    zoom,
    minZoom,
    maxZoom,
    zoomControl,
    label,
    basemap,
    attributionControl
  };
});

// select datasets and dataset state
export const getActiveDatasetsState = createSelector(
  getMapSettings,
  settings => settings.datasets
);

export const getActiveDatasetIds = createSelector(
  [getActiveDatasetsState],
  activeDatasetsState => {
    if (!activeDatasetsState || !activeDatasetsState.length) return null;
    return activeDatasetsState.map(l => l.dataset);
  }
);

export const getActiveDatasets = createSelector(
  [getDatasets, getActiveDatasetIds],
  (datasets, datasetIds) => {
    if (isEmpty(datasets) || isEmpty(datasetIds)) return null;
    return datasets.filter(d => datasetIds.includes(d.id));
  }
);

export const getBoundaryDatasets = createSelector([getDatasets], datasets => {
  if (isEmpty(datasets)) return null;
  return datasets.filter(d => d.isBoundary).map(d => ({
    name: d.name,
    dataset: d.id,
    layers: d.layers.map(l => l.id),
    id: d.id,
    label: d.name,
    value: d.layer
  }));
});

export const getAllBoundaries = createSelector(
  [getBoundaryDatasets],
  boundaries =>
    [{ label: 'No boundaries', value: 'no-boundaries' }].concat(boundaries)
);

export const getActiveBoundaryDatasets = createSelector(
  [getBoundaryDatasets, getActiveDatasets],
  (datasets, activeDatasets) => {
    if (isEmpty(datasets) || isEmpty(activeDatasets)) return null;
    const datasetIds = activeDatasets.map(d => d.dataset);
    return datasets.find(d => datasetIds.includes(d.dataset));
  }
);

// parse active datasets to add config from url
export const getDatasetsWithConfig = createSelector(
  [getActiveDatasets, getActiveDatasetsState, getLatest],
  (datasets, activeDatasetsState, latestDates) => {
    if (isEmpty(datasets) || isEmpty(activeDatasetsState)) return null;

    return datasets.map(d => {
      const layerConfig =
        activeDatasetsState.find(l => l.dataset === d.id) || {};
      const {
        params,
        sqlParams,
        decodeParams,
        timelineParams,
        layers,
        visibility,
        opacity,
        bbox
      } =
        layerConfig || {};

      return {
        ...d,
        ...layerConfig,
        ...(d.selectorLayerConfig && {
          selectorLayerConfig: {
            ...d.selectorLayerConfig,
            selected: d.selectorLayerConfig.options.find(
              l => l.value === layers[0]
            )
          }
        }),
        layers: d.layers.map(l => {
          const {
            hasParamsTimeline,
            hasDecodeTimeline,
            timelineConfig,
            id
          } = l;
          const maxDate = latestDates[id];

          return {
            ...l,
            visibility,
            opacity,
            bbox,
            color: d.color,
            active: layers && layers.includes(l.id),
            ...(!isEmpty(l.params) && {
              params: {
                ...l.params,
                ...params,
                ...(hasParamsTimeline && {
                  ...timelineParams
                }),
                ...(maxDate && {
                  maxDate
                })
              }
            }),
            ...(!isEmpty(l.sqlParams) && {
              sqlParams: {
                ...l.sqlParams,
                ...sqlParams
              }
            }),
            ...(!isEmpty(l.decodeParams) &&
              l.decodeFunction && {
                decodeParams: {
                  ...l.decodeParams,
                  ...(layers &&
                    layers.includes('confirmedOnly') && {
                      confirmedOnly: true
                    }),
                  ...decodeParams,
                  ...(hasDecodeTimeline && {
                    ...timelineParams
                  }),
                  ...(maxDate && {
                    maxDate
                  })
                }
              }),
            ...((l.hasParamsTimeline || l.hasDecodeTimeline) && {
              timelineConfig: {
                ...timelineConfig,
                ...(l.hasParamsTimeline && {
                  ...l.params
                }),
                ...(l.hasDecodeTimeline && {
                  ...l.decodeParams
                }),
                ...timelineParams,
                ...(maxDate && {
                  maxDate
                })
              }
            })
          };
        })
      };
    });
  }
);

// map active datasets into correct order based on url state (drag and drop)
export const getLayerGroups = createSelector(
  [getDatasetsWithConfig, getActiveDatasetsState],
  (datasets, activeDatasetsState) => {
    if (isEmpty(datasets) || isEmpty(activeDatasetsState)) return null;

    return activeDatasetsState
      .map(l => datasets.find(d => d.id === l.dataset))
      .filter(l => l)
      .map(d => {
        const { metadata } = (d && d.layers.find(l => l.active)) || {};
        return {
          ...d,
          metadata: metadata || d.metadata
        };
      });
  }
);

// filter out any boundary layers that are for the basemaps comp
export const getLegendLayerGroups = createSelector([getLayerGroups], groups => {
  if (!groups) return null;
  return groups.filter(g => !g.isBoundary && !g.isRecentImagery);
});

// flatten datasets into layers for the layer manager
export const getAllLayers = createSelector(getLayerGroups, layerGroups => {
  if (isEmpty(layerGroups)) return null;

  return flatten(layerGroups.map(d => d.layers))
    .filter(l => l.active)
    .map((l, i) => ({
      ...l,
      zIndex:
        l.interactionConfig && l.interactionConfig.article ? 1100 + i : 1000 - i
    }));
});

// all layers for importing by other components
export const getActiveLayers = createSelector(getAllLayers, layers => {
  if (isEmpty(layers)) return [];
  return layers.filter(l => !l.confirmedOnly);
});

// flatten datasets into layers for the layer manager
export const getActiveLayersWithWidgetSettings = createSelector(
  [getAllLayers, selectWidgetActiveSettings],
  (layers, widgetSettings) => {
    if (isEmpty(layers)) return [];
    if (isEmpty(widgetSettings)) return layers;
    return layers.map(l => {
      const layerWidgetState =
        widgetSettings &&
        Object.values(widgetSettings).find(
          w => w.layers && w.layers.includes(l.id)
        );
      const { updateLayer } = layerWidgetState || {};
      return {
        ...l,
        ...(l.decodeParams &&
          updateLayer && {
            decodeParams: {
              ...l.decodeParams,
              ...layerWidgetState
            }
          }),
        ...(l.params &&
          updateLayer && {
            params: {
              ...l.params,
              ...layerWidgetState
            }
          })
      };
    });
  }
);

export const getLayerBbox = createSelector([getActiveLayers], layers => {
  const layerWithBbox =
    layers && layers.find(l => l.bbox || (l.layerConfig && l.layerConfig.bbox));
  const layerBbox =
    layerWithBbox &&
    (layerWithBbox.bbox ||
      (layerWithBbox.layerConfig && layerWithBbox.layerConfig.bbox));
  return layerBbox;
});

export const getGeostoreBbox = createSelector(
  [getGeostore],
  geostore => geostore && geostore.bbox
);

// analysis
export const getShowAnalysis = createSelector(
  getQuery,
  query => query && query.analysis && query.analysis.showAnalysis
);

export const getOneClickAnalysisActive = createSelector(
  [selectAnalysisSettings, selectLocation, getDraw, getLoading],
  (settings, location, draw, loading) =>
    settings &&
    !draw &&
    !loading &&
    settings.showAnalysis &&
    !settings.showDraw &&
    !location.adm0
);

export const filterInteractions = createSelector(
  [selectInteractions],
  interactions => {
    if (isEmpty(interactions)) return null;
    return Object.values(interactions)
      .filter(i => !isEmpty(i.data))
      .map(i => ({
        ...i
      }));
  }
);

export const getSelectedInteraction = createSelector(
  [filterInteractions, selectSelectedInteractionId, getActiveLayers],
  (options, selected, layers) => {
    if (isEmpty(options)) return null;
    const layersWithoutBoundaries = layers.filter(
      l => !l.isBoundary && !isEmpty(l.interactionConfig)
    );
    // if there is an article (icon layer) then choose that
    let selectedData = options.find(o => o.article);
    // if there is nothing selected get the top layer
    if (!selected && !!layersWithoutBoundaries.length) {
      selectedData = options.find(
        o => o.value === layersWithoutBoundaries[0].id
      );
    }
    // if only one layer then get that
    if (!selectedData && options.length === 1) selectedData = options[0];
    // otherwise get based on selected
    if (!selectedData) selectedData = options.find(o => o.value === selected);
    const layer =
      selectedData && layers && layers.find(l => l.id === selectedData.id);

    return { ...selectedData, layer };
  }
);

export const getMapProps = createStructuredSelector({
  mapOptions: getMapOptions,
  basemap: getBasemap,
  label: getLabels,
  loading: getLoading,
  layerBbox: getLayerBbox,
  geostoreBbox: getGeostoreBbox,
  bbox: getBbox,
  canBound: getCanBound,
  tileGeoJSON: getTileGeoJSON,
  draw: getDraw,
  analysisActive: getShowAnalysis,
  oneClickAnalysisActive: getOneClickAnalysisActive,
  embed: selectEmbed,
  hidePanels: getHidePanels,
  selectedInteraction: getSelectedInteraction,
  menuSection: selectMenuSection,
  activeDatasets: getActiveDatasetsState
});
<commit_msg>fix datepicker not getting maxDate on first render<commit_after>import { createSelector, createStructuredSelector } from 'reselect';
import flatten from 'lodash/flatten';
import isEmpty from 'lodash/isEmpty';

import { getTileGeoJSON } from './components/recent-imagery/recent-imagery-selectors';
import { initialState } from './reducers';

// get list data
const getMapUrlState = state =>
  (state.location && state.location.query && state.location.query.map) || null;
const getDatasets = state => state.datasets.datasets;
const getLatest = state => state.latest.data;
const getLoading = state =>
  state.datasets.loading ||
  state.geostore.loading ||
  state.map.loading ||
  state.latest.loading;
const getGeostore = state => state.geostore.geostore || null;
const getQuery = state => (state.location && state.location.query) || null;
const selectEmbed = state =>
  (state.location &&
    state.location.pathname &&
    state.location.pathname.includes('embed')) ||
  null;
const selectLocation = state =>
  (state.location && state.location.payload) || null;
// analysis selects
const selectAnalysisSettings = state =>
  state.location && state.location.query && state.location.query.analysis;
const selectWidgetActiveSettings = state => state.widgets.settings;
// popup interactons
const selectSelectedInteractionId = state => state.popup.selected;
const selectInteractions = state => state.popup.interactions;
const selectMenuSection = state =>
  state.location.query &&
  state.location.query.menu &&
  state.location.query.menu.menuSection;

// get all map settings
export const getMapSettings = createSelector([getMapUrlState], urlState => ({
  ...initialState.settings,
  ...urlState
}));

// get single map settings
export const getBasemap = createSelector(
  getMapSettings,
  settings => settings.basemap
);

export const getMapZoom = createSelector(
  getMapSettings,
  settings => settings.zoom
);

export const getLabels = createSelector(
  getMapSettings,
  settings => settings.label
);

export const getDraw = createSelector(
  [getMapSettings, selectAnalysisSettings],
  (settings, analysisSettings) => settings.draw && analysisSettings.showDraw
);

export const getBbox = createSelector(
  getMapSettings,
  settings => settings.bbox
);

export const getHidePanels = createSelector(
  getMapSettings,
  settings => settings.hidePanels
);

export const getCanBound = createSelector(
  getMapSettings,
  settings => settings.canBound
);

export const getMapOptions = createSelector(getMapSettings, settings => {
  if (!settings) return null;
  const {
    center,
    zoom,
    minZoom,
    maxZoom,
    zoomControl,
    basemap,
    label,
    attributionControl
  } = settings;
  return {
    center,
    zoom,
    minZoom,
    maxZoom,
    zoomControl,
    label,
    basemap,
    attributionControl
  };
});

// select datasets and dataset state
export const getActiveDatasetsState = createSelector(
  getMapSettings,
  settings => settings.datasets
);

export const getActiveDatasetIds = createSelector(
  [getActiveDatasetsState],
  activeDatasetsState => {
    if (!activeDatasetsState || !activeDatasetsState.length) return null;
    return activeDatasetsState.map(l => l.dataset);
  }
);

export const getActiveDatasets = createSelector(
  [getDatasets, getActiveDatasetIds],
  (datasets, datasetIds) => {
    if (isEmpty(datasets) || isEmpty(datasetIds)) return null;
    return datasets.filter(d => datasetIds.includes(d.id));
  }
);

export const getBoundaryDatasets = createSelector([getDatasets], datasets => {
  if (isEmpty(datasets)) return null;
  return datasets.filter(d => d.isBoundary).map(d => ({
    name: d.name,
    dataset: d.id,
    layers: d.layers.map(l => l.id),
    id: d.id,
    label: d.name,
    value: d.layer
  }));
});

export const getAllBoundaries = createSelector(
  [getBoundaryDatasets],
  boundaries =>
    [{ label: 'No boundaries', value: 'no-boundaries' }].concat(boundaries)
);

export const getActiveBoundaryDatasets = createSelector(
  [getBoundaryDatasets, getActiveDatasets],
  (datasets, activeDatasets) => {
    if (isEmpty(datasets) || isEmpty(activeDatasets)) return null;
    const datasetIds = activeDatasets.map(d => d.dataset);
    return datasets.find(d => datasetIds.includes(d.dataset));
  }
);

// parse active datasets to add config from url
export const getDatasetsWithConfig = createSelector(
  [getActiveDatasets, getActiveDatasetsState, getLatest],
  (datasets, activeDatasetsState, latestDates) => {
    if (isEmpty(datasets) || isEmpty(activeDatasetsState)) return null;

    return datasets.map(d => {
      const layerConfig =
        activeDatasetsState.find(l => l.dataset === d.id) || {};
      const {
        params,
        sqlParams,
        decodeParams,
        timelineParams,
        layers,
        visibility,
        opacity,
        bbox
      } =
        layerConfig || {};

      return {
        ...d,
        ...layerConfig,
        ...(d.selectorLayerConfig && {
          selectorLayerConfig: {
            ...d.selectorLayerConfig,
            selected: d.selectorLayerConfig.options.find(
              l => l.value === layers[0]
            )
          }
        }),
        layers: d.layers.map(l => {
          const {
            hasParamsTimeline,
            hasDecodeTimeline,
            timelineConfig,
            id
          } = l;
          const maxDate = latestDates[id];

          return {
            ...l,
            visibility,
            opacity,
            bbox,
            color: d.color,
            active: layers && layers.includes(l.id),
            ...(!isEmpty(l.params) && {
              params: {
                ...l.params,
                ...(maxDate && {
                  endDate: maxDate
                }),
                ...params,
                ...(hasParamsTimeline && {
                  ...timelineParams
                })
              }
            }),
            ...(!isEmpty(l.sqlParams) && {
              sqlParams: {
                ...l.sqlParams,
                ...sqlParams
              }
            }),
            ...(!isEmpty(l.decodeParams) &&
              l.decodeFunction && {
                decodeParams: {
                  ...l.decodeParams,
                  ...(layers &&
                    layers.includes('confirmedOnly') && {
                      confirmedOnly: true
                    }),
                  ...(maxDate && {
                    endDate: maxDate
                  }),
                  ...decodeParams,
                  ...(hasDecodeTimeline && {
                    ...timelineParams
                  })
                }
              }),
            ...((l.hasParamsTimeline || l.hasDecodeTimeline) && {
              timelineConfig: {
                ...timelineConfig,
                ...(l.hasParamsTimeline && {
                  ...l.params
                }),
                ...(l.hasDecodeTimeline && {
                  ...l.decodeParams
                }),
                ...(maxDate && {
                  endDate: maxDate,
                  maxDate,
                  trimEndDate: maxDate
                }),
                ...timelineParams
              }
            })
          };
        })
      };
    });
  }
);

// map active datasets into correct order based on url state (drag and drop)
export const getLayerGroups = createSelector(
  [getDatasetsWithConfig, getActiveDatasetsState],
  (datasets, activeDatasetsState) => {
    if (isEmpty(datasets) || isEmpty(activeDatasetsState)) return null;

    return activeDatasetsState
      .map(l => datasets.find(d => d.id === l.dataset))
      .filter(l => l)
      .map(d => {
        const { metadata } = (d && d.layers.find(l => l.active)) || {};
        return {
          ...d,
          metadata: metadata || d.metadata
        };
      });
  }
);

// filter out any boundary layers that are for the basemaps comp
export const getLegendLayerGroups = createSelector([getLayerGroups], groups => {
  if (!groups) return null;
  return groups.filter(g => !g.isBoundary && !g.isRecentImagery);
});

// flatten datasets into layers for the layer manager
export const getAllLayers = createSelector(getLayerGroups, layerGroups => {
  if (isEmpty(layerGroups)) return null;

  return flatten(layerGroups.map(d => d.layers))
    .filter(l => l.active)
    .map((l, i) => ({
      ...l,
      zIndex:
        l.interactionConfig && l.interactionConfig.article ? 1100 + i : 1000 - i
    }));
});

// all layers for importing by other components
export const getActiveLayers = createSelector(getAllLayers, layers => {
  if (isEmpty(layers)) return [];
  return layers.filter(l => !l.confirmedOnly);
});

// flatten datasets into layers for the layer manager
export const getActiveLayersWithWidgetSettings = createSelector(
  [getAllLayers, selectWidgetActiveSettings],
  (layers, widgetSettings) => {
    if (isEmpty(layers)) return [];
    if (isEmpty(widgetSettings)) return layers;
    return layers.map(l => {
      const layerWidgetState =
        widgetSettings &&
        Object.values(widgetSettings).find(
          w => w.layers && w.layers.includes(l.id)
        );
      const { updateLayer } = layerWidgetState || {};
      return {
        ...l,
        ...(l.decodeParams &&
          updateLayer && {
            decodeParams: {
              ...l.decodeParams,
              ...layerWidgetState
            }
          }),
        ...(l.params &&
          updateLayer && {
            params: {
              ...l.params,
              ...layerWidgetState
            }
          })
      };
    });
  }
);

export const getLayerBbox = createSelector([getActiveLayers], layers => {
  const layerWithBbox =
    layers && layers.find(l => l.bbox || (l.layerConfig && l.layerConfig.bbox));
  const layerBbox =
    layerWithBbox &&
    (layerWithBbox.bbox ||
      (layerWithBbox.layerConfig && layerWithBbox.layerConfig.bbox));
  return layerBbox;
});

export const getGeostoreBbox = createSelector(
  [getGeostore],
  geostore => geostore && geostore.bbox
);

// analysis
export const getShowAnalysis = createSelector(
  getQuery,
  query => query && query.analysis && query.analysis.showAnalysis
);

export const getOneClickAnalysisActive = createSelector(
  [selectAnalysisSettings, selectLocation, getDraw, getLoading],
  (settings, location, draw, loading) =>
    settings &&
    !draw &&
    !loading &&
    settings.showAnalysis &&
    !settings.showDraw &&
    !location.adm0
);

export const filterInteractions = createSelector(
  [selectInteractions],
  interactions => {
    if (isEmpty(interactions)) return null;
    return Object.values(interactions)
      .filter(i => !isEmpty(i.data))
      .map(i => ({
        ...i
      }));
  }
);

export const getSelectedInteraction = createSelector(
  [filterInteractions, selectSelectedInteractionId, getActiveLayers],
  (options, selected, layers) => {
    if (isEmpty(options)) return null;
    const layersWithoutBoundaries = layers.filter(
      l => !l.isBoundary && !isEmpty(l.interactionConfig)
    );
    // if there is an article (icon layer) then choose that
    let selectedData = options.find(o => o.article);
    // if there is nothing selected get the top layer
    if (!selected && !!layersWithoutBoundaries.length) {
      selectedData = options.find(
        o => o.value === layersWithoutBoundaries[0].id
      );
    }
    // if only one layer then get that
    if (!selectedData && options.length === 1) selectedData = options[0];
    // otherwise get based on selected
    if (!selectedData) selectedData = options.find(o => o.value === selected);
    const layer =
      selectedData && layers && layers.find(l => l.id === selectedData.id);

    return { ...selectedData, layer };
  }
);

export const getMapProps = createStructuredSelector({
  mapOptions: getMapOptions,
  basemap: getBasemap,
  label: getLabels,
  loading: getLoading,
  layerBbox: getLayerBbox,
  geostoreBbox: getGeostoreBbox,
  bbox: getBbox,
  canBound: getCanBound,
  tileGeoJSON: getTileGeoJSON,
  draw: getDraw,
  analysisActive: getShowAnalysis,
  oneClickAnalysisActive: getOneClickAnalysisActive,
  embed: selectEmbed,
  hidePanels: getHidePanels,
  selectedInteraction: getSelectedInteraction,
  menuSection: selectMenuSection,
  activeDatasets: getActiveDatasetsState
});
<|endoftext|>


<commit_before>import {
  TIMELINE_REFRESH_REQUEST,
  TIMELINE_REFRESH_SUCCESS,
  TIMELINE_REFRESH_FAIL,
  TIMELINE_UPDATE,
  TIMELINE_DELETE,
  TIMELINE_EXPAND_SUCCESS,
  TIMELINE_EXPAND_REQUEST,
  TIMELINE_EXPAND_FAIL,
  TIMELINE_SCROLL_TOP,
  TIMELINE_CONNECT,
  TIMELINE_DISCONNECT,
} from '../actions/timelines';
import {
  ACCOUNT_BLOCK_SUCCESS,
  ACCOUNT_MUTE_SUCCESS,
  ACCOUNT_UNFOLLOW_SUCCESS,
} from '../actions/accounts';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';

const initialState = ImmutableMap();

const initialTimeline = ImmutableMap({
  unread: 0,
  online: false,
  top: true,
  loaded: false,
  isLoading: false,
  next: false,
  items: ImmutableList(),
});

const normalizeTimeline = (state, timeline, statuses, next) => {
  const oldIds    = state.getIn([timeline, 'items'], ImmutableList());
  const ids       = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
  const wasLoaded = state.getIn([timeline, 'loaded']);
  const hadNext   = state.getIn([timeline, 'next']);

  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    mMap.set('loaded', true);
    mMap.set('isLoading', false);
    if (!hadNext) mMap.set('next', next);
    mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
  }));
};

const appendNormalizedTimeline = (state, timeline, statuses, next) => {
  const oldIds = state.getIn([timeline, 'items'], ImmutableList());
  const ids    = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));

  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    mMap.set('isLoading', false);
    mMap.set('next', next);
    mMap.set('items', oldIds.concat(ids));
  }));
};

const updateTimeline = (state, timeline, status, references) => {
  const top        = state.getIn([timeline, 'top']);
  const ids        = state.getIn([timeline, 'items'], ImmutableList());
  const includesId = ids.includes(status.get('id'));
  const unread     = state.getIn([timeline, 'unread'], 0);

  if (includesId) {
    return state;
  }

  let newIds = ids;

  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    if (!top) mMap.set('unread', unread + 1);
    if (top && ids.size > 40) newIds = newIds.take(20);
    if (status.getIn(['reblog', 'id'], null) !== null) newIds = newIds.filterNot(item => references.includes(item));
    mMap.set('items', newIds.unshift(status.get('id')));
  }));
};

const deleteStatus = (state, id, accountId, references) => {
  state.keySeq().forEach(timeline => {
    state = state.updateIn([timeline, 'items'], list => list.filterNot(item => item === id));
  });

  // Remove reblogs of deleted status
  references.forEach(ref => {
    state = deleteStatus(state, ref[0], ref[1], []);
  });

  return state;
};

const filterTimelines = (state, relationship, statuses) => {
  let references;

  statuses.forEach(status => {
    if (status.get('account') !== relationship.id) {
      return;
    }

    references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => [item.get('id'), item.get('account')]);
    state      = deleteStatus(state, status.get('id'), status.get('account'), references);
  });

  return state;
};

const filterTimeline = (timeline, state, relationship, statuses) =>
  state.updateIn([timeline, 'items'], ImmutableList(), list =>
    list.filterNot(statusId =>
      statuses.getIn([statusId, 'account']) === relationship.id
    ));

const updateTop = (state, timeline, top) => {
  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    if (top) mMap.set('unread', 0);
    mMap.set('top', top);
  }));
};

export default function timelines(state = initialState, action) {
  switch(action.type) {
  case TIMELINE_REFRESH_REQUEST:
  case TIMELINE_EXPAND_REQUEST:
    return state.update(action.timeline, initialTimeline, map => map.set('isLoading', true));
  case TIMELINE_REFRESH_FAIL:
  case TIMELINE_EXPAND_FAIL:
    return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
  case TIMELINE_REFRESH_SUCCESS:
    return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next);
  case TIMELINE_EXPAND_SUCCESS:
    return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
  case TIMELINE_UPDATE:
    return updateTimeline(state, action.timeline, fromJS(action.status), action.references);
  case TIMELINE_DELETE:
    return deleteStatus(state, action.id, action.accountId, action.references, action.reblogOf);
  case ACCOUNT_BLOCK_SUCCESS:
  case ACCOUNT_MUTE_SUCCESS:
    return filterTimelines(state, action.relationship, action.statuses);
  case ACCOUNT_UNFOLLOW_SUCCESS:
    return filterTimeline('home', state, action.relationship, action.statuses);
  case TIMELINE_SCROLL_TOP:
    return updateTop(state, action.timeline, action.top);
  case TIMELINE_CONNECT:
    return state.update(action.timeline, initialTimeline, map => map.set('online', true));
  case TIMELINE_DISCONNECT:
    return state.update(action.timeline, initialTimeline, map => map.set('online', false));
  default:
    return state;
  }
};
<commit_msg>Don't remove originals of boosted toots from timeline (#5479)<commit_after>import {
  TIMELINE_REFRESH_REQUEST,
  TIMELINE_REFRESH_SUCCESS,
  TIMELINE_REFRESH_FAIL,
  TIMELINE_UPDATE,
  TIMELINE_DELETE,
  TIMELINE_EXPAND_SUCCESS,
  TIMELINE_EXPAND_REQUEST,
  TIMELINE_EXPAND_FAIL,
  TIMELINE_SCROLL_TOP,
  TIMELINE_CONNECT,
  TIMELINE_DISCONNECT,
} from '../actions/timelines';
import {
  ACCOUNT_BLOCK_SUCCESS,
  ACCOUNT_MUTE_SUCCESS,
  ACCOUNT_UNFOLLOW_SUCCESS,
} from '../actions/accounts';
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';

const initialState = ImmutableMap();

const initialTimeline = ImmutableMap({
  unread: 0,
  online: false,
  top: true,
  loaded: false,
  isLoading: false,
  next: false,
  items: ImmutableList(),
});

const normalizeTimeline = (state, timeline, statuses, next) => {
  const oldIds    = state.getIn([timeline, 'items'], ImmutableList());
  const ids       = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));
  const wasLoaded = state.getIn([timeline, 'loaded']);
  const hadNext   = state.getIn([timeline, 'next']);

  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    mMap.set('loaded', true);
    mMap.set('isLoading', false);
    if (!hadNext) mMap.set('next', next);
    mMap.set('items', wasLoaded ? ids.concat(oldIds) : ids);
  }));
};

const appendNormalizedTimeline = (state, timeline, statuses, next) => {
  const oldIds = state.getIn([timeline, 'items'], ImmutableList());
  const ids    = ImmutableList(statuses.map(status => status.get('id'))).filter(newId => !oldIds.includes(newId));

  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    mMap.set('isLoading', false);
    mMap.set('next', next);
    mMap.set('items', oldIds.concat(ids));
  }));
};

const updateTimeline = (state, timeline, status) => {
  const top        = state.getIn([timeline, 'top']);
  const ids        = state.getIn([timeline, 'items'], ImmutableList());
  const includesId = ids.includes(status.get('id'));
  const unread     = state.getIn([timeline, 'unread'], 0);

  if (includesId) {
    return state;
  }

  let newIds = ids;

  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    if (!top) mMap.set('unread', unread + 1);
    if (top && ids.size > 40) newIds = newIds.take(20);
    mMap.set('items', newIds.unshift(status.get('id')));
  }));
};

const deleteStatus = (state, id, accountId, references) => {
  state.keySeq().forEach(timeline => {
    state = state.updateIn([timeline, 'items'], list => list.filterNot(item => item === id));
  });

  // Remove reblogs of deleted status
  references.forEach(ref => {
    state = deleteStatus(state, ref[0], ref[1], []);
  });

  return state;
};

const filterTimelines = (state, relationship, statuses) => {
  let references;

  statuses.forEach(status => {
    if (status.get('account') !== relationship.id) {
      return;
    }

    references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => [item.get('id'), item.get('account')]);
    state      = deleteStatus(state, status.get('id'), status.get('account'), references);
  });

  return state;
};

const filterTimeline = (timeline, state, relationship, statuses) =>
  state.updateIn([timeline, 'items'], ImmutableList(), list =>
    list.filterNot(statusId =>
      statuses.getIn([statusId, 'account']) === relationship.id
    ));

const updateTop = (state, timeline, top) => {
  return state.update(timeline, initialTimeline, map => map.withMutations(mMap => {
    if (top) mMap.set('unread', 0);
    mMap.set('top', top);
  }));
};

export default function timelines(state = initialState, action) {
  switch(action.type) {
  case TIMELINE_REFRESH_REQUEST:
  case TIMELINE_EXPAND_REQUEST:
    return state.update(action.timeline, initialTimeline, map => map.set('isLoading', true));
  case TIMELINE_REFRESH_FAIL:
  case TIMELINE_EXPAND_FAIL:
    return state.update(action.timeline, initialTimeline, map => map.set('isLoading', false));
  case TIMELINE_REFRESH_SUCCESS:
    return normalizeTimeline(state, action.timeline, fromJS(action.statuses), action.next);
  case TIMELINE_EXPAND_SUCCESS:
    return appendNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next);
  case TIMELINE_UPDATE:
    return updateTimeline(state, action.timeline, fromJS(action.status));
  case TIMELINE_DELETE:
    return deleteStatus(state, action.id, action.accountId, action.references, action.reblogOf);
  case ACCOUNT_BLOCK_SUCCESS:
  case ACCOUNT_MUTE_SUCCESS:
    return filterTimelines(state, action.relationship, action.statuses);
  case ACCOUNT_UNFOLLOW_SUCCESS:
    return filterTimeline('home', state, action.relationship, action.statuses);
  case TIMELINE_SCROLL_TOP:
    return updateTop(state, action.timeline, action.top);
  case TIMELINE_CONNECT:
    return state.update(action.timeline, initialTimeline, map => map.set('online', true));
  case TIMELINE_DISCONNECT:
    return state.update(action.timeline, initialTimeline, map => map.set('online', false));
  default:
    return state;
  }
};
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';

import { withRouter, Route } from 'react-router-dom'
import { connect } from 'react-redux'

import {
        Tab ,
        Tabs ,
        Avatar ,
        Typography,
        Button,
        TextField,
        Paper,
        Grid,
      } from '@material-ui/core';

import {getFileMetadata, directUpload} from '../../shared/fileUploader'

//import {Link} from 'react-router-dom'

import graphql from '../../graphql/client'

import {
  CREATE_DIRECT_UPLOAD,
  ARTICLE_BLOB_ATTACH,
} from '../../graphql/mutations'

import { withStyles } from '@material-ui/core/styles';

//import Loader from './loader'
import _ from "lodash"

import GestureIcon from '@material-ui/icons/Gesture'
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import {setCurrentPage} from '../../actions/navigation'
import FieldRenderer from '../../shared/FormFields'
import ContentHeader from '../../components/ContentHeader'
import Content from '../../components/Content'

const styles = theme => ({

  paper: {
    margin: '9em',
    padding: '1em',
    marginTop: '1.5em',
    paddingBottom: '6em'
  }
});

class Settings extends Component {

  state = {
    loading: true,
    tabValue: 0
  };

  titleRef = null
  descriptionRef = null
  switch_ref = null

  componentDidMount(){
    this.props.dispatch(
      setCurrentPage('Help Center')
    )
  }

  updateState = (data)=>{
    this.setState(data)
  }

  uploadHandler = (file, imageBlock)=>{

    getFileMetadata(file).then((input) => {
      graphql(CREATE_DIRECT_UPLOAD, input, {
        success: (data)=>{
          const {signedBlobId, headers, url, serviceUrl} = data.createDirectUpload.directUpload

          directUpload(url, JSON.parse(headers), file).then(
            () => {
              graphql(ARTICLE_BLOB_ATTACH, {
                appKey: this.props.app.key ,
                id: parseInt(this.state.article.id),
                blobId: signedBlobId
              }, {
                success: (data)=>{
                  imageBlock.uploadCompleted(serviceUrl)
                },
                error: (err)=>{
                  console.log("error on direct upload", err)
                }
              })
          });
        },
        error: (error)=>{
         console.log("error on signing blob", error)
        }
      })
    });
  }

  definitionsForSettings = () => {
    return [
      {
        name: "subdomain",
        hint: "documentation site subdomain",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },

      {
        name: "site title",
        hint: "documentation site subdomain",
        type: 'text',
        grid: { xs: 12, sm: 12 }
      },

      {
        name: "site description",
        hint: "documentation site subdomain",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },

      {
        name: "website",
        hint: "link to your website",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },

      {
        name: "google_code",
        hint: "Google Analytics Tracking ID",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },

      {
        name: "color",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "logo",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "header logo",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "facebook",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "twitter",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "linkedin",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "credits",
        type: 'bool',
        hint: "Display a subtle link to the Chaskiq website",
        grid: { xs: 12, sm: 8 }
      },
    ]
  }

  handleTabChange = (e, i)=>{
    this.setState({tabValue: i})
  }

  tabsContent = ()=>{
    return <Tabs value={this.state.tabValue}
              onChange={this.handleTabChange}
              textColor="inherit">
              <Tab textColor="inherit" label="Basic Setup" />
              <Tab textColor="inherit" label="Lang" />
              <Tab textColor="inherit" label="Appearance" />
            </Tabs>
  }

  renderTabcontent = ()=>{

    switch (this.state.tabValue){
      case 0:
        return <SettingsForm
                  title={"General app's information"}
                  //currentUser={this.props.currentUser}
                  //data={this.props.app}
                  //update={this.update.bind(this)}
                  //fetchApp={this.fetchApp}
                  //classes={this.props.classes}
                  definitions={this.definitionsForSettings}
                  {...this.props}
               />

      case 1:
        return <SettingsForm
                  title={"Security Settings"}
                  //currentUser={this.props.currentUser}
                  //data={this.props.app}
                  //update={this.update.bind(this)}
                  //fetchApp={this.fetchApp}
                  //classes={this.props.classes}
                  definitions={this.definitionsForSettings}
                  {...this.props}
                />
      case 2:
        return <SettingsForm
                  title={"Appearance settings"}
                  //currentUser={this.props.currentUser}
                  //data={this.props.app}
                  //update={this.update.bind(this)}
                  //fetchApp={this.fetchApp}
                  //classes={this.props.classes}
                  definitions={this.definitionsForSettings}
                  {...this.props}
                />
      case 3:
        return
ddkd

    }
  }

  render() {
    const {classes} = this.props
    return (
       <React.Fragment>

         <ContentHeader
            title={ 'App Settings' }
            tabsContent={ this.tabsContent() }
          />

          <Content>
            {this.renderTabcontent()}
          </Content>

      </React.Fragment>
    );
  }
}

class SettingsForm extends Component{
  render(){
    return (

      <Grid container spacing={3}>
        {
          this.props.definitions().map((field) => {

            return <Grid item
                      key={field.name}
                      xs={field.grid.xs}
                      sm={field.grid.sm}>
                      <FieldRenderer
                        namespace={'app'}
                        data={field}
                        props={{data: {}}}
                        errors={ {} }
                      />
                  </Grid>
          })
        }
      </Grid>
    )
  }
}

function mapStateToProps(state) {

  const { auth, app } = state
  const { isAuthenticated } = auth
  //const { sort, filter, collection , meta, loading} = conversations

  return {
    app,
    isAuthenticated
  }
}

export default withRouter(connect(mapStateToProps)(withStyles(styles)(Settings)))
<commit_msg>Update settings.js<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';

import { withRouter, Route } from 'react-router-dom'
import { connect } from 'react-redux'

import {
        Tab ,
        Tabs ,
        Avatar ,
        Typography,
        Button,
        TextField,
        Paper,
        Grid,
      } from '@material-ui/core';

import {getFileMetadata, directUpload} from '../../shared/fileUploader'

//import {Link} from 'react-router-dom'

import graphql from '../../graphql/client'

import {
  CREATE_DIRECT_UPLOAD,
  ARTICLE_BLOB_ATTACH,
} from '../../graphql/mutations'

import { withStyles } from '@material-ui/core/styles';

//import Loader from './loader'
import _ from "lodash"

import GestureIcon from '@material-ui/icons/Gesture'
import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import {setCurrentPage} from '../../actions/navigation'
import FieldRenderer from '../../shared/FormFields'
import ContentHeader from '../../components/ContentHeader'
import Content from '../../components/Content'

const styles = theme => ({

  paper: {
    margin: '9em',
    padding: '1em',
    marginTop: '1.5em',
    paddingBottom: '6em'
  }
});

class Settings extends Component {

  state = {
    loading: true,
    tabValue: 0
  };

  titleRef = null
  descriptionRef = null
  switch_ref = null

  componentDidMount(){
    this.props.dispatch(
      setCurrentPage('Help Center')
    )
  }

  updateState = (data)=>{
    this.setState(data)
  }

  uploadHandler = (file, imageBlock)=>{

    getFileMetadata(file).then((input) => {
      graphql(CREATE_DIRECT_UPLOAD, input, {
        success: (data)=>{
          const {signedBlobId, headers, url, serviceUrl} = data.createDirectUpload.directUpload

          directUpload(url, JSON.parse(headers), file).then(
            () => {
              graphql(ARTICLE_BLOB_ATTACH, {
                appKey: this.props.app.key ,
                id: parseInt(this.state.article.id),
                blobId: signedBlobId
              }, {
                success: (data)=>{
                  imageBlock.uploadCompleted(serviceUrl)
                },
                error: (err)=>{
                  console.log("error on direct upload", err)
                }
              })
          });
        },
        error: (error)=>{
         console.log("error on signing blob", error)
        }
      })
    });
  }

  definitionsForSettings = () => {
    return [
      {
        name: "subdomain",
        hint: "documentation site subdomain",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },
      {
        name: "site title",
        hint: "documentation site subdomain",
        type: 'text',
        grid: { xs: 12, sm: 12 }
      },
      {
        name: "site description",
        hint: "documentation site subdomain",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },
      {
        name: "website",
        hint: "link to your website",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },
      {
        name: "google_code",
        hint: "Google Analytics Tracking ID",
        type: 'string',
        grid: { xs: 12, sm: 12 }
      },
    ]
  }

  definitionsForAppearance = () => {
    return [
      {
        name: "color",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "logo",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "header logo",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "facebook",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "twitter",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "linkedin",
        type: 'string',
        grid: { xs: 12, sm: 4 }
      },

      {
        name: "credits",
        type: 'bool',
        hint: "Display a subtle link to the Chaskiq website",
        grid: { xs: 12, sm: 8 }
      },
    ]
  }

  definitionsForLang = () => {
    return [

    ]
  }

  handleTabChange = (e, i)=>{
    this.setState({tabValue: i})
  }

  tabsContent = ()=>{
    return <Tabs value={this.state.tabValue}
              onChange={this.handleTabChange}
              textColor="inherit">
              <Tab textColor="inherit" label="Basic Setup" />
              <Tab textColor="inherit" label="Lang" />
              <Tab textColor="inherit" label="Appearance" />
            </Tabs>
  }

  renderTabcontent = ()=>{

    switch (this.state.tabValue){
      case 0:
        return <SettingsForm
                  title={"General app's information"}
                  //currentUser={this.props.currentUser}
                  //data={this.props.app}
                  //update={this.update.bind(this)}
                  //fetchApp={this.fetchApp}
                  //classes={this.props.classes}
                  definitions={this.definitionsForSettings}
                  {...this.props}
               />

      case 1:
        return <SettingsForm
                  title={"Lang"}
                  //currentUser={this.props.currentUser}
                  //data={this.props.app}
                  //update={this.update.bind(this)}
                  //fetchApp={this.fetchApp}
                  //classes={this.props.classes}
                  definitions={this.definitionsForLang}
                  {...this.props}
                />
      case 2:
        return <SettingsForm
                  title={"Appearance settings"}
                  //currentUser={this.props.currentUser}
                  //data={this.props.app}
                  //update={this.update.bind(this)}
                  //fetchApp={this.fetchApp}
                  //classes={this.props.classes}
                  definitions={this.definitionsForAppearance}
                  {...this.props}
                />
      case 3:
        return
ddkd

    }
  }

  render() {
    const {classes} = this.props
    return (
       <React.Fragment>

         <ContentHeader
            title={ 'App Settings' }
            tabsContent={ this.tabsContent() }
          />

          <Content>
            {this.renderTabcontent()}
          </Content>

      </React.Fragment>
    );
  }
}

class SettingsForm extends Component{
  render(){
    return (

      <Grid container spacing={3}>
        {
          this.props.definitions().map((field) => {

            return <Grid item
                      key={field.name}
                      xs={field.grid.xs}
                      sm={field.grid.sm}>
                      <FieldRenderer
                        namespace={'app'}
                        data={field}
                        props={{data: {}}}
                        errors={ {} }
                      />
                  </Grid>
          })
        }
      </Grid>
    )
  }
}

function mapStateToProps(state) {

  const { auth, app } = state
  const { isAuthenticated } = auth
  //const { sort, filter, collection , meta, loading} = conversations

  return {
    app,
    isAuthenticated
  }
}

export default withRouter(connect(mapStateToProps)(withStyles(styles)(Settings)))
<|endoftext|>


<commit_before>/** * Imports ***/
import ShadersUniform from '../shaders/shaders.vr.uniform';
import ShadersVertex from '../shaders/shaders.vr.vertex';
import ShadersFragment from '../shaders/shaders.vr.fragment';

import HelpersMaterialMixin from '../helpers/helpers.material.mixin';

import {Matrix4} from 'three';

/**
 * @module helpers/volumerendering
 */

export default class HelpersVolumeRendering extends HelpersMaterialMixin(THREE.Object3D) {
  constructor(stack) {
    //
    super();

    this._stack = stack;
    this._textures = [];
    this._shadersFragment = ShadersFragment;
    this._shadersVertex = ShadersVertex;
    this._uniforms = ShadersUniform.uniforms();
    this._material = null;
    this._geometry = null;

    this._algorithm = 0; // ray marching
    this._alphaCorrection = 0.5; // default
    this._interpolation = 1; // default to trilinear interpolation
    this._shading = 1; // shading is on by default
    this._shininess = 10.0;
    this._steps = 256; // default
    this._windowCenter = 0.0;
    this._windowWidth = 1.0;

    this._create();
  }

  _create() {
    this._prepareStack();
    this._prepareTexture();
    this._prepareMaterial();
    this._prepareGeometry();

    this._mesh = new THREE.Mesh(this._geometry, this._material);
    this.add(this._mesh);
  }

  _prepareStack() {
    if (!this._stack.prepared) {
      this._stack.prepare();
    }

    if (!this._stack.packed) {
      this._stack.pack();
    }

    // compensate for the offset to only pass > 0 values to shaders
    // models > models.stack.js : _packTo8Bits
    this._offset = Math.min(0, this._stack._minMax[0]);
    this._windowCenter = this._stack.windowCenter;
    this._windowWidth = this._stack.windowWidth * 0.8; // multiply for better default visualization
  }

  _prepareMaterial() {
    // uniforms
    this._uniforms = ShadersUniform.uniforms();
    this._uniforms.uWorldBBox.value = this._stack.worldBoundingBox();
    this._uniforms.uTextureSize.value = this._stack.textureSize;
    this._uniforms.uTextureContainer.value = this._textures;
    this._uniforms.uWorldToData.value = this._stack.lps2IJK;
    this._uniforms.uNumberOfChannels.value = this._stack.numberOfChannels;
    this._uniforms.uPixelType.value = this._stack.pixelType;
    this._uniforms.uBitsAllocated.value = this._stack.bitsAllocated;
    this._uniforms.uPackedPerPixel.value = this._stack.packedPerPixel;
    this._uniforms.uWindowCenterWidth.value = [this._windowCenter - this._offset, this._windowWidth];
    this._uniforms.uRescaleSlopeIntercept.value = [this._stack.rescaleSlope, this._stack.rescaleIntercept];
    this._uniforms.uDataDimensions.value = [this._stack.dimensionsIJK.x,
                                                this._stack.dimensionsIJK.y,
                                                this._stack.dimensionsIJK.z];
    this._uniforms.uAlphaCorrection.value = this._alphaCorrection;
    this._uniforms.uInterpolation.value = this._interpolation;
    this._uniforms.uShading.value = this._shading;
    this._uniforms.uShininess.value = this._shininess;
    this._uniforms.uSteps.value = this._steps;
    this._uniforms.uAlgorithm.value = this._algorithm;

    this._createMaterial({
      side: THREE.BackSide,
      transparent: true,
    });
  }

  _prepareGeometry() {
    let worldBBox = this._stack.worldBoundingBox();
    let centerLPS = this._stack.worldCenter();

    this._geometry = new THREE.BoxGeometry(
      worldBBox[1] - worldBBox[0],
      worldBBox[3] - worldBBox[2],
      worldBBox[5] - worldBBox[4]);
    this._geometry.applyMatrix(new Matrix4().makeTranslation(
      centerLPS.x, centerLPS.y, centerLPS.z));
  }

  get uniforms() {
    return this._uniforms;
  }

  set uniforms(uniforms) {
    this._uniforms = uniforms;
  }

  get stack() {
    return this._stack;
  }

  set stack(stack) {
    this._stack = stack;
  }

  get windowCenter() {
    return this._windowCenter;
  }

  set windowCenter(windowCenter) {
    this._windowCenter = windowCenter;
    this._uniforms.uWindowCenterWidth.value[0] = this._windowCenter - this._offset;
  }

  get windowWidth() {
    return this._windowWidth;
  }

  set windowWidth(windowWidth) {
    this._windowWidth = Math.max(1, windowWidth);
    this._uniforms.uWindowCenterWidth.value[1] = this._windowWidth;
  }

  get steps() {
    return this._steps;
  }

  set steps(steps) {
    this._steps = steps;
    this._uniforms.uSteps.value = this._steps;
  }

  get alphaCorrection() {
    return this._alphaCorrection;
  }

  set alphaCorrection(alphaCorrection) {
    this._alphaCorrection = alphaCorrection;
    this._uniforms.uAlphaCorrection.value = this._alphaCorrection;
  }

  get interpolation() {
    return this._interpolation;
  }

  set interpolation(interpolation) {
    this._interpolation = interpolation;
    this._uniforms.uInterpolation.value = this._interpolation;
    this._updateMaterial();
  }

  get shading() {
    return this._shading;
  }

  set shading(shading) {
    this._shading = shading;
    this._uniforms.uShading.value = this._shading;
  }

  get shininess() {
    return this._shininess;
  }

  set shininess(shininess) {
    this._shininess = shininess;
    this._uniforms.uShininess.value = this._shininess;
  }

  get algorithm() {
    return this._algorithm;
  }

  set algorithm(algorithm) {
    this._algorithm = algorithm;
    this._uniforms.uAlgorithm.value = this._algorithm;
  }

  dispose() {
    // Release memory
    for (let j =0; j< this._textures.length; j++) {
      this._textures[j].dispose();
      this._textures[j] = null;
    }
    this._textures = null;
    this._shadersFragment = null;
    this._shadersVertex = null;

    this._uniforms.uTextureContainer = null;
    this._uniforms.uTextureLUT = null;
    this._uniforms = null;

    // material, geometry and mesh
    this.remove(this._mesh);
    this._mesh.geometry.dispose();
    this._mesh.geometry = null;
    this._mesh.material.dispose();
    this._mesh.material = null;
    this._mesh = null;

    this._geometry.dispose();
    this._geometry = null;
    this._material.vertexShader = null;
    this._material.fragmentShader = null;
    this._material.uniforms = null;
    this._material.dispose();
    this._material = null;

    this._stack = null;
  }
}
<commit_msg>Update helpers.volumerendering.js<commit_after>/** * Imports ***/
import ShadersUniform from '../shaders/shaders.vr.uniform';
import ShadersVertex from '../shaders/shaders.vr.vertex';
import ShadersFragment from '../shaders/shaders.vr.fragment';

import HelpersMaterialMixin from '../helpers/helpers.material.mixin';

import {Matrix4} from 'three';

/**
 * @module helpers/volumerendering
 */

export default class HelpersVolumeRendering extends HelpersMaterialMixin(THREE.Object3D) {
  constructor(stack) {
    //
    super();

    this._stack = stack;
    this._textures = [];
    this._shadersFragment = ShadersFragment;
    this._shadersVertex = ShadersVertex;
    this._uniforms = ShadersUniform.uniforms();
    this._material = null;
    this._geometry = null;

    this._algorithm = 0; // ray marching
    this._alphaCorrection = 0.5; // default
    this._interpolation = 1; // default to trilinear interpolation
    this._shading = 1; // shading is on by default
    this._shininess = 10.0;
    this._steps = 256; // default
    this._offset = 0.;
    this._windowCenter = 0.0;
    this._windowWidth = 1.0;

    this._create();
  }

  _create() {
    this._prepareStack();
    this._prepareTexture();
    this._prepareMaterial();
    this._prepareGeometry();

    this._mesh = new THREE.Mesh(this._geometry, this._material);
    this.add(this._mesh);
  }

  _prepareStack() {
    if (!this._stack.prepared) {
      this._stack.prepare();
    }

    if (!this._stack.packed) {
      this._stack.pack();
    }

    // compensate for the offset to only pass > 0 values to shaders
    // models > models.stack.js : _packTo8Bits
    this._offset = Math.min(0, this._stack._minMax[0]);
    this._windowCenter = this._stack.windowCenter;
    this._windowWidth = this._stack.windowWidth * 0.8; // multiply for better default visualization
  }

  _prepareMaterial() {
    // uniforms
    this._uniforms = ShadersUniform.uniforms();
    this._uniforms.uWorldBBox.value = this._stack.worldBoundingBox();
    this._uniforms.uTextureSize.value = this._stack.textureSize;
    this._uniforms.uTextureContainer.value = this._textures;
    this._uniforms.uWorldToData.value = this._stack.lps2IJK;
    this._uniforms.uNumberOfChannels.value = this._stack.numberOfChannels;
    this._uniforms.uPixelType.value = this._stack.pixelType;
    this._uniforms.uBitsAllocated.value = this._stack.bitsAllocated;
    this._uniforms.uPackedPerPixel.value = this._stack.packedPerPixel;
    this._uniforms.uWindowCenterWidth.value = [this._windowCenter - this._offset, this._windowWidth];
    this._uniforms.uRescaleSlopeIntercept.value = [this._stack.rescaleSlope, this._stack.rescaleIntercept];
    this._uniforms.uDataDimensions.value = [this._stack.dimensionsIJK.x,
                                                this._stack.dimensionsIJK.y,
                                                this._stack.dimensionsIJK.z];
    this._uniforms.uAlphaCorrection.value = this._alphaCorrection;
    this._uniforms.uInterpolation.value = this._interpolation;
    this._uniforms.uShading.value = this._shading;
    this._uniforms.uShininess.value = this._shininess;
    this._uniforms.uSteps.value = this._steps;
    this._uniforms.uAlgorithm.value = this._algorithm;

    this._createMaterial({
      side: THREE.BackSide,
      transparent: true,
    });
  }

  _prepareGeometry() {
    let worldBBox = this._stack.worldBoundingBox();
    let centerLPS = this._stack.worldCenter();

    this._geometry = new THREE.BoxGeometry(
      worldBBox[1] - worldBBox[0],
      worldBBox[3] - worldBBox[2],
      worldBBox[5] - worldBBox[4]);
    this._geometry.applyMatrix(new Matrix4().makeTranslation(
      centerLPS.x, centerLPS.y, centerLPS.z));
  }

  get uniforms() {
    return this._uniforms;
  }

  set uniforms(uniforms) {
    this._uniforms = uniforms;
  }

  get stack() {
    return this._stack;
  }

  set stack(stack) {
    this._stack = stack;
  }

  get windowCenter() {
    return this._windowCenter;
  }

  set windowCenter(windowCenter) {
    this._windowCenter = windowCenter;
    this._uniforms.uWindowCenterWidth.value[0] = this._windowCenter - this._offset;
  }

  get windowWidth() {
    return this._windowWidth;
  }

  set windowWidth(windowWidth) {
    this._windowWidth = Math.max(1, windowWidth);
    this._uniforms.uWindowCenterWidth.value[1] = this._windowWidth;
  }

  get steps() {
    return this._steps;
  }

  set steps(steps) {
    this._steps = steps;
    this._uniforms.uSteps.value = this._steps;
  }

  get alphaCorrection() {
    return this._alphaCorrection;
  }

  set alphaCorrection(alphaCorrection) {
    this._alphaCorrection = alphaCorrection;
    this._uniforms.uAlphaCorrection.value = this._alphaCorrection;
  }

  get interpolation() {
    return this._interpolation;
  }

  set interpolation(interpolation) {
    this._interpolation = interpolation;
    this._uniforms.uInterpolation.value = this._interpolation;
    this._updateMaterial();
  }

  get shading() {
    return this._shading;
  }

  set shading(shading) {
    this._shading = shading;
    this._uniforms.uShading.value = this._shading;
  }

  get shininess() {
    return this._shininess;
  }

  set shininess(shininess) {
    this._shininess = shininess;
    this._uniforms.uShininess.value = this._shininess;
  }

  get algorithm() {
    return this._algorithm;
  }

  set algorithm(algorithm) {
    this._algorithm = algorithm;
    this._uniforms.uAlgorithm.value = this._algorithm;
  }

  dispose() {
    // Release memory
    for (let j =0; j< this._textures.length; j++) {
      this._textures[j].dispose();
      this._textures[j] = null;
    }
    this._textures = null;
    this._shadersFragment = null;
    this._shadersVertex = null;

    this._uniforms.uTextureContainer = null;
    this._uniforms.uTextureLUT = null;
    this._uniforms = null;

    // material, geometry and mesh
    this.remove(this._mesh);
    this._mesh.geometry.dispose();
    this._mesh.geometry = null;
    this._mesh.material.dispose();
    this._mesh.material = null;
    this._mesh = null;

    this._geometry.dispose();
    this._geometry = null;
    this._material.vertexShader = null;
    this._material.fragmentShader = null;
    this._material.uniforms = null;
    this._material.dispose();
    this._material = null;

    this._stack = null;
  }
}
<|endoftext|>


<commit_before>import * as d3 from 'd3';
import {crossfilter, units, legend, lineChart, geoChoroplethChart, bubbleChart, renderAll, redrawAll, filterAll, pieChart, barChart, dataCount, dataTable, pluck, round} from 'dc';
import * as colorbrewer from "colorbrewer";
import reductio from 'reductio';
//we can call export at the top of the class declaration
export default class NOAADashDC {

  constructor(el, props = {}) {
    //we initiate charts in constructor
    this.myCharts = NOAADashDC.initCharts();
  }

  render() {
    //de-structure myCharts object
    //const {heightChart, periodChart} = this.myCharts;
    let {heightChart, periodChart, heightSLChart, periodSLChart} = this.myCharts;

    d3.csv('data/fullyear_wv_dec_cc.csv', (error, data) => {
      //format the data
      const buoyData = this.formatData(data);
      let wavesx = crossfilter(buoyData);
      // build the x dimensions
      let xDims = this.buildXDimensions(wavesx);
      //destructure the xDims object
      let {heightDim, periodDim, hMonthDim, pMonthDim} = xDims;
      //build the Y groups
      let yGroups = this.buildYGroups(wavesx, xDims);
      //de-structure they yGroups object
      let {heightGroup, periodGroup, hMonthGroup, pMonthGroup} = yGroups;
      //console.log(myMonthGroup.all());
      //console.log(yourMonthGroup.all());
      //call number format
      const numberFormat =  this.numberFormat();
      //dc.js Charts chained configuration

      heightSLChart = this.buildSLChart(heightSLChart, data, hMonthDim, hMonthGroup, periodSLChart, 'height');
      periodSLChart = this.buildSLChart(periodSLChart, data, pMonthDim, pMonthGroup, heightSLChart, 'period');
      this.buildHeightChart(heightChart, heightDim, heightGroup);
      this.buildPeriodChart(periodChart, periodDim, periodGroup, numberFormat);
      //draw the viz!
      renderAll();

    });
  }

  buildPeriodChart(periodChart, periodDim, periodGroup, numberFormat){
    //dc.barChart("#period-chart")
    periodChart
      .width(300)
      .height(180)
      .margins({top: 10, right: 50, bottom: 30, left: 40})
      .dimension(periodDim)
      .group(periodGroup)
      .elasticY(true)
    // (optional) whether bar should be center to its x value. Not needed for ordinal chart, :default=false
      .centerBar(true)
    // (optional) set gap between bars manually in px, :default=2
      .gap(45)
    // (optional) set filter brush rounding
      .round(round.floor)
      .x(d3.scale.linear().domain([0, 30]))
      .renderHorizontalGridLines(true)
    // customize the filter displayed in the control span
      .filterPrinter(function (filters) {
        var filter = filters[0], s = "";
        s += numberFormat(filter[0]) + "sec -> " + numberFormat(filter[1]) + "sec";
        return s;
      });
    // Customize axis
    periodChart.xAxis().tickFormat(
      function (v) { return v + "sec"; });
    periodChart.yAxis().ticks(5);

  }

  buildHeightChart(heightChart, heightDim, heightGroup){
    let numberFormat = this.numberFormat();
    heightChart
      .width(300)
      .height(180)
      .margins({top: 10, right: 50, bottom: 30, left: 40})
      .dimension(heightDim)
      .group(heightGroup)
      .elasticY(true)
    // (optional) whether bar should be center to its x value. Not needed for ordinal chart, :default=false
      .centerBar(true)
    // (optional) set gap between bars manually in px, :default=2
      .gap(65)
    // (optional) set filter brush rounding
      .round(round.floor)
      .x(d3.scale.linear().domain([0, 7]))
      .renderHorizontalGridLines(true)
    // customize the filter displayed in the control span
      .filterPrinter((filters) => {
        var filter = filters[0], s = "";
        s += numberFormat(filter[0]) + "met -> " + numberFormat(filter[1]) + "met";
        return s;
      });

    // Customize axis
    heightChart.xAxis().tickFormat((v) => {
      return v + "met";
    });
    heightChart.yAxis().ticks(5);

  }

  buildSLChart(chart, data, dim, group, range, dimension){
    chart /* dc.lineChart('#monthly-move-chart', 'chartGroup') */
      .renderArea(true)
      .width(990)
      .height(200)
      .transitionDuration(1000)
      .margins({top: 30, right: 50, bottom: 25, left: 40})
      .dimension(dim)
      .mouseZoomable(true)
    // Specify a "range chart" to link its brush extent with the zoom of the current "focus chart".
      .rangeChart(range)
    //.x(d3.time.scale().domain([new Date(2004, 0, 1), new Date(2012, 11, 31)]))
      .x(d3.time.scale().domain(d3.extent(data, (d) => { return d.dd; })))  //use extent to auto scale the axis
      .round(d3.time.month.round)
      .xUnits(d3.time.months)
      .elasticY(true)
      .renderHorizontalGridLines(true)
    //##### Legend

    // Position the legend relative to the chart origin and specify items' height and separation.
      .legend(legend().x(800).y(10).itemHeight(13).gap(5))
      .brushOn(false)
    // Add the base layer of the stack with group. The second parameter specifies a series name for use in the
    // legend.
    // The `.valueAccessor` will be used for the base layer
      .group(group, 'Monthly Height Min')
      .valueAccessor((d) =>  {
          //console.log(d.value.height.count);
          //console.log(d.value.[dimension].count);
          return d.value.count ? d.value.min : 0;
      })
    // Stack additional layers with `.stack`. The first paramenter is a new group.
    // The second parameter is the series name. The third is a value accessor.
      .stack(group, 'Monthly Height Average', (d) => {
        //console.log("val " + d.value);
          return d.value.count ? d.value.avg : 0;
      })
    // Title can be called by any stack layer.
    /* .title(function (d) {
       var value = d.value.avg ? d.value.avg : d.value;
       if (isNaN(value)) {
       value = 0;
       }
       return dateFormat(d.key) + '\n' + numberFormat(value);
       });*/
      .stack(group, "Monthly Height Max", (d) => {
          return d.value.count ? d.value.max : 0;
      })
   return chart;
  }

  static initCharts() {
    const heightChart = barChart('#chart-height');
    const periodChart = barChart('#chart-period');
    const heightSLChart = lineChart('#chart-month-move');
    const periodSLChart = lineChart('#chart-period-stacked-line');

    const myCharts = {heightChart, periodChart, heightSLChart, periodSLChart}
    return myCharts;
  }

  resetChart(chartName) {

    let {heightChart, periodChart} = this.myCharts;

    switch (chartName) {
      case "height-chart":
        heightChart.filterAll();
        break;
      case "period-chart":
        periodChart.filterAll();
        break;
      default:
        //Statements executed when none of the values match the value of the expression
        break;
    }

    redrawAll();
  }

  formatData(data){

    const buoyData = data;
    const dateFormat = d3.time.format("%Y-%m-%d %H:%M:%S");
    buoyData.forEach(d => {
      d.dd = dateFormat.parse(d.origintime);
      d.day = d3.time.day(d.dd); // pre-calculate day for better performance
      d.week = d3.time.week(d.dd);
      d.month = d3.time.month(d.dd);
      d.year = d3.time.year(d.dd);
      d.wvdp   = d3.round(+d.wvdp,1);
      //d.wvht = d3.round((+d.wvht * 3.2),1); //convert to feet
      d.wvht = d3.round((+d.wvht * 3.2)); //convert to feet
      d.wndir = +d.wndir;
    });
    return buoyData;
  }

  numberFormat(){
    return d3.format(".2f");
  }

  buildXDimensions(xwaves){
    // create dimensions (x-axis values)
    const heightDim  = xwaves.dimension(pluck("wvht"));
    const periodDim  = xwaves.dimension(pluck("wvdp"));
    const hMonthDim  = xwaves.dimension(pluck("month"));
    const pMonthDim = xwaves.dimension(pluck("month"));
    const xDims = { heightDim, periodDim, hMonthDim, pMonthDim};
    return xDims;
  }

  buildYGroups(wavesx, xDims){

    const {heightDim, periodDim, hMonthDim, pMonthDim} = xDims;

    // create groups (y-axis values)
    const heightGroup = heightDim.group();
    const periodGroup = periodDim.group();
    let hMonthGroup = hMonthDim.group();
    let pMonthGroup = pMonthDim.group();
    let hReducer = reductio();
    let pReducer = reductio();
    hReducer.count(true).sum('wvht').avg(true).min('wvht').max(true).median(true);
    pReducer.count(true).sum('wvdp').avg(true).min('wvdp').max(true).median(true);
    hReducer(hMonthGroup);
    pReducer(pMonthGroup);

    //console.log(myMonthGroup.all());
       //map reduce functions
    let yGroups = {heightGroup, periodGroup, hMonthGroup, pMonthGroup};
    return yGroups;
  }
  //end of class
}
<commit_msg>refactored and cleaned SLC<commit_after>import * as d3 from 'd3';
import {crossfilter, units, legend, lineChart, geoChoroplethChart, bubbleChart, renderAll, redrawAll, filterAll, pieChart, barChart, dataCount, dataTable, pluck, round} from 'dc';
import * as colorbrewer from "colorbrewer";
import reductio from 'reductio';
//we can call export at the top of the class declaration
export default class NOAADashDC {

  constructor(el, props = {}) {
    //we initiate charts in constructor
    this.myCharts = NOAADashDC.initCharts();
  }

  render() {
    //de-structure myCharts object
    //const {heightChart, periodChart} = this.myCharts;
    let {heightChart, periodChart, heightSLChart, periodSLChart} = this.myCharts;

    d3.csv('data/fullyear_wv_dec_cc.csv', (error, data) => {
      //format the data
      const buoyData = this.formatData(data);
      let wavesx = crossfilter(buoyData);
      // build the x dimensions
      let xDims = this.buildXDimensions(wavesx);
      //destructure the xDims object
      let {heightDim, periodDim, monthDim} = xDims;
      //build the Y groups
      let yGroups = this.buildYGroups(wavesx, xDims);
      //de-structure they yGroups object
      let {heightGroup, periodGroup, hMonthGroup, pMonthGroup} = yGroups;
      //call number format
      const numberFormat =  this.numberFormat();
      //dc.js Charts chained configuration

      heightSLChart = this.buildSLChart(heightSLChart, data, monthDim, hMonthGroup, periodSLChart, 'Height');
      periodSLChart = this.buildSLChart(periodSLChart, data, monthDim, pMonthGroup, heightSLChart, 'Period');
      this.buildHeightChart(heightChart, heightDim, heightGroup);
      this.buildPeriodChart(periodChart, periodDim, periodGroup, numberFormat);
      //draw the viz!
      renderAll();

    });
  }

  buildPeriodChart(periodChart, periodDim, periodGroup, numberFormat){
    //dc.barChart("#period-chart")
    periodChart
      .width(300)
      .height(180)
      .margins({top: 10, right: 50, bottom: 30, left: 40})
      .dimension(periodDim)
      .group(periodGroup)
      .elasticY(true)
    // (optional) whether bar should be center to its x value. Not needed for ordinal chart, :default=false
      .centerBar(true)
    // (optional) set gap between bars manually in px, :default=2
      .gap(45)
    // (optional) set filter brush rounding
      .round(round.floor)
      .x(d3.scale.linear().domain([0, 30]))
      .renderHorizontalGridLines(true)
    // customize the filter displayed in the control span
      .filterPrinter(function (filters) {
        var filter = filters[0], s = "";
        s += numberFormat(filter[0]) + "sec -> " + numberFormat(filter[1]) + "sec";
        return s;
      });
    // Customize axis
    periodChart.xAxis().tickFormat(
      function (v) { return v + "sec"; });
    periodChart.yAxis().ticks(5);

  }

  buildHeightChart(heightChart, heightDim, heightGroup){
    let numberFormat = this.numberFormat();
    heightChart
      .width(300)
      .height(180)
      .margins({top: 10, right: 50, bottom: 30, left: 40})
      .dimension(heightDim)
      .group(heightGroup)
      .elasticY(true)
    // (optional) whether bar should be center to its x value. Not needed for ordinal chart, :default=false
      .centerBar(true)
    // (optional) set gap between bars manually in px, :default=2
      .gap(65)
    // (optional) set filter brush rounding
      .round(round.floor)
      .x(d3.scale.linear().domain([0, 7]))
      .renderHorizontalGridLines(true)
    // customize the filter displayed in the control span
      .filterPrinter((filters) => {
        var filter = filters[0], s = "";
        s += numberFormat(filter[0]) + "met -> " + numberFormat(filter[1]) + "met";
        return s;
      });

    // Customize axis
    heightChart.xAxis().tickFormat((v) => {
      return v + "met";
    });
    heightChart.yAxis().ticks(5);

  }

  buildSLChart(chart, data, dim, group, range, dimension){
    chart
      .renderArea(true)
      .width(990)
      .height(200)
      .transitionDuration(1000)
      .margins({top: 30, right: 50, bottom: 25, left: 40})
      .dimension(dim)
      .mouseZoomable(true)
      .rangeChart(range)
    //.x(d3.time.scale().domain([new Date(2004, 0, 1), new Date(2012, 11, 31)]))
      .x(d3.time.scale().domain(d3.extent(data, (d) => { return d.dd; })))  //use extent to auto scale the axis
      .round(d3.time.month.round)
      .xUnits(d3.time.months)
      .elasticY(true)
      .renderHorizontalGridLines(true)
      .legend(legend().x(800).y(5).itemHeight(5).gap(10))
      .brushOn(false)
      .group(group, 'Monthly '+dimension+' Min')
      .valueAccessor((d) =>  {
          return d.value.count ? d.value.min : 0;
      })
      .stack(group, 'Monthly '+dimension+' Average', (d) => {
          return d.value.count ? d.value.avg : 0;
      })
    // Title can be called by any stack layer.
    /* .title(function (d) {
       var value = d.value.avg ? d.value.avg : d.value;
       if (isNaN(value)) {
       value = 0;
       }
       return dateFormat(d.key) + '\n' + numberFormat(value);
       });*/
      .stack(group, 'Monthly '+dimension+' Max', (d) => {
          return d.value.count ? d.value.max : 0;
      })
   return chart;
  }

  static initCharts() {
    const heightChart = barChart('#chart-height');
    const periodChart = barChart('#chart-period');
    const heightSLChart = lineChart('#chart-month-move');
    const periodSLChart = lineChart('#chart-period-stacked-line');
    const myCharts = {heightChart, periodChart, heightSLChart, periodSLChart};
    return myCharts;
  }

  resetChart(chartName) {

    let {heightChart, periodChart} = this.myCharts;

    switch (chartName) {
      case "height-chart":
        heightChart.filterAll();
        break;
      case "period-chart":
        periodChart.filterAll();
        break;
      default:
        //Statements executed when none of the values match the value of the expression
        break;
    }

    redrawAll();
  }

  formatData(data){
    const buoyData = data;
    const dateFormat = d3.time.format("%Y-%m-%d %H:%M:%S");
    buoyData.forEach(d => {
      d.dd = dateFormat.parse(d.origintime);
      d.day = d3.time.day(d.dd); // pre-calculate day for better performance
      d.week = d3.time.week(d.dd);
      d.month = d3.time.month(d.dd);
      d.year = d3.time.year(d.dd);
      d.wvdp   = d3.round(+d.wvdp,1);
      d.wvht = d3.round((+d.wvht * 3.2)); //convert to feet
      d.wndir = +d.wndir;
    });
    return buoyData;
  }

  numberFormat(){
    return d3.format(".2f");
  }

  buildXDimensions(xwaves){
    const heightDim  = xwaves.dimension(pluck("wvht"));
    const periodDim  = xwaves.dimension(pluck("wvdp"));
    const monthDim  = xwaves.dimension(pluck("month"));
    const xDims = { heightDim, periodDim, monthDim};
    return xDims;
  }

  buildYGroups(wavesx, xDims){
    const {heightDim, periodDim, monthDim} = xDims;
    const heightGroup = heightDim.group();
    const periodGroup = periodDim.group();
    let hMonthGroup = monthDim.group();
    let pMonthGroup = monthDim.group();
    let hReducer = reductio();
    let pReducer = reductio();
    hReducer.count(true).sum('wvht').avg(true).min('wvht').max(true).median(true);
    pReducer.count(true).sum('wvdp').avg(true).min('wvdp').max(true).median(true);
    hReducer(hMonthGroup);
    pReducer(pMonthGroup);
    let yGroups = {heightGroup, periodGroup, hMonthGroup, pMonthGroup};
    return yGroups;
  }
  //end of class
}
<|endoftext|>