@genome-spy/core 0.37.4 → 0.38.0
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.
- package/dist/bundle/__vite-browser-external-ENoMJThg.js +8 -0
- package/dist/bundle/_commonjsHelpers-QtkX90xp.js +30 -0
- package/dist/bundle/index-1QVesMzU.js +1074 -0
- package/dist/bundle/index-Cbz74kpR.js +638 -0
- package/dist/bundle/index-LD6yPc3X.js +515 -0
- package/dist/bundle/index-Pv3tKJ1W.js +2190 -0
- package/dist/bundle/index-UyrC0vvF.js +72 -0
- package/dist/bundle/index-Y-LdHNIz.js +501 -0
- package/dist/bundle/index-gn8bhQ8w.js +4050 -0
- package/dist/bundle/index-lmJu1tfP.js +1372 -0
- package/dist/bundle/index-z4Cs62EO.js +279 -0
- package/dist/bundle/index.es.js +6448 -20571
- package/dist/bundle/index.js +93 -112
- package/dist/bundle/long-Veu0zKh9.js +2382 -0
- package/dist/bundle/remoteFile-Ur-gRKsH.js +96 -0
- package/dist/schema.json +492 -108
- package/dist/src/data/collector.d.ts +11 -11
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +8 -8
- package/dist/src/data/dataFlow.d.ts +18 -18
- package/dist/src/data/dataFlow.d.ts.map +1 -1
- package/dist/src/data/dataFlow.js +7 -7
- package/dist/src/data/flowNode.d.ts +9 -9
- package/dist/src/data/flowNode.d.ts.map +1 -1
- package/dist/src/data/flowNode.js +5 -5
- package/dist/src/data/flowOptimizer.d.ts +11 -11
- package/dist/src/data/flowOptimizer.d.ts.map +1 -1
- package/dist/src/data/flowOptimizer.js +7 -7
- package/dist/src/data/flowTestUtils.d.ts +2 -2
- package/dist/src/data/flowTestUtils.d.ts.map +1 -1
- package/dist/src/data/flowTestUtils.js +1 -1
- package/dist/src/data/sources/dataSource.js +1 -1
- package/dist/src/data/sources/dataSourceFactory.d.ts +3 -3
- package/dist/src/data/sources/dataSourceFactory.d.ts.map +1 -1
- package/dist/src/data/sources/dataSourceFactory.js +20 -20
- package/dist/src/data/sources/dataUtils.d.ts +20 -20
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +11 -11
- package/dist/src/data/sources/dynamic/axisGenomeSource.d.ts +3 -3
- package/dist/src/data/sources/dynamic/axisGenomeSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/axisGenomeSource.js +2 -2
- package/dist/src/data/sources/dynamic/axisTickSource.d.ts +6 -6
- package/dist/src/data/sources/dynamic/axisTickSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/axisTickSource.js +4 -4
- package/dist/src/data/sources/dynamic/bamSource.d.ts +7 -13
- package/dist/src/data/sources/dynamic/bamSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/bamSource.js +35 -27
- package/dist/src/data/sources/dynamic/bigBedSource.d.ts +9 -9
- package/dist/src/data/sources/dynamic/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/bigBedSource.js +31 -18
- package/dist/src/data/sources/dynamic/bigWigSource.d.ts +7 -7
- package/dist/src/data/sources/dynamic/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/bigWigSource.js +33 -26
- package/dist/src/data/sources/dynamic/gff3Source.d.ts +9 -0
- package/dist/src/data/sources/dynamic/gff3Source.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/gff3Source.js +17 -2
- package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts +6 -9
- package/dist/src/data/sources/dynamic/indexedFastaSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/indexedFastaSource.js +28 -18
- package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts +10 -10
- package/dist/src/data/sources/dynamic/singleAxisLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/singleAxisLazySource.js +6 -6
- package/dist/src/data/sources/dynamic/tabixSource.d.ts +11 -8
- package/dist/src/data/sources/dynamic/tabixSource.d.ts.map +1 -1
- package/dist/src/data/sources/dynamic/tabixSource.js +31 -17
- package/dist/src/data/sources/inlineSource.d.ts +7 -7
- package/dist/src/data/sources/inlineSource.d.ts.map +1 -1
- package/dist/src/data/sources/inlineSource.js +5 -5
- package/dist/src/data/sources/namedSource.d.ts +9 -9
- package/dist/src/data/sources/namedSource.d.ts.map +1 -1
- package/dist/src/data/sources/namedSource.js +6 -6
- package/dist/src/data/sources/sequenceSource.d.ts +7 -7
- package/dist/src/data/sources/sequenceSource.d.ts.map +1 -1
- package/dist/src/data/sources/sequenceSource.js +4 -4
- package/dist/src/data/sources/urlSource.d.ts +7 -7
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +4 -4
- package/dist/src/data/transforms/aggregate.d.ts +3 -3
- package/dist/src/data/transforms/aggregate.d.ts.map +1 -1
- package/dist/src/data/transforms/aggregate.js +2 -2
- package/dist/src/data/transforms/clone.d.ts +2 -2
- package/dist/src/data/transforms/clone.d.ts.map +1 -1
- package/dist/src/data/transforms/clone.js +1 -1
- package/dist/src/data/transforms/coverage.d.ts +3 -3
- package/dist/src/data/transforms/coverage.d.ts.map +1 -1
- package/dist/src/data/transforms/coverage.js +1 -1
- package/dist/src/data/transforms/coverage.test.js +1 -1
- package/dist/src/data/transforms/filter.d.ts +3 -3
- package/dist/src/data/transforms/filter.d.ts.map +1 -1
- package/dist/src/data/transforms/filter.js +2 -2
- package/dist/src/data/transforms/filter.test.js +1 -1
- package/dist/src/data/transforms/filterScoredLabels.d.ts +4 -4
- package/dist/src/data/transforms/filterScoredLabels.d.ts.map +1 -1
- package/dist/src/data/transforms/filterScoredLabels.js +3 -3
- package/dist/src/data/transforms/flatten.d.ts +2 -2
- package/dist/src/data/transforms/flatten.d.ts.map +1 -1
- package/dist/src/data/transforms/flatten.js +3 -3
- package/dist/src/data/transforms/flatten.test.js +6 -6
- package/dist/src/data/transforms/flattenCompressedExons.d.ts +2 -2
- package/dist/src/data/transforms/flattenCompressedExons.d.ts.map +1 -1
- package/dist/src/data/transforms/flattenCompressedExons.js +1 -1
- package/dist/src/data/transforms/flattenDelimited.d.ts +2 -2
- package/dist/src/data/transforms/flattenDelimited.d.ts.map +1 -1
- package/dist/src/data/transforms/flattenDelimited.js +2 -2
- package/dist/src/data/transforms/flattenDelimited.test.js +5 -5
- package/dist/src/data/transforms/flattenSequence.d.ts +2 -2
- package/dist/src/data/transforms/flattenSequence.d.ts.map +1 -1
- package/dist/src/data/transforms/flattenSequence.js +1 -1
- package/dist/src/data/transforms/flattenSequence.test.js +1 -1
- package/dist/src/data/transforms/formula.d.ts +3 -3
- package/dist/src/data/transforms/formula.d.ts.map +1 -1
- package/dist/src/data/transforms/formula.js +2 -2
- package/dist/src/data/transforms/identifier.d.ts +3 -3
- package/dist/src/data/transforms/identifier.d.ts.map +1 -1
- package/dist/src/data/transforms/identifier.js +2 -2
- package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts +3 -3
- package/dist/src/data/transforms/linearizeGenomicCoordinate.d.ts.map +1 -1
- package/dist/src/data/transforms/linearizeGenomicCoordinate.js +2 -2
- package/dist/src/data/transforms/measureText.d.ts +2 -2
- package/dist/src/data/transforms/measureText.d.ts.map +1 -1
- package/dist/src/data/transforms/measureText.js +1 -1
- package/dist/src/data/transforms/pileup.d.ts +3 -3
- package/dist/src/data/transforms/pileup.d.ts.map +1 -1
- package/dist/src/data/transforms/pileup.js +1 -1
- package/dist/src/data/transforms/pileup.test.js +1 -1
- package/dist/src/data/transforms/project.d.ts +2 -2
- package/dist/src/data/transforms/project.d.ts.map +1 -1
- package/dist/src/data/transforms/project.js +1 -1
- package/dist/src/data/transforms/project.test.js +1 -1
- package/dist/src/data/transforms/regexExtract.d.ts +2 -2
- package/dist/src/data/transforms/regexExtract.d.ts.map +1 -1
- package/dist/src/data/transforms/regexExtract.js +1 -1
- package/dist/src/data/transforms/regexExtract.test.js +3 -3
- package/dist/src/data/transforms/regexFold.d.ts +2 -2
- package/dist/src/data/transforms/regexFold.d.ts.map +1 -1
- package/dist/src/data/transforms/regexFold.js +2 -2
- package/dist/src/data/transforms/regexFold.test.js +3 -3
- package/dist/src/data/transforms/sample.d.ts +2 -2
- package/dist/src/data/transforms/sample.d.ts.map +1 -1
- package/dist/src/data/transforms/sample.js +2 -2
- package/dist/src/data/transforms/stack.d.ts +3 -3
- package/dist/src/data/transforms/stack.d.ts.map +1 -1
- package/dist/src/data/transforms/stack.js +2 -2
- package/dist/src/data/transforms/stack.test.js +2 -2
- package/dist/src/data/transforms/transformFactory.d.ts +5 -5
- package/dist/src/data/transforms/transformFactory.d.ts.map +1 -1
- package/dist/src/data/transforms/transformFactory.js +3 -3
- package/dist/src/encoder/accessor.d.ts +6 -6
- package/dist/src/encoder/accessor.d.ts.map +1 -1
- package/dist/src/encoder/accessor.js +4 -4
- package/dist/src/encoder/encoder.d.ts +59 -59
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +40 -40
- package/dist/src/encoder/encoder.test.js +4 -4
- package/dist/src/fonts/bmFontManager.d.ts +7 -7
- package/dist/src/fonts/bmFontManager.d.ts.map +1 -1
- package/dist/src/fonts/bmFontManager.js +3 -3
- package/dist/src/fonts/bmFontMetrics.d.ts +6 -6
- package/dist/src/fonts/bmFontMetrics.d.ts.map +1 -1
- package/dist/src/fonts/bmFontMetrics.js +4 -4
- package/dist/src/genome/genome.d.ts +7 -7
- package/dist/src/genome/genome.d.ts.map +1 -1
- package/dist/src/genome/genome.js +2 -2
- package/dist/src/genome/genomeStore.d.ts +2 -2
- package/dist/src/genome/genomeStore.d.ts.map +1 -1
- package/dist/src/genome/genomeStore.js +1 -1
- package/dist/src/genome/locusFormat.d.ts +7 -7
- package/dist/src/genome/locusFormat.d.ts.map +1 -1
- package/dist/src/genome/locusFormat.js +4 -4
- package/dist/src/genome/scaleIndex.d.ts +1 -1
- package/dist/src/genome/scaleIndex.d.ts.map +1 -1
- package/dist/src/genome/scaleIndex.js +1 -1
- package/dist/src/genome/scaleLocus.d.ts +2 -2
- package/dist/src/genome/scaleLocus.d.ts.map +1 -1
- package/dist/src/genome/scaleLocus.js +3 -3
- package/dist/src/genomeSpy.d.ts +12 -12
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +51 -34
- package/dist/src/gl/arrayBuilder.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.d.ts +18 -18
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.js +10 -10
- package/dist/src/gl/webGLHelper.d.ts +4 -4
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/marks/link.js +5 -5
- package/dist/src/marks/mark.d.ts +35 -32
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +26 -23
- package/dist/src/marks/markUtils.d.ts +10 -10
- package/dist/src/marks/markUtils.d.ts.map +1 -1
- package/dist/src/marks/markUtils.js +5 -5
- package/dist/src/marks/pointMark.d.ts +1 -1
- package/dist/src/marks/pointMark.d.ts.map +1 -1
- package/dist/src/marks/pointMark.js +7 -7
- package/dist/src/marks/rectMark.d.ts +2 -2
- package/dist/src/marks/rectMark.d.ts.map +1 -1
- package/dist/src/marks/rectMark.js +7 -7
- package/dist/src/marks/rule.js +6 -6
- package/dist/src/marks/text.d.ts +1 -1
- package/dist/src/marks/text.d.ts.map +1 -1
- package/dist/src/marks/text.js +6 -6
- package/dist/src/scale/colorUtils.d.ts +4 -4
- package/dist/src/scale/colorUtils.d.ts.map +1 -1
- package/dist/src/scale/colorUtils.js +2 -2
- package/dist/src/scale/glslScaleGenerator.d.ts +3 -3
- package/dist/src/scale/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/scale/glslScaleGenerator.js +2 -2
- package/dist/src/scale/scale.d.ts +3 -3
- package/dist/src/scale/scale.d.ts.map +1 -1
- package/dist/src/scale/scale.js +2 -2
- package/dist/src/scale/ticks.d.ts +4 -4
- package/dist/src/scale/ticks.js +4 -4
- package/dist/src/spec/axis.d.ts +1 -1
- package/dist/src/spec/channel.d.ts +2 -2
- package/dist/src/spec/data.d.ts +2 -2
- package/dist/src/spec/mark.d.ts +3 -3
- package/dist/src/spec/root.d.ts +2 -2
- package/dist/src/spec/sampleView.d.ts +5 -5
- package/dist/src/spec/scale.d.ts +1 -1
- package/dist/src/spec/title.d.ts +1 -1
- package/dist/src/spec/view.d.ts +36 -9
- package/dist/src/tooltip/dataTooltipHandler.js +1 -1
- package/dist/src/tooltip/refseqGeneTooltipHandler.d.ts.map +1 -1
- package/dist/src/tooltip/refseqGeneTooltipHandler.js +1 -1
- package/dist/src/tooltip/tooltipHandler.d.ts +1 -1
- package/dist/src/tooltip/tooltipHandler.d.ts.map +1 -1
- package/dist/src/tooltip/tooltipHandler.ts +1 -1
- package/dist/src/types/embedApi.d.ts +3 -3
- package/dist/src/types/encoder.d.ts +4 -4
- package/dist/src/types/flowBatch.d.ts +1 -1
- package/dist/src/types/rendering.d.ts +3 -3
- package/dist/src/types/scaleResolutionApi.d.ts +2 -2
- package/dist/src/types/viewContext.d.ts +41 -12
- package/dist/src/utils/animator.d.ts +2 -2
- package/dist/src/utils/animator.d.ts.map +1 -1
- package/dist/src/utils/animator.js +1 -1
- package/dist/src/utils/inertia.d.ts +3 -3
- package/dist/src/utils/inertia.d.ts.map +1 -1
- package/dist/src/utils/inertia.js +1 -1
- package/dist/src/utils/interactionEvent.d.ts +5 -5
- package/dist/src/utils/interactionEvent.d.ts.map +1 -1
- package/dist/src/utils/interactionEvent.js +2 -2
- package/dist/src/utils/trees.js +1 -1
- package/dist/src/view/axisGridView.d.ts +17 -16
- package/dist/src/view/axisGridView.d.ts.map +1 -1
- package/dist/src/view/axisGridView.js +24 -20
- package/dist/src/view/axisResolution.d.ts +10 -10
- package/dist/src/view/axisResolution.d.ts.map +1 -1
- package/dist/src/view/axisResolution.js +6 -6
- package/dist/src/view/axisResolution.test.js +1 -1
- package/dist/src/view/axisView.d.ts +18 -17
- package/dist/src/view/axisView.d.ts.map +1 -1
- package/dist/src/view/axisView.js +39 -35
- package/dist/src/view/concatView.d.ts +5 -5
- package/dist/src/view/concatView.d.ts.map +1 -1
- package/dist/src/view/concatView.js +23 -23
- package/dist/src/view/containerView.d.ts +10 -8
- package/dist/src/view/containerView.d.ts.map +1 -1
- package/dist/src/view/containerView.js +18 -13
- package/dist/src/view/facetView.d.ts +12 -12
- package/dist/src/view/facetView.d.ts.map +1 -1
- package/dist/src/view/facetView.js +19 -19
- package/dist/src/view/flowBuilder.d.ts +4 -4
- package/dist/src/view/flowBuilder.d.ts.map +1 -1
- package/dist/src/view/flowBuilder.js +13 -13
- package/dist/src/view/flowBuilder.test.js +7 -7
- package/dist/src/view/gridView.d.ts +63 -35
- package/dist/src/view/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView.js +400 -113
- package/dist/src/view/layerView.d.ts +12 -14
- package/dist/src/view/layerView.d.ts.map +1 -1
- package/dist/src/view/layerView.js +55 -26
- package/dist/src/{utils → view}/layout/flexLayout.d.ts +6 -6
- package/dist/src/view/layout/flexLayout.d.ts.map +1 -0
- package/dist/src/{utils → view}/layout/flexLayout.js +4 -4
- package/dist/src/view/layout/grid.d.ts.map +1 -0
- package/dist/src/{utils → view}/layout/padding.d.ts +4 -4
- package/dist/src/view/layout/padding.d.ts.map +1 -0
- package/dist/src/{utils → view}/layout/padding.js +2 -2
- package/dist/src/view/layout/point.d.ts.map +1 -0
- package/dist/src/{utils → view}/layout/rectangle.d.ts +8 -2
- package/dist/src/view/layout/rectangle.d.ts.map +1 -0
- package/dist/src/{utils → view}/layout/rectangle.js +22 -2
- package/dist/src/{utils → view}/layout/rectangle.test.js +8 -0
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts +10 -10
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +10 -10
- package/dist/src/view/renderingContext/compositeViewRenderingContext.d.ts +2 -2
- package/dist/src/view/renderingContext/compositeViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/compositeViewRenderingContext.js +4 -4
- package/dist/src/view/renderingContext/debuggingViewRenderingContext.d.ts +4 -4
- package/dist/src/view/renderingContext/debuggingViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/debuggingViewRenderingContext.js +3 -3
- package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.d.ts +8 -8
- package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/layoutRecorderViewRenderingContext.js +4 -4
- package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts +6 -6
- package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/simpleViewRenderingContext.js +7 -7
- package/dist/src/view/renderingContext/svgViewRenderingContext.d.ts +4 -4
- package/dist/src/view/renderingContext/svgViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/svgViewRenderingContext.js +6 -6
- package/dist/src/view/renderingContext/viewRenderingContext.d.ts +10 -10
- package/dist/src/view/renderingContext/viewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/viewRenderingContext.js +5 -5
- package/dist/src/view/scaleResolution.d.ts +21 -17
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +29 -24
- package/dist/src/view/scaleResolution.test.js +57 -72
- package/dist/src/view/testUtils.d.ts +6 -15
- package/dist/src/view/testUtils.d.ts.map +1 -1
- package/dist/src/view/testUtils.js +40 -44
- package/dist/src/view/title.d.ts +3 -3
- package/dist/src/view/title.d.ts.map +1 -1
- package/dist/src/view/title.js +12 -12
- package/dist/src/view/unitView.d.ts +31 -30
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +30 -22
- package/dist/src/view/view.d.ts +86 -57
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +148 -103
- package/dist/src/view/view.test.js +9 -8
- package/dist/src/view/viewError.d.ts +9 -0
- package/dist/src/view/viewError.d.ts.map +1 -0
- package/dist/src/view/viewError.js +11 -0
- package/dist/src/view/viewFactory.d.ts +53 -20
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +148 -33
- package/dist/src/view/viewFactory.test.js +8 -0
- package/dist/src/view/viewUtils.d.ts +14 -12
- package/dist/src/view/viewUtils.d.ts.map +1 -1
- package/dist/src/view/viewUtils.js +10 -63
- package/dist/src/view/zoom.d.ts +4 -4
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/dist/src/view/zoom.js +3 -3
- package/package.json +7 -5
- package/dist/src/utils/layout/flexLayout.d.ts.map +0 -1
- package/dist/src/utils/layout/grid.d.ts.map +0 -1
- package/dist/src/utils/layout/padding.d.ts.map +0 -1
- package/dist/src/utils/layout/point.d.ts.map +0 -1
- package/dist/src/utils/layout/rectangle.d.ts.map +0 -1
- package/dist/src/view/implicitRootView.d.ts +0 -9
- package/dist/src/view/implicitRootView.d.ts.map +0 -1
- package/dist/src/view/implicitRootView.js +0 -23
- package/dist/src/view/importView.d.ts +0 -17
- package/dist/src/view/importView.d.ts.map +0 -1
- package/dist/src/view/importView.js +0 -22
- /package/dist/src/{utils → view}/layout/flexLayout.test.js +0 -0
- /package/dist/src/{utils → view}/layout/grid.d.ts +0 -0
- /package/dist/src/{utils → view}/layout/grid.js +0 -0
- /package/dist/src/{utils → view}/layout/grid.test.js +0 -0
- /package/dist/src/{utils → view}/layout/point.d.ts +0 -0
- /package/dist/src/{utils → view}/layout/point.js +0 -0
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
mapToPixelCoords,
|
|
7
7
|
parseSizeDef,
|
|
8
8
|
ZERO_SIZEDEF,
|
|
9
|
-
} from "
|
|
10
|
-
import Grid from "
|
|
11
|
-
import Padding from "
|
|
12
|
-
import Rectangle from "
|
|
9
|
+
} from "./layout/flexLayout.js";
|
|
10
|
+
import Grid from "./layout/grid.js";
|
|
11
|
+
import Padding from "./layout/padding.js";
|
|
12
|
+
import Rectangle from "./layout/rectangle.js";
|
|
13
13
|
import AxisGridView from "./axisGridView.js";
|
|
14
14
|
import AxisView, { CHANNEL_ORIENTS, ORIENT_CHANNELS } from "./axisView.js";
|
|
15
15
|
import ContainerView from "./containerView.js";
|
|
@@ -17,6 +17,7 @@ import LayerView from "./layerView.js";
|
|
|
17
17
|
import createTitle from "./title.js";
|
|
18
18
|
import UnitView from "./unitView.js";
|
|
19
19
|
import interactionToZoom from "./zoom.js";
|
|
20
|
+
import clamp from "../utils/clamp.js";
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Modeled after: https://vega.github.io/vega/docs/layout/
|
|
@@ -31,13 +32,15 @@ import interactionToZoom from "./zoom.js";
|
|
|
31
32
|
* - Facet (column / row) titles
|
|
32
33
|
* - Header / footer
|
|
33
34
|
* - Zoom / pan
|
|
35
|
+
* - Scrollable viewports (with scrollbars)
|
|
34
36
|
* - And later on, brushing, legend(?)
|
|
35
37
|
*/
|
|
36
38
|
export default class GridView extends ContainerView {
|
|
37
39
|
/**
|
|
38
40
|
* @typedef {"row" | "column"} Direction
|
|
41
|
+
* @typedef {"horizontal" | "vertical"} ScrollDirection
|
|
39
42
|
*
|
|
40
|
-
* @typedef {import("./view").default} View
|
|
43
|
+
* @typedef {import("./view.js").default} View
|
|
41
44
|
*/
|
|
42
45
|
|
|
43
46
|
/** */
|
|
@@ -55,7 +58,7 @@ export default class GridView extends ContainerView {
|
|
|
55
58
|
* toggleable view visibilities. For example, if the bottom view is suddenly hidden,
|
|
56
59
|
* the axis should be shown in the view that takes its place as the new bottom view.
|
|
57
60
|
*
|
|
58
|
-
* @type { Partial<Record<import("../spec/channel").PrimaryPositionalChannel, AxisView>> } }
|
|
61
|
+
* @type { Partial<Record<import("../spec/channel.js").PrimaryPositionalChannel, AxisView>> } }
|
|
59
62
|
*/
|
|
60
63
|
#sharedAxes = {};
|
|
61
64
|
|
|
@@ -63,15 +66,24 @@ export default class GridView extends ContainerView {
|
|
|
63
66
|
|
|
64
67
|
/**
|
|
65
68
|
*
|
|
66
|
-
* @param {import("../spec/view").AnyConcatSpec} spec
|
|
67
|
-
* @param {import("../types/viewContext").default} context
|
|
69
|
+
* @param {import("../spec/view.js").AnyConcatSpec} spec
|
|
70
|
+
* @param {import("../types/viewContext.js").default} context
|
|
68
71
|
* @param {ContainerView} layoutParent
|
|
69
72
|
* @param {View} dataParent
|
|
70
73
|
* @param {string} name
|
|
71
74
|
* @param {number} columns
|
|
75
|
+
* @param {import("./view.js").ViewOptions} [options]
|
|
72
76
|
*/
|
|
73
|
-
constructor(
|
|
74
|
-
|
|
77
|
+
constructor(
|
|
78
|
+
spec,
|
|
79
|
+
context,
|
|
80
|
+
layoutParent,
|
|
81
|
+
dataParent,
|
|
82
|
+
name,
|
|
83
|
+
columns,
|
|
84
|
+
options
|
|
85
|
+
) {
|
|
86
|
+
super(spec, context, layoutParent, dataParent, name, options);
|
|
75
87
|
this.spec = spec;
|
|
76
88
|
|
|
77
89
|
this.#spacing = spec.spacing ?? 10;
|
|
@@ -80,15 +92,6 @@ export default class GridView extends ContainerView {
|
|
|
80
92
|
this.#children = [];
|
|
81
93
|
|
|
82
94
|
this.wrappingFacet = false;
|
|
83
|
-
|
|
84
|
-
this._createChildren();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @protected
|
|
89
|
-
*/
|
|
90
|
-
_createChildren() {
|
|
91
|
-
// Override
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
/**
|
|
@@ -153,13 +156,13 @@ export default class GridView extends ContainerView {
|
|
|
153
156
|
return this.#children.length;
|
|
154
157
|
}
|
|
155
158
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
/**
|
|
160
|
+
* @protected
|
|
161
|
+
*/
|
|
162
|
+
async createAxes() {
|
|
163
|
+
/** @type {Promise<void>[]} */
|
|
164
|
+
const promises = [];
|
|
161
165
|
|
|
162
|
-
#createAxes() {
|
|
163
166
|
// Axis ticks, labels, etc. They should be created only if this view has caught
|
|
164
167
|
// the scale resolution for the channel.
|
|
165
168
|
for (const channel of primaryPositionalChannels) {
|
|
@@ -180,22 +183,17 @@ export default class GridView extends ContainerView {
|
|
|
180
183
|
this,
|
|
181
184
|
this
|
|
182
185
|
);
|
|
186
|
+
promises.push(v.initializeChildren());
|
|
183
187
|
this.#sharedAxes[channel] = v;
|
|
184
|
-
|
|
185
|
-
// Axes are created after scales are resolved, so we need to resolve possible new scales here
|
|
186
|
-
v.visit((view) => {
|
|
187
|
-
if (view instanceof UnitView) {
|
|
188
|
-
view.resolve("scale");
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
188
|
}
|
|
192
189
|
}
|
|
193
190
|
}
|
|
194
191
|
|
|
195
192
|
// Create view decorations, grid lines, and independent axes for each child
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
193
|
+
return Promise.all([
|
|
194
|
+
...promises,
|
|
195
|
+
...this.#children.map((gridChild) => gridChild.createAxes()),
|
|
196
|
+
]);
|
|
199
197
|
}
|
|
200
198
|
|
|
201
199
|
/**
|
|
@@ -244,9 +242,9 @@ export default class GridView extends ContainerView {
|
|
|
244
242
|
view: getLargestSize(
|
|
245
243
|
col.map(
|
|
246
244
|
(rowIndex) =>
|
|
247
|
-
this.#visibleChildren[
|
|
248
|
-
|
|
249
|
-
]
|
|
245
|
+
this.#visibleChildren[
|
|
246
|
+
rowIndex
|
|
247
|
+
].view.getViewportSize()[dim]
|
|
250
248
|
)
|
|
251
249
|
),
|
|
252
250
|
})
|
|
@@ -275,7 +273,7 @@ export default class GridView extends ContainerView {
|
|
|
275
273
|
#makeFlexItems(direction) {
|
|
276
274
|
const sizes = this.#getSizes(direction);
|
|
277
275
|
|
|
278
|
-
/** @type {import("
|
|
276
|
+
/** @type {import("./layout/flexLayout.js").SizeDef[]} */
|
|
279
277
|
const items = [];
|
|
280
278
|
|
|
281
279
|
// Title
|
|
@@ -312,15 +310,14 @@ export default class GridView extends ContainerView {
|
|
|
312
310
|
|
|
313
311
|
/**
|
|
314
312
|
* @param {Direction} direction
|
|
315
|
-
* @return {import("
|
|
313
|
+
* @return {import("./layout/flexLayout.js").SizeDef}
|
|
316
314
|
*/
|
|
317
315
|
#getFlexSize(direction) {
|
|
318
316
|
let grow = 0;
|
|
319
317
|
let px = 0;
|
|
320
318
|
|
|
321
319
|
const explicitSize =
|
|
322
|
-
|
|
323
|
-
(direction == "column" && this.spec.width);
|
|
320
|
+
direction == "row" ? this.spec.height : this.spec.width;
|
|
324
321
|
if (explicitSize || explicitSize === 0) {
|
|
325
322
|
return parseSizeDef(explicitSize);
|
|
326
323
|
}
|
|
@@ -396,7 +393,7 @@ export default class GridView extends ContainerView {
|
|
|
396
393
|
|
|
397
394
|
#getSharedAxisOverhang() {
|
|
398
395
|
/**
|
|
399
|
-
* @param {import("../spec/axis").AxisOrient} orient
|
|
396
|
+
* @param {import("../spec/axis.js").AxisOrient} orient
|
|
400
397
|
*/
|
|
401
398
|
const getSharedAxisSize = (orient) => {
|
|
402
399
|
const channel = ORIENT_CHANNELS[orient];
|
|
@@ -433,9 +430,9 @@ export default class GridView extends ContainerView {
|
|
|
433
430
|
}
|
|
434
431
|
|
|
435
432
|
/**
|
|
436
|
-
* @param {import("./renderingContext/viewRenderingContext").default} context
|
|
437
|
-
* @param {import("
|
|
438
|
-
* @param {import("../types/rendering").RenderingOptions} [options]
|
|
433
|
+
* @param {import("./renderingContext/viewRenderingContext.js").default} context
|
|
434
|
+
* @param {import("./layout/rectangle.js").default} coords
|
|
435
|
+
* @param {import("../types/rendering.js").RenderingOptions} [options]
|
|
439
436
|
*/
|
|
440
437
|
// eslint-disable-next-line complexity
|
|
441
438
|
render(context, coords, options = {}) {
|
|
@@ -471,6 +468,10 @@ export default class GridView extends ContainerView {
|
|
|
471
468
|
this.#columns ?? Infinity
|
|
472
469
|
);
|
|
473
470
|
|
|
471
|
+
/** @param {number} x */
|
|
472
|
+
const round = (x) =>
|
|
473
|
+
Math.round(x * devicePixelRatio) / devicePixelRatio;
|
|
474
|
+
|
|
474
475
|
for (const [i, gridChild] of this.#visibleChildren.entries()) {
|
|
475
476
|
const {
|
|
476
477
|
view,
|
|
@@ -486,31 +487,65 @@ export default class GridView extends ContainerView {
|
|
|
486
487
|
columnFlexCoords[this.#getViewSlot("column", col)];
|
|
487
488
|
const rowLocSize = rowFlexCoords[this.#getViewSlot("row", row)];
|
|
488
489
|
|
|
489
|
-
const
|
|
490
|
+
const viewportSize = view.getViewportSize();
|
|
491
|
+
const viewSize = view.getSize();
|
|
492
|
+
|
|
490
493
|
const overhang = view.getOverhang();
|
|
491
494
|
|
|
492
495
|
const x = colLocSize.location - overhang.left;
|
|
493
496
|
const y = rowLocSize.location - overhang.top;
|
|
494
497
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
498
|
+
// TODO: Optimize for cases where viewportSize and viewSize have equal identity
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* @param {FlexDimensions} size
|
|
502
|
+
* @param {"width" | "height"} dimension
|
|
503
|
+
*/
|
|
504
|
+
const getLen = (size, dimension) =>
|
|
505
|
+
(size[dimension].grow
|
|
506
|
+
? (dimension == "width" ? colLocSize : rowLocSize).size
|
|
507
|
+
: size[dimension].px) + overhang[dimension];
|
|
501
508
|
|
|
502
|
-
const
|
|
509
|
+
const viewportWidth = getLen(viewportSize, "width");
|
|
510
|
+
const viewportHeight = getLen(viewportSize, "height");
|
|
511
|
+
const viewWidth = getLen(viewSize, "width");
|
|
512
|
+
const viewHeight = getLen(viewSize, "height");
|
|
513
|
+
|
|
514
|
+
const hScrollbar = gridChild.scrollbars.horizontal;
|
|
515
|
+
const vScrollbar = gridChild.scrollbars.vertical;
|
|
516
|
+
|
|
517
|
+
const getHScrollOffset = hScrollbar
|
|
518
|
+
? () => round(hScrollbar.viewportOffset)
|
|
519
|
+
: () => 0;
|
|
520
|
+
const getVScrollOffset = vScrollbar
|
|
521
|
+
? () => round(vScrollbar.viewportOffset)
|
|
522
|
+
: () => 0;
|
|
523
|
+
|
|
524
|
+
// TODO: Part of the following rendering logic could be moved to GridChild
|
|
525
|
+
|
|
526
|
+
const viewportCoords = new Rectangle(
|
|
503
527
|
() => coords.x + x,
|
|
504
528
|
() => coords.y + y,
|
|
505
|
-
() =>
|
|
506
|
-
() =>
|
|
529
|
+
() => viewportWidth,
|
|
530
|
+
() => viewportHeight
|
|
507
531
|
);
|
|
508
532
|
|
|
509
|
-
|
|
533
|
+
const scrollable = view.isScrollable();
|
|
534
|
+
|
|
535
|
+
const viewCoords = scrollable
|
|
536
|
+
? new Rectangle(
|
|
537
|
+
() => coords.x + x - getHScrollOffset(),
|
|
538
|
+
() => coords.y + y - getVScrollOffset(),
|
|
539
|
+
() => viewWidth,
|
|
540
|
+
() => viewHeight
|
|
541
|
+
)
|
|
542
|
+
: viewportCoords;
|
|
543
|
+
|
|
544
|
+
gridChild.coords = viewportCoords;
|
|
510
545
|
|
|
511
546
|
const clippedChildCoords = options.clipRect
|
|
512
|
-
?
|
|
513
|
-
:
|
|
547
|
+
? viewportCoords.intersect(options.clipRect)
|
|
548
|
+
: viewportCoords;
|
|
514
549
|
|
|
515
550
|
background?.render(context, clippedChildCoords, {
|
|
516
551
|
...options,
|
|
@@ -518,13 +553,17 @@ export default class GridView extends ContainerView {
|
|
|
518
553
|
});
|
|
519
554
|
|
|
520
555
|
for (const gridLineView of Object.values(gridLines)) {
|
|
521
|
-
gridLineView.render(context,
|
|
556
|
+
gridLineView.render(context, viewportCoords, options);
|
|
522
557
|
}
|
|
523
558
|
|
|
559
|
+
const clipped = isClippedChildren(view) || scrollable;
|
|
560
|
+
|
|
524
561
|
// If clipped, the axes should be drawn on top of the marks (because clipping may not be pixel-perfect)
|
|
525
|
-
const clipped = isClippedChildren(view);
|
|
526
562
|
if (clipped) {
|
|
527
|
-
view.render(context,
|
|
563
|
+
view.render(context, viewCoords, {
|
|
564
|
+
...options,
|
|
565
|
+
clipRect: clippedChildCoords,
|
|
566
|
+
});
|
|
528
567
|
}
|
|
529
568
|
|
|
530
569
|
backgroundStroke?.render(context, clippedChildCoords, {
|
|
@@ -534,14 +573,66 @@ export default class GridView extends ContainerView {
|
|
|
534
573
|
|
|
535
574
|
// Independent axes
|
|
536
575
|
for (const [orient, axisView] of Object.entries(axes)) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
576
|
+
const direction =
|
|
577
|
+
orient == "left" || orient == "right"
|
|
578
|
+
? "vertical"
|
|
579
|
+
: "horizontal";
|
|
580
|
+
|
|
581
|
+
const scrollable = gridChild.scrollbars[direction];
|
|
582
|
+
|
|
583
|
+
// Axes should stick to the viewport edge but move with the view
|
|
584
|
+
// when scrolling.
|
|
585
|
+
const coords = scrollable
|
|
586
|
+
? viewportCoords.modify(
|
|
587
|
+
direction == "vertical"
|
|
588
|
+
? {
|
|
589
|
+
y: () => viewCoords.y,
|
|
590
|
+
height: viewHeight,
|
|
591
|
+
}
|
|
592
|
+
: {
|
|
593
|
+
x: () => viewCoords.x,
|
|
594
|
+
width: viewWidth,
|
|
595
|
+
}
|
|
596
|
+
)
|
|
597
|
+
: viewportCoords;
|
|
598
|
+
|
|
599
|
+
const translatedCoords = translateAxisCoords(
|
|
600
|
+
coords,
|
|
601
|
+
orient,
|
|
602
|
+
axisView
|
|
541
603
|
);
|
|
604
|
+
|
|
605
|
+
let clipRect = options.clipRect;
|
|
606
|
+
|
|
607
|
+
// Scrollable axes must be clipped along the scroll direction.
|
|
608
|
+
if (scrollable) {
|
|
609
|
+
clipRect = translatedCoords.intersect(clipRect).intersect(
|
|
610
|
+
scrollable
|
|
611
|
+
? viewportCoords.modify(
|
|
612
|
+
// Ugly hack. Need to implement intersectX and intersectY.
|
|
613
|
+
direction == "vertical"
|
|
614
|
+
? {
|
|
615
|
+
x: -100000,
|
|
616
|
+
width: 200000,
|
|
617
|
+
}
|
|
618
|
+
: {
|
|
619
|
+
y: -100000,
|
|
620
|
+
height: 200000,
|
|
621
|
+
}
|
|
622
|
+
)
|
|
623
|
+
: undefined
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
axisView.render(context, translatedCoords, {
|
|
628
|
+
...options,
|
|
629
|
+
clipRect,
|
|
630
|
+
});
|
|
542
631
|
}
|
|
543
632
|
|
|
544
633
|
// Axes shared between children
|
|
634
|
+
// TODO: What if some have scrollable viewports?
|
|
635
|
+
// Should throw an error because cannot have shared axes in such cases.
|
|
545
636
|
for (const axisView of Object.values(this.#sharedAxes)) {
|
|
546
637
|
const props = axisView.axisProps;
|
|
547
638
|
const orient = props.orient;
|
|
@@ -554,7 +645,7 @@ export default class GridView extends ContainerView {
|
|
|
554
645
|
axisView.render(
|
|
555
646
|
context,
|
|
556
647
|
translateAxisCoords(
|
|
557
|
-
|
|
648
|
+
viewportCoords.shrink(gridChild.view.getOverhang()),
|
|
558
649
|
orient,
|
|
559
650
|
axisView
|
|
560
651
|
),
|
|
@@ -564,17 +655,22 @@ export default class GridView extends ContainerView {
|
|
|
564
655
|
}
|
|
565
656
|
|
|
566
657
|
if (!clipped) {
|
|
567
|
-
view.render(context,
|
|
658
|
+
view.render(context, viewCoords, options);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
for (const scrollbar of Object.values(gridChild.scrollbars)) {
|
|
662
|
+
scrollbar.updateScrollbar(viewportCoords, viewCoords);
|
|
663
|
+
scrollbar.render(context, coords, options);
|
|
568
664
|
}
|
|
569
665
|
|
|
570
|
-
title?.render(context,
|
|
666
|
+
title?.render(context, viewportCoords, options);
|
|
571
667
|
}
|
|
572
668
|
|
|
573
669
|
context.popView(this);
|
|
574
670
|
}
|
|
575
671
|
|
|
576
672
|
/**
|
|
577
|
-
* @param {import("../utils/interactionEvent").default} event
|
|
673
|
+
* @param {import("../utils/interactionEvent.js").default} event
|
|
578
674
|
*/
|
|
579
675
|
propagateInteractionEvent(event) {
|
|
580
676
|
this.handleInteractionEvent(undefined, event, true);
|
|
@@ -586,6 +682,16 @@ export default class GridView extends ContainerView {
|
|
|
586
682
|
const pointedChild = this.#visibleChildren.find((gridChild) =>
|
|
587
683
|
gridChild.coords.containsPoint(event.point.x, event.point.y)
|
|
588
684
|
);
|
|
685
|
+
|
|
686
|
+
for (const scrollbar of Object.values(pointedChild?.scrollbars ?? {})) {
|
|
687
|
+
if (scrollbar.coords.containsPoint(event.point.x, event.point.y)) {
|
|
688
|
+
scrollbar.propagateInteractionEvent(event);
|
|
689
|
+
if (event.stopped) {
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
589
695
|
const pointedView = pointedChild?.view;
|
|
590
696
|
if (pointedView) {
|
|
591
697
|
pointedView.propagateInteractionEvent(event);
|
|
@@ -617,9 +723,9 @@ export default class GridView extends ContainerView {
|
|
|
617
723
|
|
|
618
724
|
/**
|
|
619
725
|
*
|
|
620
|
-
* @param {import("
|
|
726
|
+
* @param {import("./layout/rectangle.js").default} coords Coordinates
|
|
621
727
|
* @param {View} view
|
|
622
|
-
* @param {import("./zoom").ZoomEvent} zoomEvent
|
|
728
|
+
* @param {import("./zoom.js").ZoomEvent} zoomEvent
|
|
623
729
|
*/
|
|
624
730
|
#handleZoom(coords, view, zoomEvent) {
|
|
625
731
|
for (const [channel, resolutionSet] of Object.entries(
|
|
@@ -653,9 +759,9 @@ export default class GridView extends ContainerView {
|
|
|
653
759
|
}
|
|
654
760
|
|
|
655
761
|
/**
|
|
656
|
-
* @param {import("../spec/channel").Channel} channel
|
|
657
|
-
* @param {import("../spec/view").ResolutionTarget} resolutionType
|
|
658
|
-
* @returns {import("../spec/view").ResolutionBehavior}
|
|
762
|
+
* @param {import("../spec/channel.js").Channel} channel
|
|
763
|
+
* @param {import("../spec/view.js").ResolutionTarget} resolutionType
|
|
764
|
+
* @returns {import("../spec/view.js").ResolutionBehavior}
|
|
659
765
|
*/
|
|
660
766
|
getDefaultResolution(channel, resolutionType) {
|
|
661
767
|
return "independent";
|
|
@@ -663,8 +769,8 @@ export default class GridView extends ContainerView {
|
|
|
663
769
|
}
|
|
664
770
|
|
|
665
771
|
/**
|
|
666
|
-
* @param {import("../spec/view").ViewBackground} viewBackground
|
|
667
|
-
* @returns {import("../spec/view").UnitSpec}
|
|
772
|
+
* @param {import("../spec/view.js").ViewBackground} viewBackground
|
|
773
|
+
* @returns {import("../spec/view.js").UnitSpec}
|
|
668
774
|
*/
|
|
669
775
|
export function createBackground(viewBackground) {
|
|
670
776
|
if (
|
|
@@ -691,8 +797,8 @@ export function createBackground(viewBackground) {
|
|
|
691
797
|
}
|
|
692
798
|
|
|
693
799
|
/**
|
|
694
|
-
* @param {import("../spec/view").ViewBackground} viewBackground
|
|
695
|
-
* @returns {import("../spec/view").UnitSpec}
|
|
800
|
+
* @param {import("../spec/view.js").ViewBackground} viewBackground
|
|
801
|
+
* @returns {import("../spec/view.js").UnitSpec}
|
|
696
802
|
*/
|
|
697
803
|
export function createBackgroundStroke(viewBackground) {
|
|
698
804
|
if (
|
|
@@ -745,7 +851,7 @@ export function createBackgroundStroke(viewBackground) {
|
|
|
745
851
|
* @returns
|
|
746
852
|
*/
|
|
747
853
|
function getZoomableResolutions(view) {
|
|
748
|
-
/** @type {Record<import("../spec/channel").PrimaryPositionalChannel, Set<import("./scaleResolution").default>>} */
|
|
854
|
+
/** @type {Record<import("../spec/channel.js").PrimaryPositionalChannel, Set<import("./scaleResolution.js").default>>} */
|
|
749
855
|
const resolutions = {
|
|
750
856
|
x: new Set(),
|
|
751
857
|
y: new Set(),
|
|
@@ -781,8 +887,8 @@ export function isClippedChildren(view) {
|
|
|
781
887
|
|
|
782
888
|
/**
|
|
783
889
|
*
|
|
784
|
-
* @param {import("
|
|
785
|
-
* @param {import("../spec/axis").AxisOrient} orient
|
|
890
|
+
* @param {import("./layout/rectangle.js").default} coords
|
|
891
|
+
* @param {import("../spec/axis.js").AxisOrient} orient
|
|
786
892
|
* @param {AxisView} axisView
|
|
787
893
|
*/
|
|
788
894
|
export function translateAxisCoords(coords, orient, axisView) {
|
|
@@ -821,12 +927,15 @@ export class GridChild {
|
|
|
821
927
|
/** @type {UnitView} */
|
|
822
928
|
this.backgroundStroke = undefined;
|
|
823
929
|
|
|
824
|
-
/** @type {Partial<Record<import("../spec/axis").AxisOrient, AxisView>>} axes */
|
|
930
|
+
/** @type {Partial<Record<import("../spec/axis.js").AxisOrient, AxisView>>} axes */
|
|
825
931
|
this.axes = {};
|
|
826
932
|
|
|
827
|
-
/** @type {Partial<Record<import("../spec/axis").AxisOrient, AxisGridView>>} gridLines */
|
|
933
|
+
/** @type {Partial<Record<import("../spec/axis.js").AxisOrient, AxisGridView>>} gridLines */
|
|
828
934
|
this.gridLines = {};
|
|
829
935
|
|
|
936
|
+
/** @type {Partial<Record<ScrollDirection, Scrollbar>>} */
|
|
937
|
+
this.scrollbars = {};
|
|
938
|
+
|
|
830
939
|
/** @type {UnitView} */
|
|
831
940
|
this.title = undefined;
|
|
832
941
|
|
|
@@ -844,10 +953,11 @@ export class GridChild {
|
|
|
844
953
|
layoutParent.context,
|
|
845
954
|
layoutParent,
|
|
846
955
|
view,
|
|
847
|
-
"background" + serial
|
|
956
|
+
"background" + serial,
|
|
957
|
+
{
|
|
958
|
+
blockEncodingInheritance: true,
|
|
959
|
+
}
|
|
848
960
|
);
|
|
849
|
-
// TODO: Make configurable through spec:
|
|
850
|
-
this.background.blockEncodingInheritance = true;
|
|
851
961
|
}
|
|
852
962
|
|
|
853
963
|
const backgroundStrokeSpec = createBackgroundStroke(viewBackground);
|
|
@@ -857,10 +967,11 @@ export class GridChild {
|
|
|
857
967
|
layoutParent.context,
|
|
858
968
|
layoutParent,
|
|
859
969
|
view,
|
|
860
|
-
"backgroundStroke" + serial
|
|
970
|
+
"backgroundStroke" + serial,
|
|
971
|
+
{
|
|
972
|
+
blockEncodingInheritance: true,
|
|
973
|
+
}
|
|
861
974
|
);
|
|
862
|
-
// TODO: Make configurable through spec:
|
|
863
|
-
this.backgroundStroke.blockEncodingInheritance = true;
|
|
864
975
|
}
|
|
865
976
|
|
|
866
977
|
const title = createTitle(view.spec.title);
|
|
@@ -870,13 +981,23 @@ export class GridChild {
|
|
|
870
981
|
layoutParent.context,
|
|
871
982
|
layoutParent,
|
|
872
983
|
view,
|
|
873
|
-
"title" + serial
|
|
984
|
+
"title" + serial,
|
|
985
|
+
{
|
|
986
|
+
blockEncodingInheritance: true,
|
|
987
|
+
}
|
|
874
988
|
);
|
|
875
|
-
// TODO: Make configurable through spec:
|
|
876
|
-
unitView.blockEncodingInheritance = true;
|
|
877
989
|
this.title = unitView;
|
|
878
990
|
}
|
|
879
991
|
}
|
|
992
|
+
|
|
993
|
+
// TODO: More specific getter for this
|
|
994
|
+
if (view.spec.viewportWidth != null) {
|
|
995
|
+
this.scrollbars.horizontal = new Scrollbar(this, "horizontal");
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
if (view.spec.viewportHeight != null) {
|
|
999
|
+
this.scrollbars.vertical = new Scrollbar(this, "vertical");
|
|
1000
|
+
}
|
|
880
1001
|
}
|
|
881
1002
|
|
|
882
1003
|
*getChildren() {
|
|
@@ -892,17 +1013,18 @@ export class GridChild {
|
|
|
892
1013
|
yield* Object.values(this.axes);
|
|
893
1014
|
yield* Object.values(this.gridLines);
|
|
894
1015
|
yield this.view;
|
|
1016
|
+
yield* Object.values(this.scrollbars);
|
|
895
1017
|
}
|
|
896
1018
|
|
|
897
1019
|
/**
|
|
898
1020
|
* Create view decorations, grid lines, axes, etc.
|
|
899
1021
|
*/
|
|
900
|
-
createAxes() {
|
|
1022
|
+
async createAxes() {
|
|
901
1023
|
const { view, axes, gridLines } = this;
|
|
902
1024
|
|
|
903
1025
|
/**
|
|
904
|
-
* @param {import("./axisResolution").default} r
|
|
905
|
-
* @param {import("../spec/channel").PrimaryPositionalChannel} channel
|
|
1026
|
+
* @param {import("./axisResolution.js").default} r
|
|
1027
|
+
* @param {import("../spec/channel.js").PrimaryPositionalChannel} channel
|
|
906
1028
|
*/
|
|
907
1029
|
const getAxisPropsWithDefaults = (r, channel) => {
|
|
908
1030
|
const propsWithoutDefaults = r.getAxisProps();
|
|
@@ -942,11 +1064,11 @@ export class GridChild {
|
|
|
942
1064
|
};
|
|
943
1065
|
|
|
944
1066
|
/**
|
|
945
|
-
* @param {import("./axisResolution").default} r
|
|
946
|
-
* @param {import("../spec/channel").PrimaryPositionalChannel} channel
|
|
1067
|
+
* @param {import("./axisResolution.js").default} r
|
|
1068
|
+
* @param {import("../spec/channel.js").PrimaryPositionalChannel} channel
|
|
947
1069
|
* @param {View} axisParent
|
|
948
1070
|
*/
|
|
949
|
-
const createAxis = (r, channel, axisParent) => {
|
|
1071
|
+
const createAxis = async (r, channel, axisParent) => {
|
|
950
1072
|
const props = getAxisPropsWithDefaults(r, channel);
|
|
951
1073
|
|
|
952
1074
|
if (props) {
|
|
@@ -956,37 +1078,41 @@ export class GridChild {
|
|
|
956
1078
|
);
|
|
957
1079
|
}
|
|
958
1080
|
|
|
959
|
-
|
|
1081
|
+
const axisView = new AxisView(
|
|
960
1082
|
props,
|
|
961
1083
|
r.scaleResolution.type,
|
|
962
1084
|
this.layoutParent.context,
|
|
963
1085
|
this.layoutParent,
|
|
964
1086
|
axisParent
|
|
965
1087
|
);
|
|
1088
|
+
axes[props.orient] = axisView;
|
|
1089
|
+
await axisView.initializeChildren();
|
|
966
1090
|
}
|
|
967
1091
|
};
|
|
968
1092
|
|
|
969
1093
|
/**
|
|
970
|
-
* @param {import("./axisResolution").default} r
|
|
971
|
-
* @param {import("../spec/channel").PrimaryPositionalChannel} channel
|
|
1094
|
+
* @param {import("./axisResolution.js").default} r
|
|
1095
|
+
* @param {import("../spec/channel.js").PrimaryPositionalChannel} channel
|
|
972
1096
|
* @param {View} axisParent
|
|
973
1097
|
*/
|
|
974
|
-
const createAxisGrid = (r, channel, axisParent) => {
|
|
1098
|
+
const createAxisGrid = async (r, channel, axisParent) => {
|
|
975
1099
|
const props = getAxisPropsWithDefaults(r, channel);
|
|
976
1100
|
|
|
977
1101
|
if (props && (props.grid || props.chromGrid)) {
|
|
978
|
-
|
|
1102
|
+
const axisGridView = new AxisGridView(
|
|
979
1103
|
props,
|
|
980
1104
|
r.scaleResolution.type,
|
|
981
1105
|
this.layoutParent.context,
|
|
982
1106
|
this.layoutParent,
|
|
983
1107
|
axisParent
|
|
984
1108
|
);
|
|
1109
|
+
gridLines[props.orient] = axisGridView;
|
|
1110
|
+
await axisGridView.initializeChildren();
|
|
985
1111
|
}
|
|
986
1112
|
};
|
|
987
1113
|
|
|
988
1114
|
// Handle children that have caught axis resolutions. Create axes for them.
|
|
989
|
-
for (const channel of /** @type {import("../spec/channel").PrimaryPositionalChannel[]} */ ([
|
|
1115
|
+
for (const channel of /** @type {import("../spec/channel.js").PrimaryPositionalChannel[]} */ ([
|
|
990
1116
|
"x",
|
|
991
1117
|
"y",
|
|
992
1118
|
])) {
|
|
@@ -996,13 +1122,13 @@ export class GridChild {
|
|
|
996
1122
|
continue;
|
|
997
1123
|
}
|
|
998
1124
|
|
|
999
|
-
createAxis(r, channel, view);
|
|
1125
|
+
await createAxis(r, channel, view);
|
|
1000
1126
|
}
|
|
1001
1127
|
}
|
|
1002
1128
|
|
|
1003
1129
|
// Handle gridlines of children. Note: children's axis resolution may be caught by
|
|
1004
1130
|
// this view or some of this view's ancestors.
|
|
1005
|
-
for (const channel of /** @type {import("../spec/channel").PrimaryPositionalChannel[]} */ ([
|
|
1131
|
+
for (const channel of /** @type {import("../spec/channel.js").PrimaryPositionalChannel[]} */ ([
|
|
1006
1132
|
"x",
|
|
1007
1133
|
"y",
|
|
1008
1134
|
])) {
|
|
@@ -1014,32 +1140,32 @@ export class GridChild {
|
|
|
1014
1140
|
|
|
1015
1141
|
// TODO: Optimization: the same grid view could be reused for all children
|
|
1016
1142
|
// because they share the axis and scale resolutions anyway.
|
|
1017
|
-
createAxisGrid(r, channel, view);
|
|
1143
|
+
await createAxisGrid(r, channel, view);
|
|
1018
1144
|
}
|
|
1019
1145
|
}
|
|
1020
1146
|
|
|
1021
1147
|
// Handle LayerView's possible independent axes
|
|
1022
1148
|
if (view instanceof LayerView) {
|
|
1023
1149
|
// First create axes that have an orient preference
|
|
1024
|
-
for (const layerChild of view
|
|
1150
|
+
for (const layerChild of view) {
|
|
1025
1151
|
for (const [channel, r] of Object.entries(
|
|
1026
1152
|
layerChild.resolutions.axis
|
|
1027
1153
|
)) {
|
|
1028
1154
|
const props = r.getAxisProps();
|
|
1029
1155
|
if (props && props.orient) {
|
|
1030
|
-
createAxis(r, channel, layerChild);
|
|
1156
|
+
await createAxis(r, channel, layerChild);
|
|
1031
1157
|
}
|
|
1032
1158
|
}
|
|
1033
1159
|
}
|
|
1034
1160
|
|
|
1035
1161
|
// Then create axes in a priority order
|
|
1036
|
-
for (const layerChild of view
|
|
1162
|
+
for (const layerChild of view) {
|
|
1037
1163
|
for (const [channel, r] of Object.entries(
|
|
1038
1164
|
layerChild.resolutions.axis
|
|
1039
1165
|
)) {
|
|
1040
1166
|
const props = r.getAxisProps();
|
|
1041
1167
|
if (props && !props.orient) {
|
|
1042
|
-
createAxis(r, channel, layerChild);
|
|
1168
|
+
await createAxis(r, channel, layerChild);
|
|
1043
1169
|
}
|
|
1044
1170
|
}
|
|
1045
1171
|
}
|
|
@@ -1059,7 +1185,7 @@ export class GridChild {
|
|
|
1059
1185
|
|
|
1060
1186
|
getOverhang() {
|
|
1061
1187
|
const calculate = (
|
|
1062
|
-
/** @type {import("../spec/axis").AxisOrient} */ orient
|
|
1188
|
+
/** @type {import("../spec/axis.js").AxisOrient} */ orient
|
|
1063
1189
|
) => {
|
|
1064
1190
|
const axisView = this.axes[orient];
|
|
1065
1191
|
return axisView
|
|
@@ -1084,3 +1210,164 @@ export class GridChild {
|
|
|
1084
1210
|
return this.getOverhang().add(this.view.getPadding());
|
|
1085
1211
|
}
|
|
1086
1212
|
}
|
|
1213
|
+
|
|
1214
|
+
class Scrollbar extends UnitView {
|
|
1215
|
+
/**
|
|
1216
|
+
* @param {GridChild} gridChild
|
|
1217
|
+
* @param {ScrollDirection} scrollDirection
|
|
1218
|
+
*/
|
|
1219
|
+
constructor(gridChild, scrollDirection) {
|
|
1220
|
+
// TODO: Configurable
|
|
1221
|
+
const config = {
|
|
1222
|
+
scrollbarSize: 8,
|
|
1223
|
+
scrollbarPadding: 2,
|
|
1224
|
+
// TODO: inside/outside view
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
super(
|
|
1228
|
+
{
|
|
1229
|
+
data: { values: [{}] },
|
|
1230
|
+
mark: {
|
|
1231
|
+
type: "rect",
|
|
1232
|
+
fill: "#b0b0b0",
|
|
1233
|
+
fillOpacity: 0.6,
|
|
1234
|
+
stroke: "white",
|
|
1235
|
+
strokeWidth: 1,
|
|
1236
|
+
strokeOpacity: 1,
|
|
1237
|
+
cornerRadius: 5,
|
|
1238
|
+
clip: false,
|
|
1239
|
+
},
|
|
1240
|
+
configurableVisibility: false,
|
|
1241
|
+
},
|
|
1242
|
+
gridChild.layoutParent.context,
|
|
1243
|
+
gridChild.layoutParent,
|
|
1244
|
+
gridChild.view,
|
|
1245
|
+
"scrollbar-" + scrollDirection, // TODO: Serial
|
|
1246
|
+
{
|
|
1247
|
+
blockEncodingInheritance: true,
|
|
1248
|
+
}
|
|
1249
|
+
);
|
|
1250
|
+
|
|
1251
|
+
this.config = config;
|
|
1252
|
+
this.scrollDirection = scrollDirection;
|
|
1253
|
+
|
|
1254
|
+
// This is the actual state of the scrollbar. It's better to keep track of
|
|
1255
|
+
// the viewport offset rather than the scrollbar offset because the former
|
|
1256
|
+
// is more stable when the viewport size changes.
|
|
1257
|
+
this.viewportOffset = 0;
|
|
1258
|
+
|
|
1259
|
+
this.maxScrollOffset = 0;
|
|
1260
|
+
this.scrollbarCoords = Rectangle.ZERO;
|
|
1261
|
+
|
|
1262
|
+
this.addInteractionEventListener("mousedown", (coords, event) => {
|
|
1263
|
+
event.stopPropagation();
|
|
1264
|
+
|
|
1265
|
+
if (this.maxScrollOffset <= 0) {
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
const getMouseOffset = (/** @type {MouseEvent} */ mouseEvent) =>
|
|
1270
|
+
scrollDirection == "vertical"
|
|
1271
|
+
? mouseEvent.clientY
|
|
1272
|
+
: mouseEvent.clientX;
|
|
1273
|
+
|
|
1274
|
+
const mouseEvent = /** @type {MouseEvent} */ (event.uiEvent);
|
|
1275
|
+
mouseEvent.preventDefault();
|
|
1276
|
+
|
|
1277
|
+
const initialScrollOffset = this.getScrollOffset();
|
|
1278
|
+
const initialOffset = getMouseOffset(mouseEvent);
|
|
1279
|
+
|
|
1280
|
+
const onMousemove = /** @param {MouseEvent} moveEvent */ (
|
|
1281
|
+
moveEvent
|
|
1282
|
+
) => {
|
|
1283
|
+
const scrollOffset = clamp(
|
|
1284
|
+
getMouseOffset(moveEvent) -
|
|
1285
|
+
initialOffset +
|
|
1286
|
+
initialScrollOffset,
|
|
1287
|
+
0,
|
|
1288
|
+
this.maxScrollOffset
|
|
1289
|
+
);
|
|
1290
|
+
|
|
1291
|
+
this.viewportOffset =
|
|
1292
|
+
(scrollOffset / this.maxScrollOffset) *
|
|
1293
|
+
this.maxViewportOffset;
|
|
1294
|
+
this.context.animator.requestRender();
|
|
1295
|
+
};
|
|
1296
|
+
|
|
1297
|
+
const onMouseup = () => {
|
|
1298
|
+
document.removeEventListener("mousemove", onMousemove);
|
|
1299
|
+
document.removeEventListener("mouseup", onMouseup);
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
document.addEventListener("mouseup", onMouseup, false);
|
|
1303
|
+
document.addEventListener("mousemove", onMousemove, false);
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
getScrollOffset() {
|
|
1308
|
+
return (
|
|
1309
|
+
(this.viewportOffset / this.maxViewportOffset) *
|
|
1310
|
+
this.maxScrollOffset
|
|
1311
|
+
);
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
/**
|
|
1315
|
+
* @param {import("./renderingContext/viewRenderingContext.js").default} context
|
|
1316
|
+
* @param {import("./layout/rectangle.js").default} coords
|
|
1317
|
+
* @param {import("../types/rendering.js").RenderingOptions} [options]
|
|
1318
|
+
*/
|
|
1319
|
+
render(context, coords, options) {
|
|
1320
|
+
super.render(context, this.scrollbarCoords, options);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
/**
|
|
1324
|
+
*
|
|
1325
|
+
* @param {Rectangle} viewportCoords
|
|
1326
|
+
* @param {Rectangle} coords
|
|
1327
|
+
*/
|
|
1328
|
+
updateScrollbar(viewportCoords, coords) {
|
|
1329
|
+
const sPad = this.config.scrollbarPadding;
|
|
1330
|
+
const sSize = this.config.scrollbarSize;
|
|
1331
|
+
|
|
1332
|
+
const dimension =
|
|
1333
|
+
this.scrollDirection == "horizontal" ? "width" : "height";
|
|
1334
|
+
|
|
1335
|
+
const visibleFraction = Math.min(
|
|
1336
|
+
1,
|
|
1337
|
+
viewportCoords[dimension] / coords[dimension]
|
|
1338
|
+
);
|
|
1339
|
+
const maxScrollLength = viewportCoords[dimension] - 2 * sPad;
|
|
1340
|
+
const scrollLength = visibleFraction * maxScrollLength;
|
|
1341
|
+
|
|
1342
|
+
this.maxScrollOffset = maxScrollLength - scrollLength;
|
|
1343
|
+
this.maxViewportOffset = coords[dimension] - viewportCoords[dimension];
|
|
1344
|
+
this.viewportOffset = clamp(
|
|
1345
|
+
this.viewportOffset,
|
|
1346
|
+
0,
|
|
1347
|
+
this.maxViewportOffset
|
|
1348
|
+
);
|
|
1349
|
+
|
|
1350
|
+
this.scrollbarCoords =
|
|
1351
|
+
this.scrollDirection == "vertical"
|
|
1352
|
+
? new Rectangle(
|
|
1353
|
+
() =>
|
|
1354
|
+
viewportCoords.x +
|
|
1355
|
+
viewportCoords.width -
|
|
1356
|
+
sSize -
|
|
1357
|
+
sPad,
|
|
1358
|
+
() => viewportCoords.y + sPad + this.getScrollOffset(),
|
|
1359
|
+
() => sSize,
|
|
1360
|
+
() => scrollLength
|
|
1361
|
+
)
|
|
1362
|
+
: new Rectangle(
|
|
1363
|
+
() => viewportCoords.x + sPad + this.getScrollOffset(),
|
|
1364
|
+
() =>
|
|
1365
|
+
viewportCoords.y +
|
|
1366
|
+
viewportCoords.height -
|
|
1367
|
+
sSize -
|
|
1368
|
+
sPad,
|
|
1369
|
+
() => scrollLength,
|
|
1370
|
+
() => sSize
|
|
1371
|
+
);
|
|
1372
|
+
}
|
|
1373
|
+
}
|