qwc2
Version:
QGIS Web Client
10 lines • 18.7 kB
JavaScript
function _typeof(o){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(o){return typeof o}:function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},_typeof(o)}function ownKeys(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);r&&(o=o.filter(function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable})),t.push.apply(t,o)}return t}function _objectSpread(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?ownKeys(Object(t),!0).forEach(function(r){_defineProperty(e,r,t[r])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ownKeys(Object(t)).forEach(function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))})}return e}function _toConsumableArray(r){return _arrayWithoutHoles(r)||_iterableToArray(r)||_unsupportedIterableToArray(r)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArray(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}function _arrayWithoutHoles(r){if(Array.isArray(r))return _arrayLikeToArray(r)}function _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,a){if(r){if("string"==typeof r)return _arrayLikeToArray(r,a);var t={}.toString.call(r).slice(8,-1);return"Object"===t&&r.constructor&&(t=r.constructor.name),"Map"===t||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,a):void 0}}function _arrayLikeToArray(r,a){(null==a||a>r.length)&&(a=r.length);for(var e=0,n=Array(a);e<a;e++)n[e]=r[e];return n}function _iterableToArrayLimit(r,l){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var e,n,i,u,a=[],f=!0,o=!1;try{if(i=(t=t.call(r)).next,0===l){if(Object(t)!==t)return;f=!1}else for(;!(f=(e=i.call(t)).done)&&(a.push(e.value),a.length!==l);f=!0);}catch(r){o=!0,n=r}finally{try{if(!f&&null!=t["return"]&&(u=t["return"](),Object(u)!==u))return}finally{if(o)throw n}}return a}}function _arrayWithHoles(r){if(Array.isArray(r))return r}function _classCallCheck(a,n){if(!(a instanceof n))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var o=r[t];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,_toPropertyKey(o.key),o)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _callSuper(t,o,e){return o=_getPrototypeOf(o),_possibleConstructorReturn(t,_isNativeReflectConstruct()?Reflect.construct(o,e||[],_getPrototypeOf(t).constructor):o.apply(t,e))}function _possibleConstructorReturn(t,e){if(e&&("object"==_typeof(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return _assertThisInitialized(t)}function _assertThisInitialized(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function _isNativeReflectConstruct(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(_isNativeReflectConstruct=function _isNativeReflectConstruct(){return!!t})()}function _getPrototypeOf(t){return _getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},_getPrototypeOf(t)}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&_setPrototypeOf(t,e)}function _setPrototypeOf(t,e){return _setPrototypeOf=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},_setPrototypeOf(t,e)}function _defineProperty(e,r,t){return(r=_toPropertyKey(r))in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function _toPropertyKey(t){var i=_toPrimitive(t,"string");return"symbol"==_typeof(i)?i:i+""}function _toPrimitive(t,r){if("object"!=_typeof(t)||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var i=e.call(t,r||"default");if("object"!=_typeof(i))return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===r?String:Number)(t)}/**
* Copyright 2024 Sourcepole AG
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/import React from"react";import{connect}from"react-redux";import dayjs from"dayjs";import PropTypes from"prop-types";import randomcolor from"randomcolor";import{addLayerFeatures,removeLayer,LayerRole}from"../../actions/layers";import LocaleUtils from"../../utils/LocaleUtils";import MiscUtils from"../../utils/MiscUtils";import Input from"../widgets/Input";import Spinner from"../widgets/Spinner";import"./style/TimelineFeaturesSlider.css";var TimelineFeaturesSlider=/*#__PURE__*/function(_React$Component){function TimelineFeaturesSlider(){var _this;_classCallCheck(this,TimelineFeaturesSlider);for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}_this=_callSuper(this,TimelineFeaturesSlider,[].concat(args));_defineProperty(_this,"state",{currentTimestampDrag:null,highlightFeatures:null,layerClassifications:{},layerAttrGroups:{}});_defineProperty(_this,"renderCursor",function(timestamp){if(_this.props.timeEnabled){var cursorPos=_this.state.currentTimestampDrag?_this.state.currentTimestampDrag.pos:_this.props.computePixelFromTime(timestamp);var cursorStyle={left:cursorPos-2+"px"};return/*#__PURE__*/React.createElement("div",{className:"timeline-slider-cursor",style:cursorStyle},/*#__PURE__*/React.createElement("div",{className:"timeline-slider-cursor-label"},_this.props.cursorFormat.includes("date")?/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(Input,{onChange:_this.setCursorDate,required:true,type:"date",value:dayjs(timestamp).format("YYYY-MM-DD")})):null,_this.props.cursorFormat.includes("time")?/*#__PURE__*/React.createElement("div",null,/*#__PURE__*/React.createElement(Input,{onChange:_this.setCursorTime,required:true,type:"time",value:dayjs(timestamp).format("HH:mm:ss")})):null))}return null});_defineProperty(_this,"setCursorDate",function(date){if(date){var newdate=dayjs(date,"YYYY-MM-DD");_this.props.timestampChanged(+dayjs(_this.props.currentTimestamp).year(newdate.year()).month(newdate.month()).date(newdate.date()))}});_defineProperty(_this,"setCursorTime",function(time){if(time){var parts=time.split(":").map(function(x){return parseInt(x,10)});_this.props.timestampChanged(+dayjs(_this.props.currentTimestamp).hour(parts[0]).minute(parts[1]).second(parts[2]))}});_defineProperty(_this,"pickCurrentTimestamp",function(event){if(["INPUT","SELECT","OPTION"].includes(event.target.nodeName)){return}clearTimeout(_this.timestampChangeTimeout);var target=event.currentTarget;var rect=target.getBoundingClientRect();var computeTimestamp=function computeTimestamp(ev){if(!_this.props.timeEnabled){return}var pos=Math.max(0,Math.min(ev.clientX-rect.left,rect.right-rect.left));var newTimestamp=dayjs(_this.props.computeTimeFromPixel(pos));// Snap to configured step interval
var add=null;if(_this.props.stepSizeUnit.endsWith("m")){add=newTimestamp.second()>30;newTimestamp=newTimestamp.second(0)}else if(_this.props.stepSizeUnit.endsWith("h")){add=newTimestamp.minute()>30;newTimestamp=newTimestamp.second(0).minute(0)}else if(_this.props.stepSizeUnit.endsWith("d")){add=newTimestamp.hour()>12;newTimestamp=newTimestamp.second(0).minute(0).hour(0)}else if(_this.props.stepSizeUnit.endsWith("M")){add=newTimestamp.date()>15;newTimestamp=newTimestamp.second(0).minute(0).hour(0).date(1)}else if(_this.props.stepSizeUnit.endsWith("y")){add=newTimestamp.month()>5;newTimestamp=newTimestamp.second(0).minute(0).hour(0).date(1).month(0)}if(add){var num=parseInt(_this.props.stepSizeUnit.slice(0,-1),10)||1;newTimestamp=newTimestamp.add(num,_this.props.stepSizeUnit.slice(-1))}_this.setState({currentTimestampDrag:{pos:pos,time:newTimestamp}})};document.addEventListener("pointermove",computeTimestamp);document.addEventListener("pointerup",function(){if(_this.state.currentTimestampDrag){_this.props.timestampChanged(+_this.state.currentTimestampDrag.time);_this.setState({currentTimestampDrag:null})}document.removeEventListener("pointermove",computeTimestamp)},{once:true,capture:true});computeTimestamp(event)});_defineProperty(_this,"renderTimeFeatures",function(sliderGeom){return Object.entries(_this.props.timeFeatures.features).map(function(_ref){var _ref2=_slicedToArray(_ref,2),layer=_ref2[0],features=_ref2[1];var layerTitleStyle={top:sliderGeom.top+"px",left:0,right:0};sliderGeom.top+=30;var classattr=(_this.state.layerClassifications[layer]||{}).attr||"";var groupattr=(_this.state.layerAttrGroups[layer]||{}).attr||"";var sliderFeatures=null;if(_this.state.layerAttrGroups[layer]){var layerAttrGroups=_this.state.layerAttrGroups[layer];sliderFeatures=Object.values(layerAttrGroups.groups).map(function(groupData){return _this.renderTimeFeature(sliderGeom,groupData.start,groupData.end,groupData.features,"",groupattr,groupData)})}else{var layerAttrClasses=_this.state.layerClassifications[layer];sliderFeatures=features.map(function(feature){var attrData=layerAttrClasses?layerAttrClasses.classes[feature.properties[layerAttrClasses.attr]]:null;var tstart=feature.properties.__startdate;var tend=feature.properties.__enddate;var label=feature.properties[feature.displayfield];return _this.renderTimeFeature(sliderGeom,tstart,tend,[feature],label,classattr,attrData)})}return[/*#__PURE__*/React.createElement("div",{className:"timeline-slider-layertitle",key:layer,style:layerTitleStyle},/*#__PURE__*/React.createElement("span",null,layer),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("timemanager.group"),":\xA0"),/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setGroupAttr(layer,ev.target.value)},value:groupattr},/*#__PURE__*/React.createElement("option",{value:""},LocaleUtils.tr("timemanager.groupnone")),_this.props.timeFeatures.attributes[layer].map(function(attr){return/*#__PURE__*/React.createElement("option",{key:attr,value:attr},attr)})),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("timemanager.classify"),":\xA0"),/*#__PURE__*/React.createElement("select",{onChange:function onChange(ev){return _this.setClassification(layer,ev.target.value)},value:classattr},/*#__PURE__*/React.createElement("option",{value:""},LocaleUtils.tr("timemanager.classifynone")),_this.props.timeFeatures.attributes[layer].map(function(attr){return/*#__PURE__*/React.createElement("option",{key:attr,value:attr},attr)}))),sliderFeatures]})});_defineProperty(_this,"renderTimeLayers",function(sliderGeom){return Object.entries(_this.props.timeFeatures.features).reduce(function(res,_ref3){var _ref4=_slicedToArray(_ref3,2),layer=_ref4[0],features=_ref4[1];if(features.length>0){var tstart=features[0].properties.__startdate;var tend=features[0].properties.__enddate;for(var i=1;i<features.length;++i){if(features[i].properties.__startdate<tstart){tstart=features[i].properties.__startdate}if(features[i].properties.__enddate>tend){tend=features[i].properties.__enddate}}return[].concat(_toConsumableArray(res),[_this.renderTimeFeature(sliderGeom,tstart,tend,features,layer)])}return res},[])});_defineProperty(_this,"renderTimeFeature",function(sliderGeom,tstart,tend,features,label,attr,featClass){var left=tstart.isValid()?_this.props.computePixelFromTime(tstart):0;var right=tend.isValid()?_this.props.computePixelFromTime(tend):0;var style={top:sliderGeom.top+"px",left:left+"px"};if(tend.isValid()){style.width=right-left+"px"}else{style.right=0}var tooltip=LocaleUtils.tr("timemanager.starttime")+": "+(tstart.isValid()?tstart.format(_this.props.dateFormat):"-")+"\n"+LocaleUtils.tr("timemanager.endtime")+": "+(tend.isValid()?tend.format(_this.props.dateFormat):"-");if(featClass){style.backgroundColor=featClass.bg;style.color=featClass.fg;label+=(label?": ":"")+featClass.val;tooltip+="\n"+attr+": "+featClass.val}sliderGeom.top+=26;return/*#__PURE__*/React.createElement("div",{className:"timeline-slider-feature",key:features[0].id,onMouseEnter:function onMouseEnter(){return _this.setState({highlightFeatures:features})},onMouseLeave:function onMouseLeave(){return _this.setState({highlightFeatures:null})},style:style,title:tooltip},/*#__PURE__*/React.createElement("span",null,label))});_defineProperty(_this,"renderGradient",function(sliderGeom){if(!_this.props.markersEnabled){return null}var left=_this.props.computePixelFromTime(_this.props.startTime);var right=_this.props.computePixelFromTime(_this.props.endTime);var style={left:left+"px",width:right-left+"px",height:sliderGeom.top+"px",background:"linear-gradient(90deg, "+_this.props.markerConfiguration.gradient.join(", ")+")"};return/*#__PURE__*/React.createElement("div",{className:"timeline-slider-gradient",style:style})});_defineProperty(_this,"setClassification",function(layer,attr){_this.setState(function(state){var newLayerClassifications=_objectSpread({},state.layerClassifications);if(attr){var classes={};_this.props.timeFeatures.features[layer].forEach(function(feature){if(!classes[feature.properties[attr]]){var color=randomcolor();classes[feature.properties[attr]]={bg:color,fg:MiscUtils.isBrightColor(color)?"#000":"#FFF",val:feature.properties[attr]}}});newLayerClassifications[layer]={attr:attr,classes:classes}}else{delete newLayerClassifications[layer]}// Attr classification and grouping cannot be enabled at the same time
var newLayerAttrGroups=_objectSpread({},state.layerAttrGroups);delete newLayerAttrGroups[layer];return{layerClassifications:newLayerClassifications,layerAttrGroups:newLayerAttrGroups}})});_defineProperty(_this,"setGroupAttr",function(layer,attr){_this.setState(function(state){var newLayerAttrGroups=_objectSpread({},state.layerAttrGroups);if(attr){var groups={};_this.props.timeFeatures.features[layer].forEach(function(feature){if(!groups[feature.properties[attr]]){var color=randomcolor();groups[feature.properties[attr]]={bg:color,fg:MiscUtils.isBrightColor(color)?"#000":"#FFF",val:feature.properties[attr],features:[feature],start:feature.properties.__startdate,end:feature.properties.__enddate}}else{if(feature.properties.__startdate<groups[feature.properties[attr]].start){groups[feature.properties[attr]].start=feature.properties.__startdate}if(feature.properties.__enddate>groups[feature.properties[attr]].end){groups[feature.properties[attr]].end=feature.properties.__enddate}groups[feature.properties[attr]].features.push(feature)}});newLayerAttrGroups[layer]={attr:attr,groups:groups}}else{delete newLayerAttrGroups[layer]}// Attr classification and grouping cannot be enabled at the same time
var newLayerClassifications=_objectSpread({},state.layerClassifications);delete newLayerClassifications[layer];return{layerClassifications:newLayerClassifications,layerAttrGroups:newLayerAttrGroups}})});return _this}_inherits(TimelineFeaturesSlider,_React$Component);return _createClass(TimelineFeaturesSlider,[{key:"componentDidUpdate",value:function componentDidUpdate(prevProps,prevState){var _this2=this;if(this.state.highlightFeatures!==prevState.highlightFeatures){if(!this.state.highlightFeatures){this.props.removeLayer("timelinefeathighlight")}else{var layer={id:"timelinefeathighlight",role:LayerRole.MARKER,rev:+new Date};this.props.addLayerFeatures(layer,this.state.highlightFeatures,true)}}if(this.props.timeFeatures!==prevProps.timeFeatures){var newLayerClassifications=_objectSpread({},this.state.layerClassifications);Object.keys(this.state.layerClassifications).forEach(function(layername){if(!_this2.props.timeFeatures.attributes[layername]||_this2.props.timeFeatures.attributes[layername]!==prevProps.timeFeatures.attributes[layername]){delete newLayerClassifications.layername}});this.setState(function(state){var newLayerAttrGroups=_objectSpread({},state.layerAttrGroups);Object.keys(state.layerAttrGroups).forEach(function(layername){if(!_this2.props.timeFeatures.attributes[layername]||_this2.props.timeFeatures.attributes[layername]!==prevProps.timeFeatures.attributes[layername]){delete newLayerAttrGroups.layername}});return{layerAttrGroups:newLayerAttrGroups}})}}},{key:"render",value:function render(){var timestamp=this.state.currentTimestampDrag?this.state.currentTimestampDrag.time:this.props.currentTimestamp;var sliderGeom={top:5};return/*#__PURE__*/React.createElement("div",{className:"timeline-slider-container"},/*#__PURE__*/React.createElement("div",{className:"timeline-slider",onPointerDown:this.pickCurrentTimestamp},this.props.displayMode==="features"?this.renderTimeFeatures(sliderGeom):null,this.props.displayMode==="layers"?this.renderTimeLayers(sliderGeom):null,this.renderGradient(sliderGeom)),this.renderCursor(timestamp),this.props.timeFeatures.pendingRequests>0?/*#__PURE__*/React.createElement("div",{className:"timeline-slider-loading"},/*#__PURE__*/React.createElement(Spinner,null),/*#__PURE__*/React.createElement("span",null,LocaleUtils.tr("timemanager.loading"))):null)}}])}(React.Component);_defineProperty(TimelineFeaturesSlider,"propTypes",{addLayerFeatures:PropTypes.func,computePixelFromTime:PropTypes.func,computeTimeFromPixel:PropTypes.func,currentTimestamp:PropTypes.number,cursorFormat:PropTypes.string,dateFormat:PropTypes.string,displayMode:PropTypes.string,endTime:PropTypes.object,markerConfiguration:PropTypes.object,markersEnabled:PropTypes.bool,removeLayer:PropTypes.func,startTime:PropTypes.object,stepSizeUnit:PropTypes.string,timeEnabled:PropTypes.bool,timeFeatures:PropTypes.object,timestampChanged:PropTypes.func});export default connect(function(){return{}},{addLayerFeatures:addLayerFeatures,removeLayer:removeLayer})(TimelineFeaturesSlider);