feat(treemap.breadcrumb): add `emphasis` state (#17242) master
authorsusiwen8 <susiwen8@gmail.com>
Tue, 21 Jun 2022 07:14:29 +0000 (15:14 +0800)
committerGitHub <noreply@github.com>
Tue, 21 Jun 2022 07:14:29 +0000 (15:14 +0800)
* feat(treemap.breadcrumb): add `emphasis` state

* feat(treemap.breadcrumb): enbale `emphasis` by default

* feat(treemap.breadcrumb): more text style

* chore: remove unnecessary code

* chore: simplify code

* chore: cache emphasis item style

src/chart/treemap/Breadcrumb.ts
src/chart/treemap/TreemapSeries.ts
src/data/DataStore.ts
src/data/Graph.ts
src/data/Tree.ts
src/model/Global.ts
src/visual/VisualMapping.ts
test/treemap-simple.html

index 6dd35c5df2e80983e6166559a1931c7325e7800b..0875c4a2b337bed0345bbe6a0e645264e2c13114 100644 (file)
@@ -29,7 +29,8 @@ import { ZRElementEvent, BoxLayoutOptionMixin, ECElement } from '../../util/type
 import Element from 'zrender/src/Element';
 import Model from '../../model/Model';
 import { convertOptionIdName } from '../../util/model';
-import { Z2_EMPHASIS_LIFT } from '../../util/states';
+import { toggleHoverEmphasis, Z2_EMPHASIS_LIFT } from '../../util/states';
+import { createTextStyle } from '../../label/labelStyle';
 
 const TEXT_PADDING = 8;
 const ITEM_GAP = 8;
@@ -55,6 +56,7 @@ interface LayoutParam {
 }
 
 type BreadcrumbItemStyleModel = Model<TreemapSeriesOption['breadcrumb']['itemStyle']>;
+type BreadcrumbEmphasisItemStyleModel = Model<TreemapSeriesOption['breadcrumb']['emphasis']>;
 type BreadcrumbTextStyleModel = Model<TreemapSeriesOption['breadcrumb']['itemStyle']['textStyle']>;
 
 class Breadcrumb {
@@ -81,8 +83,9 @@ class Breadcrumb {
         }
 
         const normalStyleModel = model.getModel('itemStyle');
-        // let emphasisStyleModel = model.getModel('emphasis.itemStyle');
+        const emphasisModel = model.getModel('emphasis');
         const textStyleModel = normalStyleModel.getModel('textStyle');
+        const emphasisTextStyleModel = emphasisModel.getModel(['itemStyle', 'textStyle']);
 
         const layoutParam: LayoutParam = {
             pos: {
@@ -101,7 +104,10 @@ class Breadcrumb {
         };
 
         this._prepare(targetNode, layoutParam, textStyleModel);
-        this._renderContent(seriesModel, layoutParam, normalStyleModel, textStyleModel, onSelect);
+        this._renderContent(
+            seriesModel, layoutParam, normalStyleModel,
+            emphasisModel, textStyleModel, emphasisTextStyleModel, onSelect
+        );
 
         layout.positionElement(thisGroup, layoutParam.pos, layoutParam.box);
     }
@@ -134,7 +140,9 @@ class Breadcrumb {
         seriesModel: TreemapSeriesModel,
         layoutParam: LayoutParam,
         normalStyleModel: BreadcrumbItemStyleModel,
+        emphasisModel: BreadcrumbEmphasisItemStyleModel,
         textStyleModel: BreadcrumbTextStyleModel,
+        emphasisTextStyleModel: BreadcrumbTextStyleModel,
         onSelect: OnSelectCallback
     ) {
         // Start rendering.
@@ -144,6 +152,7 @@ class Breadcrumb {
         const availableSize = layout.getAvailableSize(layoutParam.pos, layoutParam.box);
         let totalWidth = layoutParam.totalWidth;
         const renderList = layoutParam.renderList;
+        const emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();
 
         for (let i = renderList.length - 1; i >= 0; i--) {
             const item = renderList[i];
@@ -172,11 +181,7 @@ class Breadcrumb {
                     }
                 ),
                 textContent: new graphic.Text({
-                    style: {
-                        text,
-                        fill: textStyleModel.getTextColor(),
-                        font: textStyleModel.getFont()
-                    }
+                    style: createTextStyle(textStyleModel, { text })
                 }),
                 textConfig: {
                     position: 'inside'
@@ -185,7 +190,11 @@ class Breadcrumb {
                 onclick: curry(onSelect, itemNode)
             });
             (el as ECElement).disableLabelAnimation = true;
-
+            el.getTextContent().ensureState('emphasis').style = createTextStyle(emphasisTextStyleModel, { text });
+            el.ensureState('emphasis').style = emphasisItemStyle;
+            toggleHoverEmphasis(
+                el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')
+            );
             this.group.add(el);
 
             packEventData(el, seriesModel, itemNode);
index 15c0a5e9a2ddaaacbaeee09359bbdf05b2c48b22..2e5f22835f38801d5147411b64e87a79692b6eaa 100644 (file)
@@ -36,7 +36,8 @@ import {
     DecalObject,
     SeriesLabelOption,
     DefaultEmphasisFocus,
-    AriaOptionMixin
+    AriaOptionMixin,
+    BlurScope
 } from '../../util/types';
 import GlobalModel from '../../model/Global';
 import { LayoutRect } from '../../util/layout';
@@ -202,6 +203,9 @@ export interface TreemapSeriesOption
         itemStyle?: BreadcrumbItemStyleOption
 
         emphasis?: {
+            disabled?: boolean
+            focus?: DefaultEmphasisFocus
+            blurScope?: BlurScope
             itemStyle?: BreadcrumbItemStyleOption
         }
     }
@@ -265,6 +269,11 @@ class TreemapSeriesModel extends SeriesModel<TreemapSeriesOption> {
                 textStyle: {
                     color: '#fff'
                 }
+            },
+            emphasis: {
+                itemStyle: {
+                    color: 'rgba(0,0,0,0.9)' //'#5793f3',
+                }
             }
         },
         label: {
index b839d8b0f3c60612b9e4452e6ea9c7120000a7a1..bb9dcf179c269e0b113f0bab282c530cb9ea6fe4 100644 (file)
@@ -448,7 +448,7 @@ class DataStore {
     }
 
     getValues(idx: number): ParsedValue[];
-    getValues(dimensions: readonly DimensionIndex[], idx?: number): ParsedValue[]
+    getValues(dimensions: readonly DimensionIndex[], idx?: number): ParsedValue[];
     getValues(dimensions: readonly DimensionIndex[] | number, idx?: number): ParsedValue[] {
         const values = [];
         let dimArr: DimensionIndex[] = [];
index a250ad9632ebc59cdbe396a27dbdcdaea22d8d16..f7939a530485c2395a53263190a1e06496d402aa 100644 (file)
@@ -360,8 +360,8 @@ class GraphNode {
     }
 
     // TODO: TYPE Same type with Model#getModel
-    getModel<T = unknown>(): Model<T>
-    getModel<T = unknown, S extends keyof T= keyof T>(path: S): Model<T[S]>
+    getModel<T = unknown>(): Model<T>;
+    getModel<T = unknown, S extends keyof T= keyof T>(path: S): Model<T[S]>;
     getModel<T = unknown>(path?: string): Model {
         if (this.dataIndex < 0) {
             return;
@@ -410,8 +410,8 @@ class GraphEdge {
         this.dataIndex = dataIndex == null ? -1 : dataIndex;
     }
 
-    getModel<T = unknown>(): Model<T>
-    getModel<T = unknown, S extends keyof T= keyof T>(path: S): Model<T[S]>
+    getModel<T = unknown>(): Model<T>;
+    getModel<T = unknown, S extends keyof T= keyof T>(path: S): Model<T[S]>;
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
     getModel<T = unknown>(path?: string): Model {
         if (this.dataIndex < 0) {
index ad7ae4241c09630340fb89ee445327e4b7caa82f..8467084945d219723d2ee1e1b977740f7a8d42f4 100644 (file)
@@ -98,9 +98,9 @@ export class TreeNode {
      * @param cb If in preorder and return false,
      *                      its subtree will not be visited.
      */
-    eachNode<Ctx>(options: TreeTraverseOrder, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void
-    eachNode<Ctx>(options: TreeTraverseOption, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void
-    eachNode<Ctx>(cb: TreeTraverseCallback<Ctx>, context?: Ctx): void
+    eachNode<Ctx>(options: TreeTraverseOrder, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void;
+    eachNode<Ctx>(options: TreeTraverseOption, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void;
+    eachNode<Ctx>(cb: TreeTraverseCallback<Ctx>, context?: Ctx): void;
     eachNode<Ctx>(
         options: TreeTraverseOrder | TreeTraverseOption | TreeTraverseCallback<Ctx>,
         cb?: TreeTraverseCallback<Ctx> | Ctx,
@@ -225,7 +225,7 @@ export class TreeNode {
         return this.hostTree.data.getItemLayout(this.dataIndex);
     }
 
-    getModel<T = unknown>(): Model<T>
+    getModel<T = unknown>(): Model<T>;
     // @depcrecated
     // getModel<T = unknown, S extends keyof T = keyof T>(path: S): Model<T[S]>
     // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -251,8 +251,8 @@ export class TreeNode {
      *  });
      */
     // TODO: TYPE
-    setVisual(key: string, value: any): void
-    setVisual(obj: Dictionary<any>): void
+    setVisual(key: string, value: any): void;
+    setVisual(obj: Dictionary<any>): void;
     setVisual(key: string | Dictionary<any>, value?: any) {
         this.dataIndex >= 0
             && this.hostTree.data.setItemVisual(this.dataIndex, key as any, value);
@@ -353,9 +353,9 @@ class Tree<HostModel extends Model = Model, LevelOption = any> {
      * @param cb
      * @param context
      */
-    eachNode<Ctx>(options: TreeTraverseOrder, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void
-    eachNode<Ctx>(options: TreeTraverseOption, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void
-    eachNode<Ctx>(cb: TreeTraverseCallback<Ctx>, context?: Ctx): void
+    eachNode<Ctx>(options: TreeTraverseOrder, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void;
+    eachNode<Ctx>(options: TreeTraverseOption, cb: TreeTraverseCallback<Ctx>, context?: Ctx): void;
+    eachNode<Ctx>(cb: TreeTraverseCallback<Ctx>, context?: Ctx): void;
     eachNode<Ctx>(
         options: TreeTraverseOrder | TreeTraverseOption | TreeTraverseCallback<Ctx>,
         cb?: TreeTraverseCallback<Ctx> | Ctx,
index d4777a4ee9ab4db6dc215a5df3fb02622ed5b2bc..cadc98b20df074f1c42f38f241b3e2e014fa12e6 100644 (file)
@@ -696,17 +696,17 @@ echarts.use([${seriesImportName}]);`);
     eachComponent<T>(
         cb: EachComponentAllCallback,
         context?: T
-    ): void
+    ): void;
     eachComponent<T>(
         mainType: string,
         cb: EachComponentInMainTypeCallback,
         context?: T
-    ): void
+    ): void;
     eachComponent<T>(
         mainType: QueryConditionKindA,
         cb: EachComponentInMainTypeCallback,
         context?: T
-    ): void
+    ): void;
     eachComponent<T>(
         mainType: string | QueryConditionKindA | EachComponentAllCallback,
         cb?: EachComponentInMainTypeCallback | T,
index 8898bc7b0639b0430981c1236e3108bbc34dcaa8..f964e3fb0a5dcc2a1428adfcb1e6a0225ff9e444 100644 (file)
@@ -377,13 +377,13 @@ class VisualMapping {
         }
     }
 
-    static mapVisual<Ctx, T>(visual: T, callback: (visual: T, key?: string | number) => T, context?: Ctx): T
-    static mapVisual<Ctx, T>(visual: T[], callback: (visual: T, key?: string | number) => T[], context?: Ctx): T[]
+    static mapVisual<Ctx, T>(visual: T, callback: (visual: T, key?: string | number) => T, context?: Ctx): T;
+    static mapVisual<Ctx, T>(visual: T[], callback: (visual: T, key?: string | number) => T[], context?: Ctx): T[];
     static mapVisual<Ctx, T>(
         visual: Dictionary<T>,
         callback: (visual: T, key?: string | number) => Dictionary<T>,
         context?: Ctx
-    ): Dictionary<T>
+    ): Dictionary<T>;
     static mapVisual<Ctx, T>(
         visual: T | T[] | Dictionary<T>,
         callback: (visual: T, key?: string | number) => T | T[] | Dictionary<T>,
index c71b8122ca7f8dce8512c3b9bcb54bef42a62f71..37c7aa2ffc5f80a24e920bb63212683e45657424 100644 (file)
@@ -66,6 +66,15 @@ under the License.
                             }
                         },
                         breadcrumb: {
+                            emphasis: {
+                                itemStyle: {
+                                    color: 'blue',
+                                    opacity: 0.6,
+                                    textStyle: {
+                                        color: 'green'
+                                    }
+                                },
+                            }
                         },
                         levels: [
                             {