@genome-spy/core 0.19.1 → 0.20.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/schema.json CHANGED
@@ -478,6 +478,9 @@
478
478
  "baseUrl": {
479
479
  "type": "string"
480
480
  },
481
+ "columns": {
482
+ "type": "number"
483
+ },
481
484
  "concat": {
482
485
  "items": {
483
486
  "anyOf": [
@@ -575,7 +578,14 @@
575
578
  "type": "number"
576
579
  },
577
580
  "title": {
578
- "type": "string"
581
+ "anyOf": [
582
+ {
583
+ "type": "string"
584
+ },
585
+ {
586
+ "$ref": "#/definitions/Title"
587
+ }
588
+ ]
579
589
  },
580
590
  "transform": {
581
591
  "items": {
@@ -606,7 +616,8 @@
606
616
  }
607
617
  },
608
618
  "required": [
609
- "concat"
619
+ "concat",
620
+ "columns"
610
621
  ],
611
622
  "type": "object"
612
623
  },
@@ -1335,7 +1346,14 @@
1335
1346
  "type": "number"
1336
1347
  },
1337
1348
  "title": {
1338
- "type": "string"
1349
+ "anyOf": [
1350
+ {
1351
+ "type": "string"
1352
+ },
1353
+ {
1354
+ "$ref": "#/definitions/Title"
1355
+ }
1356
+ ]
1339
1357
  },
1340
1358
  "transform": {
1341
1359
  "items": {
@@ -1624,7 +1642,14 @@
1624
1642
  "type": "object"
1625
1643
  },
1626
1644
  "title": {
1627
- "type": "string"
1645
+ "anyOf": [
1646
+ {
1647
+ "type": "string"
1648
+ },
1649
+ {
1650
+ "$ref": "#/definitions/Title"
1651
+ }
1652
+ ]
1628
1653
  },
1629
1654
  "transform": {
1630
1655
  "items": {
@@ -1633,7 +1658,7 @@
1633
1658
  "type": "array"
1634
1659
  },
1635
1660
  "view": {
1636
- "$ref": "#/definitions/ViewConfig"
1661
+ "$ref": "#/definitions/ViewBackground"
1637
1662
  },
1638
1663
  "visible": {
1639
1664
  "description": "Visibility of the view. An invisible view is removed from the layout and not rendered.\n\n**Default:** `true`",
@@ -2972,7 +2997,14 @@
2972
2997
  "type": "object"
2973
2998
  },
2974
2999
  "title": {
2975
- "type": "string"
3000
+ "anyOf": [
3001
+ {
3002
+ "type": "string"
3003
+ },
3004
+ {
3005
+ "$ref": "#/definitions/Title"
3006
+ }
3007
+ ]
2976
3008
  },
2977
3009
  "transform": {
2978
3010
  "items": {
@@ -2981,7 +3013,7 @@
2981
3013
  "type": "array"
2982
3014
  },
2983
3015
  "view": {
2984
- "$ref": "#/definitions/ViewConfig"
3016
+ "$ref": "#/definitions/ViewBackground"
2985
3017
  },
2986
3018
  "visible": {
2987
3019
  "description": "Visibility of the view. An invisible view is removed from the layout and not rendered.\n\n**Default:** `true`",
@@ -3137,7 +3169,14 @@
3137
3169
  "type": "object"
3138
3170
  },
3139
3171
  "title": {
3140
- "type": "string"
3172
+ "anyOf": [
3173
+ {
3174
+ "type": "string"
3175
+ },
3176
+ {
3177
+ "$ref": "#/definitions/Title"
3178
+ }
3179
+ ]
3141
3180
  },
3142
3181
  "transform": {
3143
3182
  "items": {
@@ -3146,7 +3185,7 @@
3146
3185
  "type": "array"
3147
3186
  },
3148
3187
  "view": {
3149
- "$ref": "#/definitions/ViewConfig"
3188
+ "$ref": "#/definitions/ViewBackground"
3150
3189
  },
3151
3190
  "visible": {
3152
3191
  "description": "Visibility of the view. An invisible view is removed from the layout and not rendered.\n\n**Default:** `true`",
@@ -3292,7 +3331,14 @@
3292
3331
  "type": "boolean"
3293
3332
  },
3294
3333
  "title": {
3295
- "type": "string"
3334
+ "anyOf": [
3335
+ {
3336
+ "type": "string"
3337
+ },
3338
+ {
3339
+ "$ref": "#/definitions/Title"
3340
+ }
3341
+ ]
3296
3342
  },
3297
3343
  "transform": {
3298
3344
  "items": {
@@ -3432,7 +3478,14 @@
3432
3478
  "type": "number"
3433
3479
  },
3434
3480
  "title": {
3435
- "type": "string"
3481
+ "anyOf": [
3482
+ {
3483
+ "type": "string"
3484
+ },
3485
+ {
3486
+ "$ref": "#/definitions/Title"
3487
+ }
3488
+ ]
3436
3489
  },
3437
3490
  "transform": {
3438
3491
  "items": {
@@ -3597,7 +3650,14 @@
3597
3650
  "type": "number"
3598
3651
  },
3599
3652
  "title": {
3600
- "type": "string"
3653
+ "anyOf": [
3654
+ {
3655
+ "type": "string"
3656
+ },
3657
+ {
3658
+ "$ref": "#/definitions/Title"
3659
+ }
3660
+ ]
3601
3661
  },
3602
3662
  "transform": {
3603
3663
  "items": {
@@ -3641,6 +3701,9 @@
3641
3701
  "baseUrl": {
3642
3702
  "type": "string"
3643
3703
  },
3704
+ "columns": {
3705
+ "type": "number"
3706
+ },
3644
3707
  "concat": {
3645
3708
  "items": {
3646
3709
  "anyOf": [
@@ -3749,7 +3812,14 @@
3749
3812
  "type": "number"
3750
3813
  },
3751
3814
  "title": {
3752
- "type": "string"
3815
+ "anyOf": [
3816
+ {
3817
+ "type": "string"
3818
+ },
3819
+ {
3820
+ "$ref": "#/definitions/Title"
3821
+ }
3822
+ ]
3753
3823
  },
3754
3824
  "transform": {
3755
3825
  "items": {
@@ -3780,6 +3850,7 @@
3780
3850
  }
3781
3851
  },
3782
3852
  "required": [
3853
+ "columns",
3783
3854
  "concat"
3784
3855
  ],
3785
3856
  "type": "object"
@@ -3947,7 +4018,14 @@
3947
4018
  "type": "boolean"
3948
4019
  },
3949
4020
  "title": {
3950
- "type": "string"
4021
+ "anyOf": [
4022
+ {
4023
+ "type": "string"
4024
+ },
4025
+ {
4026
+ "$ref": "#/definitions/Title"
4027
+ }
4028
+ ]
3951
4029
  },
3952
4030
  "transform": {
3953
4031
  "items": {
@@ -4498,6 +4576,109 @@
4498
4576
  }
4499
4577
  ]
4500
4578
  },
4579
+ "Title": {
4580
+ "additionalProperties": false,
4581
+ "properties": {
4582
+ "align": {
4583
+ "$ref": "#/definitions/Align",
4584
+ "description": "Horizontal text alignment for title text. One of `\"left\"`, `\"center\"`, or `\"right\"`."
4585
+ },
4586
+ "anchor": {
4587
+ "$ref": "#/definitions/TitleAnchor",
4588
+ "description": "The anchor position for placing the title and subtitle text. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title."
4589
+ },
4590
+ "angle": {
4591
+ "description": "Angle in degrees of title and subtitle text.",
4592
+ "type": "number"
4593
+ },
4594
+ "baseline": {
4595
+ "$ref": "#/definitions/Baseline",
4596
+ "description": "Vertical text baseline for title and subtitle text. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, or `\"bottom\"`."
4597
+ },
4598
+ "color": {
4599
+ "description": "Text color for title text.",
4600
+ "type": "string"
4601
+ },
4602
+ "dx": {
4603
+ "description": "Delta offset for title and subtitle text x-coordinate.",
4604
+ "type": "number"
4605
+ },
4606
+ "dy": {
4607
+ "description": "Delta offset for title and subtitle text y-coordinate.",
4608
+ "type": "number"
4609
+ },
4610
+ "font": {
4611
+ "description": "Font name for title text.",
4612
+ "type": "string"
4613
+ },
4614
+ "fontSize": {
4615
+ "description": "Font size in pixels for title text.",
4616
+ "minimum": 0,
4617
+ "type": "number"
4618
+ },
4619
+ "fontStyle": {
4620
+ "$ref": "#/definitions/FontStyle",
4621
+ "description": "Font style for title text."
4622
+ },
4623
+ "fontWeight": {
4624
+ "$ref": "#/definitions/FontWeight",
4625
+ "description": "Font weight for title text. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
4626
+ },
4627
+ "frame": {
4628
+ "$ref": "#/definitions/TitleFrame",
4629
+ "description": "The reference frame for the anchor position, one of `\"bounds\"` (to anchor relative to the full bounding box) or `\"group\"` (to anchor relative to the group width or height)."
4630
+ },
4631
+ "offset": {
4632
+ "description": "The orthogonal offset in pixels by which to displace the title group from its position along the edge of the chart.",
4633
+ "type": "number"
4634
+ },
4635
+ "orient": {
4636
+ "$ref": "#/definitions/TitleOrient",
4637
+ "description": "Default title orientation (`\"top\"`, `\"bottom\"`, `\"left\"`, or `\"right\"`)"
4638
+ },
4639
+ "style": {
4640
+ "description": "A mark style property to apply to the title text mark. If not specified, a default style of `\"group-title\"` is applied.",
4641
+ "type": "string"
4642
+ },
4643
+ "text": {
4644
+ "description": "The title text.",
4645
+ "type": "string"
4646
+ }
4647
+ },
4648
+ "required": [
4649
+ "text"
4650
+ ],
4651
+ "type": "object"
4652
+ },
4653
+ "TitleAnchor": {
4654
+ "enum": [
4655
+ null,
4656
+ "start",
4657
+ "middle",
4658
+ "end"
4659
+ ],
4660
+ "type": [
4661
+ "null",
4662
+ "string"
4663
+ ]
4664
+ },
4665
+ "TitleFrame": {
4666
+ "enum": [
4667
+ "bounds",
4668
+ "group"
4669
+ ],
4670
+ "type": "string"
4671
+ },
4672
+ "TitleOrient": {
4673
+ "enum": [
4674
+ "none",
4675
+ "left",
4676
+ "right",
4677
+ "top",
4678
+ "bottom"
4679
+ ],
4680
+ "type": "string"
4681
+ },
4501
4682
  "Tooltip": {
4502
4683
  "anyOf": [
4503
4684
  {
@@ -4696,7 +4877,14 @@
4696
4877
  "type": "object"
4697
4878
  },
4698
4879
  "title": {
4699
- "type": "string"
4880
+ "anyOf": [
4881
+ {
4882
+ "type": "string"
4883
+ },
4884
+ {
4885
+ "$ref": "#/definitions/Title"
4886
+ }
4887
+ ]
4700
4888
  },
4701
4889
  "transform": {
4702
4890
  "items": {
@@ -4705,7 +4893,7 @@
4705
4893
  "type": "array"
4706
4894
  },
4707
4895
  "view": {
4708
- "$ref": "#/definitions/ViewConfig"
4896
+ "$ref": "#/definitions/ViewBackground"
4709
4897
  },
4710
4898
  "visible": {
4711
4899
  "description": "Visibility of the view. An invisible view is removed from the layout and not rendered.\n\n**Default:** `true`",
@@ -4855,7 +5043,14 @@
4855
5043
  "type": "number"
4856
5044
  },
4857
5045
  "title": {
4858
- "type": "string"
5046
+ "anyOf": [
5047
+ {
5048
+ "type": "string"
5049
+ },
5050
+ {
5051
+ "$ref": "#/definitions/Title"
5052
+ }
5053
+ ]
4859
5054
  },
4860
5055
  "transform": {
4861
5056
  "items": {
@@ -4932,7 +5127,7 @@
4932
5127
  ],
4933
5128
  "type": "object"
4934
5129
  },
4935
- "ViewConfig": {
5130
+ "ViewBackground": {
4936
5131
  "additionalProperties": false,
4937
5132
  "properties": {
4938
5133
  "cornerRadius": {
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "contributors": [],
9
9
  "license": "BSD-2-Clause",
10
- "version": "0.19.1",
10
+ "version": "0.20.0",
11
11
  "main": "dist/index.js",
12
12
  "module": "src/index.js",
13
13
  "exports": {
@@ -44,7 +44,7 @@
44
44
  "d3-color": "^3.0.1",
45
45
  "d3-ease": "^3.0.1",
46
46
  "d3-format": "^3.0.1",
47
- "flatqueue": "^1.2.1",
47
+ "flatqueue": "^2.0.3",
48
48
  "internmap": "^2.0.3",
49
49
  "lit-html": "^2.0.2",
50
50
  "twgl.js": "^4.19.1",
@@ -53,5 +53,5 @@
53
53
  "vega-scale": "^7.1.1",
54
54
  "vega-util": "^1.16.0"
55
55
  },
56
- "gitHead": "ca14d08659918a002fb330ffcd325e9c1e122a8c"
56
+ "gitHead": "dfeadc37891908cf775423c61a566358ecada9fa"
57
57
  }
package/src/genomeSpy.js CHANGED
@@ -8,7 +8,6 @@ import Tooltip from "./utils/ui/tooltip";
8
8
  import AccessorFactory from "./encoder/accessor";
9
9
  import {
10
10
  resolveScalesAndAxes,
11
- addDecorators,
12
11
  processImports,
13
12
  setImplicitScaleNames,
14
13
  } from "./view/viewUtils";
@@ -17,7 +16,6 @@ import UnitView from "./view/unitView";
17
16
  import WebGLHelper from "./gl/webGLHelper";
18
17
  import Rectangle from "./utils/layout/rectangle";
19
18
  import DeferredViewRenderingContext from "./view/renderingContext/deferredViewRenderingContext";
20
- import LayoutRecorderViewRenderingContext from "./view/renderingContext/layoutRecorderViewRenderingContext";
21
19
  import CompositeViewRenderingContext from "./view/renderingContext/compositeViewRenderingContext";
22
20
  import InteractionEvent from "./utils/interactionEvent";
23
21
  import Point from "./utils/layout/point";
@@ -36,6 +34,8 @@ import refseqGeneTooltipHandler from "./tooltip/refseqGeneTooltipHandler";
36
34
  import dataTooltipHandler from "./tooltip/dataTooltipHandler";
37
35
  import { invalidatePrefix } from "./utils/propertyCacher";
38
36
  import { ViewFactory } from "./view/viewFactory";
37
+ import LayerView from "./view/layerView";
38
+ import ImplicitRootView from "./view/implicitRootView";
39
39
 
40
40
  /**
41
41
  * @typedef {import("./spec/view").UnitSpec} UnitSpec
@@ -166,7 +166,9 @@ export default class GenomeSpy {
166
166
 
167
167
  this._glHelper = new WebGLHelper(this.container, () => {
168
168
  if (this.viewRoot) {
169
- const size = this.viewRoot.getSize();
169
+ const size = this.viewRoot
170
+ .getSize()
171
+ .addPadding(this.viewRoot.getOverhang());
170
172
 
171
173
  // If a dimension has an absolutely specified size (in pixels), use it for the canvas size.
172
174
  // However, if the dimension has a growing component, the canvas should be fit to the
@@ -283,12 +285,19 @@ export default class GenomeSpy {
283
285
  // Replace placeholder ImportViews with actual views.
284
286
  await processImports(this.viewRoot);
285
287
 
288
+ if (
289
+ this.viewRoot instanceof UnitView ||
290
+ this.viewRoot instanceof LayerView
291
+ ) {
292
+ this.viewRoot = new ImplicitRootView(context, this.viewRoot);
293
+ }
294
+
286
295
  // Resolve scales, i.e., if possible, pull them towards the root
287
296
  resolveScalesAndAxes(this.viewRoot);
288
297
  setImplicitScaleNames(this.viewRoot);
289
298
 
290
299
  // Wrap unit or layer views that need axes
291
- this.viewRoot = addDecorators(this.viewRoot);
300
+ //this.viewRoot = addDecorators(this.viewRoot);
292
301
 
293
302
  // We should now have a complete view hierarchy. Let's update the canvas size
294
303
  // and ensure that the loading message is visible.
@@ -424,7 +433,7 @@ export default class GenomeSpy {
424
433
 
425
434
  /** @param {Event} event */
426
435
  const listener = (event) => {
427
- if (this.layout && event instanceof MouseEvent) {
436
+ if (event instanceof MouseEvent) {
428
437
  if (event.type == "mousemove") {
429
438
  this.tooltip.handleMouseMove(event);
430
439
  this._tooltipUpdateRequested = false;
@@ -445,7 +454,7 @@ export default class GenomeSpy {
445
454
  * @param {MouseEvent} event
446
455
  */
447
456
  const dispatchEvent = (event) => {
448
- this.layout.dispatchInteractionEvent(
457
+ this.viewRoot.propagateInteractionEvent(
449
458
  new InteractionEvent(point, event)
450
459
  );
451
460
 
@@ -677,20 +686,16 @@ export default class GenomeSpy {
677
686
  },
678
687
  this._glHelper
679
688
  );
680
- const layoutRecorder = new LayoutRecorderViewRenderingContext({});
681
689
 
682
690
  root.render(
683
691
  new CompositeViewRenderingContext(
684
692
  this._renderingContext,
685
- this._pickingContext,
686
- layoutRecorder
693
+ this._pickingContext
687
694
  ),
688
695
  // Canvas should now be sized based on the root view or the container
689
696
  Rectangle.create(0, 0, canvasSize.width, canvasSize.height)
690
697
  );
691
698
 
692
- this.layout = layoutRecorder.getLayout();
693
-
694
699
  this.broadcast("layoutComputed");
695
700
  }
696
701
 
package/src/marks/mark.js CHANGED
@@ -616,6 +616,10 @@ export default class Mark {
616
616
  }
617
617
  }
618
618
 
619
+ if (!facetTexture) {
620
+ throw new Error("No facet texture available. This is bug.");
621
+ }
622
+
619
623
  setUniforms(this.programInfo, {
620
624
  uSampleFacetTexture: facetTexture,
621
625
  });
@@ -745,7 +749,7 @@ export default class Mark {
745
749
  }
746
750
  };
747
751
  } else {
748
- const rangeEntry = rangeMapSource().get(options.facetId);
752
+ const rangeEntry = rangeMapSource()?.get(options.facetId);
749
753
  if (rangeEntry && rangeEntry.count) {
750
754
  return function renderStatic() {
751
755
  if (self.prepareSampleFacetRendering(options)) {
@@ -0,0 +1,102 @@
1
+ /*!
2
+ * Adapted from
3
+ * https://github.com/vega/vega/blob/main/packages/vega-typings/types/spec/title.d.ts
4
+ *
5
+ * Copyright (c) 2015-2018, University of Washington Interactive Data Lab
6
+ * All rights reserved.
7
+ *
8
+ * BSD-3-Clause License: https://github.com/vega/vega-lite/blob/master/LICENSE
9
+ */
10
+
11
+ import { Align, Baseline, FontStyle, FontWeight } from "./font";
12
+
13
+ export type TitleOrient = "none" | "left" | "right" | "top" | "bottom";
14
+ export type TitleAnchor = null | "start" | "middle" | "end";
15
+ export type TitleFrame = "bounds" | "group";
16
+
17
+ export interface Title {
18
+ /**
19
+ * The title text.
20
+ */
21
+ text: string;
22
+
23
+ /**
24
+ * A mark style property to apply to the title text mark. If not specified, a default style of `"group-title"` is applied.
25
+ */
26
+ style?: string;
27
+
28
+ /**
29
+ * The anchor position for placing the title and subtitle text. One of `"start"`, `"middle"`, or `"end"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title.
30
+ */
31
+ anchor?: TitleAnchor;
32
+
33
+ /**
34
+ * The reference frame for the anchor position, one of `"bounds"` (to anchor relative to the full bounding box) or `"group"` (to anchor relative to the group width or height).
35
+ */
36
+ frame?: TitleFrame;
37
+
38
+ /**
39
+ * The orthogonal offset in pixels by which to displace the title group from its position along the edge of the chart.
40
+ */
41
+ offset?: number;
42
+
43
+ /**
44
+ * Default title orientation (`"top"`, `"bottom"`, `"left"`, or `"right"`)
45
+ */
46
+ orient?: TitleOrient;
47
+
48
+ // ---------- Shared Text Properties ----------
49
+ /**
50
+ * Horizontal text alignment for title text. One of `"left"`, `"center"`, or `"right"`.
51
+ */
52
+ align?: Align;
53
+
54
+ /**
55
+ * Angle in degrees of title and subtitle text.
56
+ */
57
+ angle?: number;
58
+
59
+ /**
60
+ * Vertical text baseline for title and subtitle text. One of `"alphabetic"` (default), `"top"`, `"middle"`, or `"bottom"`.
61
+ */
62
+ baseline?: Baseline;
63
+
64
+ /**
65
+ * Delta offset for title and subtitle text x-coordinate.
66
+ */
67
+ dx?: number;
68
+
69
+ /**
70
+ * Delta offset for title and subtitle text y-coordinate.
71
+ */
72
+ dy?: number;
73
+
74
+ // ---------- Title Text ----------
75
+ /**
76
+ * Text color for title text.
77
+ */
78
+ color?: string;
79
+
80
+ /**
81
+ * Font name for title text.
82
+ */
83
+ font?: string;
84
+
85
+ /**
86
+ * Font size in pixels for title text.
87
+ *
88
+ * @minimum 0
89
+ */
90
+ fontSize?: number;
91
+
92
+ /**
93
+ * Font style for title text.
94
+ */
95
+ fontStyle?: FontStyle;
96
+
97
+ /**
98
+ * Font weight for title text.
99
+ * This can be either a string (e.g `"bold"`, `"normal"`) or a number (`100`, `200`, `300`, ..., `900` where `"normal"` = `400` and `"bold"` = `700`).
100
+ */
101
+ fontWeight?: FontWeight;
102
+ }
@@ -14,6 +14,7 @@ import {
14
14
  MarkType,
15
15
  RectProps,
16
16
  } from "./mark";
17
+ import { Title } from "./title";
17
18
 
18
19
  export interface SizeDef {
19
20
  /** Size in pixels */
@@ -55,7 +56,7 @@ export type Paddings = Partial<Record<Side, number>>;
55
56
 
56
57
  export type PaddingConfig = Paddings | number;
57
58
 
58
- export interface ViewConfig extends RectProps, FillAndStrokeProps {
59
+ export interface ViewBackground extends RectProps, FillAndStrokeProps {
59
60
  // TODO: style?: string | string[];
60
61
 
61
62
  // TODO: Move to FillAndStrokeProps or something
@@ -78,7 +79,7 @@ export interface ViewSpecBase extends ResolveSpec {
78
79
  data?: Data;
79
80
  transform?: TransformParams[];
80
81
  encoding?: Encoding;
81
- title?: string;
82
+ title?: string | Title;
82
83
 
83
84
  /**
84
85
  * A description of the view. Multiple lines can be provided as an array.
@@ -115,7 +116,7 @@ export interface ViewSpecBase extends ResolveSpec {
115
116
  }
116
117
 
117
118
  export interface UnitSpec extends ViewSpecBase, AggregateSamplesSpec {
118
- view?: ViewConfig;
119
+ view?: ViewBackground;
119
120
  mark: MarkType | MarkConfigAndType;
120
121
  }
121
122
 
@@ -125,7 +126,7 @@ export interface AggregateSamplesSpec {
125
126
  }
126
127
 
127
128
  export interface LayerSpec extends ViewSpecBase, AggregateSamplesSpec {
128
- view?: ViewConfig;
129
+ view?: ViewBackground;
129
130
  layer: (LayerSpec | UnitSpec)[];
130
131
  }
131
132
 
@@ -218,4 +219,5 @@ export interface HConcatSpec extends ConcatBase {
218
219
 
219
220
  export interface ConcatSpec extends ConcatBase {
220
221
  concat: (ViewSpec | ImportSpec)[];
222
+ columns: number;
221
223
  }
@@ -47,10 +47,11 @@ export default async function dataTooltipHandler(datum, mark, params) {
47
47
  </table>
48
48
  `;
49
49
 
50
- const title = mark.unitView.spec.title
50
+ const titleText = mark.unitView.getTitleText();
51
+ const title = titleText
51
52
  ? html`
52
53
  <div class="title">
53
- <strong>${mark.unitView.spec.title}</strong>
54
+ <strong>${titleText}</strong>
54
55
  </div>
55
56
  `
56
57
  : "";