histomicsui 1.4.2.dev30__tar.gz → 1.4.2.dev32__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {histomicsui-1.4.2.dev30/histomicsui.egg-info → histomicsui-1.4.2.dev32}/PKG-INFO +1 -1
- histomicsui-1.4.2.dev32/histomicsui/web_client/dialogs/saveAnnotation.js +528 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/AnnotationSelector.js +4 -6
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/DrawWidget.js +0 -1
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/dialogs/saveAnnotation.styl +8 -0
- histomicsui-1.4.2.dev32/histomicsui/web_client/templates/dialogs/saveAnnotation.pug +108 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32/histomicsui.egg-info}/PKG-INFO +1 -1
- histomicsui-1.4.2.dev30/histomicsui/web_client/dialogs/saveAnnotation.js +0 -209
- histomicsui-1.4.2.dev30/histomicsui/web_client/templates/dialogs/saveAnnotation.pug +0 -61
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/.circleci/config.yml +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/.editorconfig +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/.gitignore +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/.travis.yml +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/LICENSE +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/MANIFEST.in +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/NOTICE +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/README.rst +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/codecov.yml +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/docs/config_options.rst +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/docs/controls.rst +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/docs/images/difference.gif +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/docs/images/intersect.gif +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/docs/images/union.gif +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/docs/images/xor.gif +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/__init__.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/constants.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/handlers.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/__init__.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/aperio.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/case.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/cohort.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/image.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/meta.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/pathology.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/models/slide.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/rest/__init__.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/rest/aperio.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/rest/hui_resource.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/rest/image_browse_resource.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/rest/system.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/rest/tcga.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/app.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/collections/StyleCollection.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/collections/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/confirmDialog.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/editElement.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/editRegionOfInterest.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/editStyleGroups.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/metadataPlot.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/openAnnotatedImage.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/dialogs/openImage.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/events.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/main.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/models/StyleModel.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/models/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/package.json +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/MetadataPlot.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/MetadataWidget.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/OverviewWidget.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/RegionSelector.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/ZoomWidget.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/panels/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/router.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/routes.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/static/favicon.png +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/body/configView.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/body/frontPage.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/body/image.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/dialogs/editStyleGroups.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/dialogs/openAnnotatedImage.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/layout/header.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/layout/headerAnalyses.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/layout/headerImage.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/layout/layout.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/annotationSelector.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/drawWidget.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/metadataPlot.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/metadataWidget.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/overviewWidget.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/regionSelector.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/panels/zoomWidget.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/popover/annotationContextMenu.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/popover/annotationPopover.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/stylesheets/views/itemList.styl +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/body/configView.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/body/frontPage.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/body/image.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/annotatedImageList.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/confirmDialog.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/editElement.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/editRegionOfInterest.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/editStyleGroups.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/metadataPlot.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/openAnnotatedImage.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/dialogs/openImage.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/layout/header.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/layout/headerAnalyses.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/layout/headerImage.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/layout/headerUser.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/layout/layout.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/annotationSelector.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/drawWidget.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/drawWidgetElement.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/metadataPlot.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/metadataWidget.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/overviewWidget.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/panel.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/regionSelector.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/panels/zoomWidget.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/popover/annotationContextMenu.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/popover/annotationPopover.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/templates/popover/pixelmapContextMenu.pug +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/HierarchyWidget.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/View.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/body/ConfigView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/body/FrontPageView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/body/ImageView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/body/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/itemList.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/itemPage.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/layout/HeaderAnalysesView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/layout/HeaderImageView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/layout/HeaderUserView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/layout/HeaderView.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/layout/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/popover/AnnotationContextMenu.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/popover/AnnotationPopover.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/popover/PixelmapContextMenu.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/popover/index.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/views/utils.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/vue/components/ColorPickerInput.vue +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/vue/components/EditHeatmapOrGridData.vue +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/vue/components/EditHeatmapOrGridDataContainer.vue +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/web_client/webpack.helper.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui/webroot.mako +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui.egg-info/SOURCES.txt +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui.egg-info/dependency_links.txt +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui.egg-info/entry_points.txt +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui.egg-info/not-zip-safe +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui.egg-info/requires.txt +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/histomicsui.egg-info/top_level.txt +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/requirements-dev.txt +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/setup.cfg +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/setup.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/__init__.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/datastore.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/girder_utilities.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_files/.histomicsui_config.yaml +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_files/sample.anot +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_files/sample.meta +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_files/sample_girder_id.anot +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_files/test_analysis_detection.xml +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_files/test_analysis_features.xml +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_handlers.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_hui_rest.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_image_browse_endpoints.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_load.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_tcga.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/test_web_client.py +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/.eslintrc +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/analysisSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/annotationSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/girderUISpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/huiSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/huiTest.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/itemSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/metadataPanelSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/metadataPlotSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/overviewPanelSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/panelLayoutSpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tests/web_client_specs/pixelmapCategorySpec.js +0 -0
- {histomicsui-1.4.2.dev30 → histomicsui-1.4.2.dev32}/tox.ini +0 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import _ from 'underscore';
|
|
2
|
+
import $ from 'jquery';
|
|
3
|
+
import tinycolor from 'tinycolor2';
|
|
4
|
+
|
|
5
|
+
import { AccessType } from '@girder/core/constants';
|
|
6
|
+
import { formatDate, DATE_SECOND } from '@girder/core/misc';
|
|
7
|
+
import AccessWidget from '@girder/core/views/widgets/AccessWidget';
|
|
8
|
+
// import MetadataWidget from '@girder/core/views/widgets/MetadataWidget';
|
|
9
|
+
import View from '@girder/core/views/View';
|
|
10
|
+
|
|
11
|
+
import MetadataWidget from '../panels/MetadataWidget';
|
|
12
|
+
import '../stylesheets/dialogs/saveAnnotation.styl';
|
|
13
|
+
import saveAnnotation from '../templates/dialogs/saveAnnotation.pug';
|
|
14
|
+
import { elementAreaAndEdgeLength } from '../views/utils';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Collect styleable properties from user parameters in elements.
|
|
18
|
+
*
|
|
19
|
+
* @param {object} styleableFuncs An object with distinct keys for functions.
|
|
20
|
+
* Modified.
|
|
21
|
+
* @param {array} elements A list of elements which might contain metadata
|
|
22
|
+
* properties in the user key.
|
|
23
|
+
* @param {array} [root] A list of keys within objects in an element.
|
|
24
|
+
*/
|
|
25
|
+
function collectStyleableProps(styleableFuncs, elements, root) {
|
|
26
|
+
const maxCategories = 20;
|
|
27
|
+
|
|
28
|
+
let children = {};
|
|
29
|
+
root = root || [];
|
|
30
|
+
let key = 'user';
|
|
31
|
+
for (let j = 0; j < root.length; j += 1) {
|
|
32
|
+
key += '.' + root[j];
|
|
33
|
+
}
|
|
34
|
+
for (let i = 0; i < elements.length; i += 1) {
|
|
35
|
+
let proplist = elements[i].user;
|
|
36
|
+
for (let j = 0; j < root.length; j += 1) {
|
|
37
|
+
if (proplist) {
|
|
38
|
+
proplist = proplist[root[j]];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (proplist !== undefined && proplist !== null) {
|
|
42
|
+
if (proplist.substring || (proplist.toFixed && _.isFinite(proplist))) {
|
|
43
|
+
if (styleableFuncs[key] === undefined) {
|
|
44
|
+
styleableFuncs[key] = {
|
|
45
|
+
root: root,
|
|
46
|
+
key: key,
|
|
47
|
+
name: root.map((k) => k.replace('_', ' ')).join(' - '),
|
|
48
|
+
categoric: !proplist.toFixed
|
|
49
|
+
};
|
|
50
|
+
styleableFuncs[key].values = [proplist];
|
|
51
|
+
if (!styleableFuncs[key].categoric) {
|
|
52
|
+
styleableFuncs[key].min = styleableFuncs[key].max = +proplist;
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
if (styleableFuncs[key].values.length <= maxCategories) {
|
|
56
|
+
if (styleableFuncs[key].values.indexOf(proplist) < 0) {
|
|
57
|
+
if (styleableFuncs[key].values.length >= maxCategories) {
|
|
58
|
+
styleableFuncs[key].manyValues = true;
|
|
59
|
+
} else {
|
|
60
|
+
styleableFuncs[key].values.push(proplist);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!styleableFuncs[key].categoric) {
|
|
65
|
+
const val = +proplist;
|
|
66
|
+
if (val < styleableFuncs[key].min) {
|
|
67
|
+
styleableFuncs[key].min = val;
|
|
68
|
+
}
|
|
69
|
+
if (val > styleableFuncs[key].max) {
|
|
70
|
+
styleableFuncs[key].max = val;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
Object.keys(proplist).forEach((subkey) => {
|
|
76
|
+
children[subkey] = true;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
Object.keys(children).forEach((subkey) => {
|
|
82
|
+
let subroot = root.slice();
|
|
83
|
+
subroot.push(subkey);
|
|
84
|
+
collectStyleableProps(styleableFuncs, elements, subroot);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Calculate the min/max values for calculated properties.
|
|
90
|
+
*
|
|
91
|
+
* @param {object} styleableFuncs An object with distinct keys for functions.
|
|
92
|
+
* Modified.
|
|
93
|
+
* @param {array} elements A list of elements which might contain metadata
|
|
94
|
+
* properties in the user key.
|
|
95
|
+
*/
|
|
96
|
+
function rangeStyleableProps(styleableFuncs, elements) {
|
|
97
|
+
let needsArea = true;
|
|
98
|
+
Object.entries(styleableFuncs).forEach(([key, func]) => {
|
|
99
|
+
if (['perimeter', 'area', 'length'].indexOf(key) >= 0) {
|
|
100
|
+
needsArea = true;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (!func.calc) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
for (let i = 0; i < elements.length; i += 1) {
|
|
107
|
+
let d = elements[i];
|
|
108
|
+
if (d[key] !== undefined) {
|
|
109
|
+
if (func.min === undefined) {
|
|
110
|
+
func.min = func.max = d[key];
|
|
111
|
+
}
|
|
112
|
+
if (d[key] < func.min) {
|
|
113
|
+
func.min = d[key];
|
|
114
|
+
}
|
|
115
|
+
if (d[key] > func.max) {
|
|
116
|
+
func.max = d[key];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
if (needsArea) {
|
|
122
|
+
for (let i = 0; i < elements.length; i += 1) {
|
|
123
|
+
let element = elements[i];
|
|
124
|
+
const { area, edge } = elementAreaAndEdgeLength({el: element});
|
|
125
|
+
if (styleableFuncs.area && area) {
|
|
126
|
+
if (styleableFuncs.area.min === undefined) {
|
|
127
|
+
styleableFuncs.area.min = styleableFuncs.area.max = area;
|
|
128
|
+
styleableFuncs.area.values = new Array(elements.length);
|
|
129
|
+
}
|
|
130
|
+
styleableFuncs.area.values[i] = area;
|
|
131
|
+
if (area < styleableFuncs.area.min) {
|
|
132
|
+
styleableFuncs.area.min = area;
|
|
133
|
+
}
|
|
134
|
+
if (area > styleableFuncs.area.max) {
|
|
135
|
+
styleableFuncs.area.max = area;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (styleableFuncs.length && edge) {
|
|
139
|
+
if (styleableFuncs.length.min === undefined) {
|
|
140
|
+
styleableFuncs.length.min = styleableFuncs.length.max = edge;
|
|
141
|
+
styleableFuncs.length.values = new Array(elements.length);
|
|
142
|
+
}
|
|
143
|
+
styleableFuncs.length.values[i] = edge;
|
|
144
|
+
if (edge < styleableFuncs.length.min) {
|
|
145
|
+
styleableFuncs.length.min = edge;
|
|
146
|
+
}
|
|
147
|
+
if (edge > styleableFuncs.length.max) {
|
|
148
|
+
styleableFuncs.length.max = edge;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (styleableFuncs.perimeter && edge) {
|
|
152
|
+
if (styleableFuncs.perimeter.min === undefined) {
|
|
153
|
+
styleableFuncs.perimeter.min = styleableFuncs.perimeter.max = edge;
|
|
154
|
+
styleableFuncs.perimeter.values = new Array(elements.perimeter);
|
|
155
|
+
}
|
|
156
|
+
styleableFuncs.perimeter.values[i] = edge;
|
|
157
|
+
if (edge < styleableFuncs.perimeter.min) {
|
|
158
|
+
styleableFuncs.perimeter.min = edge;
|
|
159
|
+
}
|
|
160
|
+
if (edge > styleableFuncs.perimeter.max) {
|
|
161
|
+
styleableFuncs.perimeter.max = edge;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Given an element and a color function, compute the color needed.
|
|
170
|
+
*
|
|
171
|
+
* @param {elementModel} element The element for which to compute a color
|
|
172
|
+
* @param {number} idx The index in the element collection
|
|
173
|
+
* @param {object} colorParam A functioon record with prepared min, max,
|
|
174
|
+
* range, minColor, and maxColor values.
|
|
175
|
+
* @param {object} funcInfo Information about the function. If calc is true,
|
|
176
|
+
* values is an array of precomputed values. Otherwise, root is an
|
|
177
|
+
* attribute path in the element user object.
|
|
178
|
+
* @returns {string} A color string.
|
|
179
|
+
*/
|
|
180
|
+
function colorFromFunc(element, idx, colorParam, funcInfo) {
|
|
181
|
+
const geo = window.geo;
|
|
182
|
+
let val;
|
|
183
|
+
if (funcInfo.calc) {
|
|
184
|
+
val = funcInfo.values[idx];
|
|
185
|
+
} else {
|
|
186
|
+
val = element.get('user');
|
|
187
|
+
for (let i = 0; i < funcInfo.root.length; i += 1) {
|
|
188
|
+
val = (val || {})[funcInfo.root[i]];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (!_.isFinite(val)) {
|
|
192
|
+
return 'rgba(0,0,0,0)';
|
|
193
|
+
}
|
|
194
|
+
val = Math.max(Math.min((val - colorParam.min) / colorParam.range, 1), 0);
|
|
195
|
+
if (colorParam.minColor.a === undefined) {
|
|
196
|
+
colorParam.minColor.a = 1;
|
|
197
|
+
}
|
|
198
|
+
if (colorParam.maxColor.a === undefined) {
|
|
199
|
+
colorParam.maxColor.a = 1;
|
|
200
|
+
}
|
|
201
|
+
let clr = {
|
|
202
|
+
r: val * (colorParam.maxColor.r - colorParam.minColor.r) + colorParam.minColor.r,
|
|
203
|
+
g: val * (colorParam.maxColor.g - colorParam.minColor.g) + colorParam.minColor.g,
|
|
204
|
+
b: val * (colorParam.maxColor.b - colorParam.minColor.b) + colorParam.minColor.b,
|
|
205
|
+
a: val * (colorParam.maxColor.a - colorParam.minColor.a) + colorParam.minColor.a
|
|
206
|
+
};
|
|
207
|
+
return geo.util.convertColorToRGBA(clr);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Create a modal dialog with fields to edit the properties of
|
|
212
|
+
* an annotation before POSTing it to the server.
|
|
213
|
+
*/
|
|
214
|
+
var SaveAnnotation = View.extend({
|
|
215
|
+
events: {
|
|
216
|
+
'click .h-access': 'access',
|
|
217
|
+
'click .h-cancel': 'cancel',
|
|
218
|
+
|
|
219
|
+
'input #h-annotation-fill-color': () => $('.h-functional-value #h-annotation-fill-color-fixed').prop('checked', true),
|
|
220
|
+
'changeColor #h-annotation-colorpicker-fill-color': () => $('.h-functional-value #h-annotation-fill-color-fixed').prop('checked', true),
|
|
221
|
+
'change #h-annotation-fill-color-func-list': 'changeFillColorFunc',
|
|
222
|
+
'input #h-annotation-fill-color-min-val': () => $('.h-functional-value #h-annotation-fill-color-min-setval').prop('checked', true),
|
|
223
|
+
'input #h-annotation-fill-color-max-val': () => $('.h-functional-value #h-annotation-fill-color-max-setval').prop('checked', true),
|
|
224
|
+
|
|
225
|
+
'input #h-annotation-line-color': () => $('.h-functional-value #h-annotation-line-color-fixed').prop('checked', true),
|
|
226
|
+
'changeColor #h-annotation-colorpicker-line-color': () => $('.h-functional-value #h-annotation-line-color-fixed').prop('checked', true),
|
|
227
|
+
'change #h-annotation-line-color-func-list': 'changeLineColorFunc',
|
|
228
|
+
'input #h-annotation-line-color-min-val': () => $('.h-functional-value #h-annotation-line-color-min-setval').prop('checked', true),
|
|
229
|
+
'input #h-annotation-line-color-max-val': () => $('.h-functional-value #h-annotation-line-color-max-setval').prop('checked', true),
|
|
230
|
+
|
|
231
|
+
'submit form': 'save'
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
render() {
|
|
235
|
+
// clean up old colorpickers when rerendering
|
|
236
|
+
this.$('.h-colorpicker').colorpicker('destroy');
|
|
237
|
+
|
|
238
|
+
let elementTypes = [];
|
|
239
|
+
if (this.annotation.get('annotation').elements) {
|
|
240
|
+
elementTypes = this.annotation.get('annotation').elements
|
|
241
|
+
.map((element) => element.type === 'polyline' ? (element.closed ? 'polygon' : 'line') : element.type)
|
|
242
|
+
.filter((type, index, types) => types.indexOf(type) === index);
|
|
243
|
+
}
|
|
244
|
+
// should be updated when additional shape elements are supported
|
|
245
|
+
const elementTypeProps = {
|
|
246
|
+
point: [],
|
|
247
|
+
polygon: ['perimeter', 'area'],
|
|
248
|
+
line: ['length'],
|
|
249
|
+
rectangle: ['perimeter', 'area', 'width', 'height', 'rotation'],
|
|
250
|
+
arrow: ['length'],
|
|
251
|
+
circle: ['perimeter', 'area', 'radius'],
|
|
252
|
+
ellipse: ['perimeter', 'area', 'width', 'height', 'rotation']
|
|
253
|
+
};
|
|
254
|
+
const annotationHasEditableElements = _.filter(elementTypes, (type) => elementTypeProps[type] !== undefined).length > 0;
|
|
255
|
+
const showStyleEditor = this.annotation.get('annotation').elements && !this.annotation._pageElements && annotationHasEditableElements;
|
|
256
|
+
|
|
257
|
+
const defaultStyles = {};
|
|
258
|
+
|
|
259
|
+
const styleableFuncs = {};
|
|
260
|
+
if (showStyleEditor) {
|
|
261
|
+
let scale;
|
|
262
|
+
if (this.options.viewer && this.options.viewer._scale) {
|
|
263
|
+
scale = this.options.viewer._scale.scale;
|
|
264
|
+
}
|
|
265
|
+
elementTypes.forEach((type) => {
|
|
266
|
+
(elementTypeProps[type] || []).forEach((key) => {
|
|
267
|
+
styleableFuncs[key] = {calc: true, key: key, scale: scale, name: key};
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
const elements = this.annotation.get('annotation').elements;
|
|
271
|
+
rangeStyleableProps(styleableFuncs, elements);
|
|
272
|
+
collectStyleableProps(styleableFuncs, elements.filter((d) => d.user));
|
|
273
|
+
const firstElement = elements[0];
|
|
274
|
+
if (elements.every((d) => d.lineWidth === firstElement.lineWidth)) {
|
|
275
|
+
defaultStyles.lineWidth = firstElement.lineWidth;
|
|
276
|
+
}
|
|
277
|
+
if (elements.every((d) => d.lineColor === firstElement.lineColor)) {
|
|
278
|
+
defaultStyles.lineColor = firstElement.lineColor;
|
|
279
|
+
}
|
|
280
|
+
if (elements.every((d) => d.fillColor === firstElement.fillColor)) {
|
|
281
|
+
defaultStyles.fillColor = firstElement.fillColor;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
this._showStyleEditor = showStyleEditor;
|
|
285
|
+
this._styleableFuncs = styleableFuncs;
|
|
286
|
+
|
|
287
|
+
let _styleFuncs;
|
|
288
|
+
if (this.annotation.attributes.annotation.attributes) {
|
|
289
|
+
_styleFuncs = this.annotation.attributes.annotation.attributes._styleFuncs;
|
|
290
|
+
}
|
|
291
|
+
if (!_styleFuncs || !_styleFuncs.lineColor || !_styleFuncs.fillColor || !_styleFuncs.lineWidth) {
|
|
292
|
+
_styleFuncs = {lineColor: {}, lineWidth: {}, fillColor: {}};
|
|
293
|
+
}
|
|
294
|
+
this.annotation._styleFuncs = _styleFuncs;
|
|
295
|
+
|
|
296
|
+
this.$el.html(
|
|
297
|
+
saveAnnotation({
|
|
298
|
+
title: this.options.title,
|
|
299
|
+
hasAdmin: this.annotation.get('_accessLevel') >= AccessType.ADMIN,
|
|
300
|
+
annotation: this.annotation.toJSON().annotation,
|
|
301
|
+
model: this.annotation,
|
|
302
|
+
formatDate: formatDate,
|
|
303
|
+
DATE_SECOND: DATE_SECOND,
|
|
304
|
+
showStyleEditor,
|
|
305
|
+
styleableFuncs,
|
|
306
|
+
styleFuncs: this.annotation._styleFuncs,
|
|
307
|
+
defaultStyles
|
|
308
|
+
})
|
|
309
|
+
).girderModal(this);
|
|
310
|
+
this.$('.h-colorpicker').colorpicker();
|
|
311
|
+
|
|
312
|
+
if (this.annotation.id) {
|
|
313
|
+
if (!this.annotation.meta) {
|
|
314
|
+
this.annotation._meta = Object.assign({}, (this.annotation.get('annotation') || {}).attributes || {});
|
|
315
|
+
delete this.annotation._meta._styleFuncs;
|
|
316
|
+
}
|
|
317
|
+
// copy the metadata to a place that is expected for the widget
|
|
318
|
+
if (!this.metadataWidget) {
|
|
319
|
+
this.metadataWidget = new MetadataWidget({
|
|
320
|
+
item: this.annotation,
|
|
321
|
+
parentView: this,
|
|
322
|
+
fieldName: '_meta',
|
|
323
|
+
accessLevel: this.annotation.get('_accessLevel'),
|
|
324
|
+
panel: false,
|
|
325
|
+
noSave: true
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
this.metadataWidget.setItem(this.annotation);
|
|
329
|
+
this.metadataWidget.accessLevel = this.annotation.get('_accessLevel');
|
|
330
|
+
this.metadataWidget.setElement(this.$('.hui-annotation-metadata')).render();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
this.$el.find('.modal-dialog').addClass('hui-save-annotation-dialog');
|
|
334
|
+
this._updateFuncValues();
|
|
335
|
+
return this;
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
access(evt) {
|
|
339
|
+
evt.preventDefault();
|
|
340
|
+
this.annotation.off('g:accessListSaved');
|
|
341
|
+
new AccessWidget({
|
|
342
|
+
el: $('#g-dialog-container'),
|
|
343
|
+
type: 'annotation',
|
|
344
|
+
hideRecurseOption: true,
|
|
345
|
+
parentView: this,
|
|
346
|
+
model: this.annotation,
|
|
347
|
+
noAccessFlag: true
|
|
348
|
+
}).on('g:accessListSaved', () => {
|
|
349
|
+
this.annotation.fetch();
|
|
350
|
+
});
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
cancel(evt) {
|
|
354
|
+
if (this.annotation) {
|
|
355
|
+
delete this.annotation._meta;
|
|
356
|
+
delete this.annotation._styleFuncs;
|
|
357
|
+
}
|
|
358
|
+
evt.preventDefault();
|
|
359
|
+
this.$el.modal('hide');
|
|
360
|
+
},
|
|
361
|
+
|
|
362
|
+
changeFillColorFunc() {
|
|
363
|
+
$('.h-functional-value #h-annotation-fill-color-func').prop('checked', true);
|
|
364
|
+
this._updateFuncValues();
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
changeLineColorFunc() {
|
|
368
|
+
$('.h-functional-value #h-annotation-line-color-func').prop('checked', true);
|
|
369
|
+
this._updateFuncValues();
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
_updateFuncValues() {
|
|
373
|
+
var names = ['fill-color', 'line-color'];
|
|
374
|
+
names.forEach((name) => {
|
|
375
|
+
let curfunc = this.$el.find('#h-annotation-' + name + '-func-list').val();
|
|
376
|
+
let mintext = '';
|
|
377
|
+
let maxtext = '';
|
|
378
|
+
if (this._styleableFuncs[curfunc]) {
|
|
379
|
+
if (!this._styleableFuncs[curfunc].categoric) {
|
|
380
|
+
mintext = 'Minimum value: ' + this._styleableFuncs[curfunc].min;
|
|
381
|
+
maxtext = 'Maximum value: ' + this._styleableFuncs[curfunc].max;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
this.$el.find('#h-annotation-' + name + '-min-auto').parent().attr('title', mintext);
|
|
385
|
+
this.$el.find('#h-annotation-' + name + '-min-setval').parent().attr('title', mintext);
|
|
386
|
+
this.$el.find('#h-annotation-' + name + '-max-auto').parent().attr('title', maxtext);
|
|
387
|
+
this.$el.find('#h-annotation-' + name + '-max-setval').parent().attr('title', maxtext);
|
|
388
|
+
});
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
_getFunctionalProps(name, key, valueParam, setValue, color) {
|
|
392
|
+
var geo = window.geo;
|
|
393
|
+
|
|
394
|
+
let valueFunc = this.annotation._styleFuncs[key];
|
|
395
|
+
valueFunc.useFunc = this.$('#h-annotation-' + name + '-func').prop('checked');
|
|
396
|
+
valueFunc.key = this.$('#h-annotation-' + name + '-func-list').val();
|
|
397
|
+
valueFunc.minColor = tinycolor(this.$('#h-annotation-' + name + '-min').val()).toRgbString();
|
|
398
|
+
valueFunc.minSet = this.$('#h-annotation-' + name + '-min-setval').prop('checked');
|
|
399
|
+
valueFunc.minValue = parseFloat(this.$('#h-annotation-' + name + '-min-val').val());
|
|
400
|
+
valueFunc.minValue = _.isFinite(valueFunc.minValue) ? valueFunc.minValue : undefined;
|
|
401
|
+
valueFunc.maxColor = tinycolor(this.$('#h-annotation-' + name + '-max').val()).toRgbString();
|
|
402
|
+
valueFunc.maxSet = this.$('#h-annotation-' + name + '-max-setval').prop('checked');
|
|
403
|
+
valueFunc.maxValue = parseFloat(this.$('#h-annotation-' + name + '-max-val').val());
|
|
404
|
+
valueFunc.maxValue = _.isFinite(valueFunc.maxValue) ? valueFunc.maxValue : undefined;
|
|
405
|
+
if (valueFunc.useFunc) {
|
|
406
|
+
setValue = 'func';
|
|
407
|
+
}
|
|
408
|
+
valueParam.key = valueFunc.key;
|
|
409
|
+
if (this._styleableFuncs[valueFunc.key]) {
|
|
410
|
+
valueParam.min = valueFunc.minSet && _.isFinite(valueFunc.minValue) ? valueFunc.minValue : this._styleableFuncs[valueFunc.key].min;
|
|
411
|
+
valueParam.max = valueFunc.maxSet && _.isFinite(valueFunc.maxValue) ? valueFunc.maxValue : this._styleableFuncs[valueFunc.key].max;
|
|
412
|
+
valueParam.range = (valueParam.max - valueParam.min) || 1;
|
|
413
|
+
valueParam.minColor = geo.util.convertColor(valueFunc.minColor);
|
|
414
|
+
valueParam.maxColor = geo.util.convertColor(valueFunc.maxColor);
|
|
415
|
+
} else if (setValue === 'func') {
|
|
416
|
+
setValue = false;
|
|
417
|
+
}
|
|
418
|
+
return setValue;
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Respond to form submission. Triggers a `g:save` event on the
|
|
423
|
+
* AnnotationModel.
|
|
424
|
+
*/
|
|
425
|
+
save(evt) {
|
|
426
|
+
evt.preventDefault();
|
|
427
|
+
|
|
428
|
+
let validation = '';
|
|
429
|
+
|
|
430
|
+
if (!this.$('#h-annotation-name').val()) {
|
|
431
|
+
this.$('#h-annotation-name').parent().addClass('has-error');
|
|
432
|
+
validation += 'Please enter a name. ';
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
let setFillColor = !!this.$('#h-annotation-fill-color').val();
|
|
436
|
+
let fillColor = tinycolor(this.$('#h-annotation-fill-color').val()).toRgbString();
|
|
437
|
+
let setLineColor = !!this.$('#h-annotation-line-color').val();
|
|
438
|
+
let lineColor = tinycolor(this.$('#h-annotation-line-color').val()).toRgbString();
|
|
439
|
+
const setLineWidth = !!this.$('#h-annotation-line-width').val();
|
|
440
|
+
const lineWidth = parseFloat(this.$('#h-annotation-line-width').val());
|
|
441
|
+
|
|
442
|
+
if (setLineWidth && (lineWidth < 0 || !isFinite(lineWidth))) {
|
|
443
|
+
validation += 'Invalid line width. ';
|
|
444
|
+
this.$('#h-annotation-line-width').parent().addClass('has-error');
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
let fillColorParam = {};
|
|
448
|
+
let lineColorParam = {};
|
|
449
|
+
if (this._showStyleEditor && Object.keys(this._styleableFuncs || {}).length) {
|
|
450
|
+
// get functional values
|
|
451
|
+
setFillColor = this._getFunctionalProps('fill-color', 'fillColor', fillColorParam, fillColor, setFillColor, true);
|
|
452
|
+
setLineColor = this._getFunctionalProps('line-color', 'lineColor', lineColorParam, lineColor, setLineColor, true);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (validation) {
|
|
456
|
+
this.$('.g-validation-failed-message').text(validation.trim())
|
|
457
|
+
.removeClass('hidden');
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// all valid
|
|
462
|
+
if (setFillColor || setLineColor || setLineWidth) {
|
|
463
|
+
this.annotation.elements().each((element, idx) => { /* eslint-disable backbone/no-silent */
|
|
464
|
+
if (setFillColor) {
|
|
465
|
+
if (setFillColor === 'func') {
|
|
466
|
+
fillColor = colorFromFunc(element, idx, fillColorParam, this._styleableFuncs[fillColorParam.key]);
|
|
467
|
+
}
|
|
468
|
+
element.set('fillColor', fillColor, {silent: true});
|
|
469
|
+
}
|
|
470
|
+
if (setLineColor) {
|
|
471
|
+
if (setLineColor === 'func') {
|
|
472
|
+
lineColor = colorFromFunc(element, idx, lineColorParam, this._styleableFuncs[lineColorParam.key]);
|
|
473
|
+
}
|
|
474
|
+
element.set('lineColor', lineColor, {silent: true});
|
|
475
|
+
}
|
|
476
|
+
if (setLineWidth) {
|
|
477
|
+
element.set('lineWidth', lineWidth, {silent: true});
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
const annotationData = _.extend({}, this.annotation.get('annotation'));
|
|
481
|
+
annotationData.elements = this.annotation.elements().toJSON();
|
|
482
|
+
this.annotation.set('annotation', annotationData, {silent: true});
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
_.extend(this.annotation.get('annotation'), {
|
|
486
|
+
name: this.$('#h-annotation-name').val(),
|
|
487
|
+
description: this.$('#h-annotation-description').val()
|
|
488
|
+
});
|
|
489
|
+
this.annotation.attributes.annotation.attributes = Object.assign({}, this.annotation._meta);
|
|
490
|
+
this.annotation.attributes.annotation.attributes._styleFuncs = this.annotation._styleFuncs;
|
|
491
|
+
delete this.annotation._meta;
|
|
492
|
+
delete this.annotation._styleFuncs;
|
|
493
|
+
this.annotation.trigger('change:annotation', this.annotation, {});
|
|
494
|
+
this.trigger('g:submit');
|
|
495
|
+
this.$el.modal('hide');
|
|
496
|
+
},
|
|
497
|
+
|
|
498
|
+
destroy() {
|
|
499
|
+
this.$('.h-colorpicker').colorpicker('destroy');
|
|
500
|
+
SaveAnnotation.prototype.destroy.call(this);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Create a singleton instance of this widget that will be rendered
|
|
506
|
+
* when `show` is called.
|
|
507
|
+
*/
|
|
508
|
+
var dialog = new SaveAnnotation({
|
|
509
|
+
parentView: null
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Show the save dialog box. Watch for the `g:submit` event on the
|
|
514
|
+
* view to respond to user submission of the form.
|
|
515
|
+
*
|
|
516
|
+
* @param {AnnotationModel} annotationElement The element to edit
|
|
517
|
+
* @returns {SaveAnnotation} The dialog's view
|
|
518
|
+
*/
|
|
519
|
+
function show(annotation, options) {
|
|
520
|
+
_.defaults(options, { title: 'Create annotation' });
|
|
521
|
+
delete annotation._meta;
|
|
522
|
+
dialog.annotation = annotation;
|
|
523
|
+
dialog.options = options;
|
|
524
|
+
dialog.setElement('#g-dialog-container').render();
|
|
525
|
+
return dialog;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export default show;
|
|
@@ -199,14 +199,12 @@ var AnnotationSelector = Panel.extend({
|
|
|
199
199
|
const id = $(evt.currentTarget).parents('.h-annotation').data('id');
|
|
200
200
|
const model = this.collection.get(id);
|
|
201
201
|
this.listenToOnce(
|
|
202
|
-
showSaveAnnotationDialog(model, {title: 'Edit annotation'}),
|
|
202
|
+
showSaveAnnotationDialog(model, {title: 'Edit annotation', viewer: this.viewer}),
|
|
203
203
|
'g:submit',
|
|
204
204
|
() => {
|
|
205
|
-
model.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
});
|
|
205
|
+
if (model.get('displayed')) {
|
|
206
|
+
this.trigger('h:redraw', model);
|
|
207
|
+
}
|
|
210
208
|
}
|
|
211
209
|
);
|
|
212
210
|
},
|