You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by ov...@apache.org on 2021/03/17 10:10:07 UTC
[echarts] 05/10: WIP(legend): refactor and use fixed line width
This is an automated email from the ASF dual-hosted git repository.
ovilia pushed a commit to branch fix-legend
in repository https://gitbox.apache.org/repos/asf/echarts.git
commit 39d4e530f29db2129cf154dd1b23226c686bb2d3
Author: Ovilia <zw...@gmail.com>
AuthorDate: Tue Mar 16 15:50:39 2021 +0800
WIP(legend): refactor and use fixed line width
---
src/chart/line/install.ts | 21 ++--
src/component/legend/LegendModel.ts | 78 ++++++++++--
src/component/legend/LegendView.ts | 230 +++++++++++++++++++++++-------------
src/model/mixin/lineStyle.ts | 2 +-
4 files changed, 227 insertions(+), 104 deletions(-)
diff --git a/src/chart/line/install.ts b/src/chart/line/install.ts
index 35147e2..b5dd22f 100644
--- a/src/chart/line/install.ts
+++ b/src/chart/line/install.ts
@@ -39,19 +39,18 @@ export function install(registers: EChartsExtensionInstallRegisters) {
seriesType: 'line',
reset: function (seriesModel: LineSeriesModel) {
// Visual coding for legend
- const lineStyle = seriesModel.getModel('lineStyle');
- const itemStyle = seriesModel.getModel('itemStyle');
- const color = itemStyle ? itemStyle.get('color') : null;
- const borderColor = itemStyle ? itemStyle.get('borderColor') : null;//TODO
- let lineColor = lineStyle && lineStyle.get('color') || color;
-
+ const lineStyle = seriesModel.getModel('lineStyle').getLineStyle();
+ const itemStyle = seriesModel.getModel('itemStyle').getItemStyle();
+ const color = itemStyle && itemStyle.fill;
+ console.log(itemStyle, lineStyle);
if (lineStyle) {
- seriesModel.getData().setVisual('legendSymbolStyle', {
- borderColor,
- horizontalLineColor: lineColor,
- horizontalLineWidth: lineStyle.get('width')
- });
+ lineStyle.stroke = lineStyle.stroke || color;
}
+
+ seriesModel.getData().setVisual('legendSymbolStyle', {
+ itemStyle,
+ lineStyle
+ });
}
});
diff --git a/src/component/legend/LegendModel.ts b/src/component/legend/LegendModel.ts
index e603ce2..b595dc1 100644
--- a/src/component/legend/LegendModel.ts
+++ b/src/component/legend/LegendModel.ts
@@ -26,14 +26,17 @@ import {
BoxLayoutOptionMixin,
BorderOptionMixin,
ColorString,
- ItemStyleOption,
LabelOption,
LayoutOrient,
CommonTooltipOption,
- ZRColor
+ ZRColor,
+ DecalObject,
+ ZRLineType
} from '../../util/types';
import { Dictionary } from 'zrender/src/core/types';
import GlobalModel from '../../model/Global';
+import { ItemStyleProps } from '../../model/mixin/itemStyle';
+import { LineStyleProps } from './../../model/mixin/lineStyle';
type LegendDefaultSelectorOptionsProps = {
type: string;
@@ -60,6 +63,38 @@ export interface LegendSelectorButtonOption {
title?: string
}
+export interface LegendItemStyleOption {
+ color?: ZRColor | 'inherit'
+ opacity?: number | 'inherit'
+ decal?: DecalObject | 'none' | 'inherit'
+ shadowBlur?: number | 'inherit'
+ shadowColor?: ColorString | 'inherit'
+ shadowOffsetX?: number | 'inherit'
+ shadowOffsetY?: number | 'inherit'
+ borderColor?: ZRColor | 'inherit'
+ borderWidth?: number | 'inherit'
+ borderType?: ZRLineType | 'inherit'
+ borderCap?: CanvasLineCap | 'inherit'
+ borderJoin?: CanvasLineJoin | 'inherit'
+ borderDashOffset?: number | 'inherit'
+ borderMiterLimit?: number | 'inherit'
+}
+
+export interface LegendLineStyleOption {
+ width?: number | 'inherit' | 'auto'
+ color?: ZRColor | 'inherit'
+ opacity?: number | 'inherit'
+ type?: ZRLineType | 'inherit'
+ cap?: CanvasLineCap | 'inherit'
+ join?: CanvasLineJoin | 'inherit'
+ dashOffset?: number | 'inherit'
+ miterLimit?: number | 'inherit'
+ shadowBlur?: number | 'inherit'
+ shadowColor?: ColorString | 'inherit'
+ shadowOffsetX?: number | 'inherit'
+ shadowOffsetY?: number | 'inherit'
+}
+
export interface LegendStyleOption {
/**
* Icon of the legend items.
@@ -81,7 +116,9 @@ export interface LegendStyleOption {
*/
formatter?: string | ((name: string) => string)
- itemStyle?: ItemStyleOption
+ itemStyle?: LegendItemStyleOption
+
+ lineStyle?: LegendLineStyleOption
textStyle?: LabelOption
@@ -104,9 +141,9 @@ export interface LegendTooltipFormatterParams {
$vars: ['name']
}
-export interface LegendSymbolStyleOption extends ItemStyleOption {
- horizontalLineColor?: ZRColor,
- horizontalLineWidth?: number
+export interface LegendSymbolStyleOption {
+ itemStyle?: ItemStyleProps,
+ lineStyle?: LineStyleProps
}
export interface LegendOption extends ComponentOption, LegendStyleOption,
@@ -418,7 +455,34 @@ class LegendModel<Ops extends LegendOption = LegendOption> extends ComponentMode
inactiveBorderColor: '#ccc',
itemStyle: {
- // borderWidth: 0
+ color: 'inherit',
+ opacity: 'inherit',
+ decal: 'inherit',
+ shadowBlur: 0,
+ shadowColor: 'inherit',
+ shadowOffsetX: 'inherit',
+ shadowOffsetY: 'inherit',
+ borderColor: 'inherit',
+ borderWidth: 'inherit',
+ borderCap: 'inherit',
+ borderJoin: 'inherit',
+ borderDashOffset: 'inherit',
+ borderMiterLimit: 'inherit'
+ },
+
+ lineStyle: {
+ width: 'auto',
+ color: 'inherit',
+ opacity: 'inherit',
+ type: 'inherit',
+ cap: 'inherit',
+ join: 'inherit',
+ dashOffset: 'inherit',
+ miterLimit: 'inherit',
+ shadowBlur: 0,
+ shadowColor: 'inherit',
+ shadowOffsetX: 'inherit',
+ shadowOffsetY: 'inherit'
},
textStyle: {
diff --git a/src/component/legend/LegendView.ts b/src/component/legend/LegendView.ts
index 1fc9abf..7449414 100644
--- a/src/component/legend/LegendView.ts
+++ b/src/component/legend/LegendView.ts
@@ -25,7 +25,7 @@ import {setLabelStyle, createTextStyle} from '../../label/labelStyle';
import {makeBackground} from '../helper/listComponent';
import * as layoutUtil from '../../util/layout';
import ComponentView from '../../view/Component';
-import LegendModel, { LegendOption, LegendSelectorButtonOption, LegendSymbolStyleOption, LegendTooltipFormatterParams } from './LegendModel';
+import LegendModel, { LegendItemStyleOption, LegendLineStyleOption, LegendOption, LegendSelectorButtonOption, LegendStyleOption, LegendSymbolStyleOption, LegendTooltipFormatterParams } from './LegendModel';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import {
@@ -37,7 +37,9 @@ import {
CommonTooltipOption,
ColorString,
SeriesOption,
- SymbolOptionMixin
+ SymbolOptionMixin,
+ LineStyleOption,
+ DecalObject
} from '../../util/types';
import Model from '../../model/Model';
import Displayable, { DisplayableState } from 'zrender/src/graphic/Displayable';
@@ -45,6 +47,11 @@ import { PathStyleProps } from 'zrender/src/graphic/Path';
import { parse, stringify } from 'zrender/src/tool/color';
import {PatternObject} from 'zrender/src/graphic/Pattern';
import {SeriesModel} from '../../echarts';
+import linesLayout from '../../chart/lines/linesLayout';
+import {LineStyleProps} from '../../model/mixin/lineStyle';
+import {ItemStyleProps} from '../../model/mixin/itemStyle';
+import {number} from '../../export/api';
+import makeStyleMapper from '../../model/mixin/makeStyleMapper';
const curry = zrUtil.curry;
const each = zrUtil.each;
@@ -202,16 +209,14 @@ class LegendView extends ComponentView {
// Legend to control series.
if (seriesModel) {
const data = seriesModel.getData();
- const legendSymbolStyle = data.getVisual('legendSymbolStyle') || {};
+ const lineVisualStyle = (data.getVisual('legendSymbolStyle') || {}).lineStyle;
/**
* `data.getVisual('style')` may be the color from the register
* in series. For example, for line series,
*/
- const style = zrUtil.extend(
- zrUtil.extend({}, data.getVisual('style')),
- legendItemStyle
- );
+ const style = data.getVisual('style');
+ console.log(style, lineVisualStyle);
// Using rect symbol defaultly
const legendSymbolType = data.getVisual('legendSymbol') || 'roundRect';
@@ -222,7 +227,7 @@ class LegendView extends ComponentView {
name, dataIndex, itemModel, legendModel,
legendSymbolType, symbolType, symbolSize,
itemAlign,
- legendSymbolStyle, style, true, selectMode
+ lineVisualStyle, style, true, selectMode
);
itemGroup.on('click', curry(dispatchSelectAction, name, null, api, excludeSeriesId))
@@ -335,8 +340,8 @@ class LegendView extends ComponentView {
symbolType: string,
symbolSize: number | number[],
itemAlign: LegendOption['align'],
- legendSymbolStyle: LegendSymbolStyleOption,
- dataItemStyle: PathStyleProps,
+ lineVisualStyle: LineStyleProps,
+ itemVisualStyle: PathStyleProps,
isColorBySeries: boolean,
selectMode: LegendOption['selectedMode']
) {
@@ -352,24 +357,11 @@ class LegendView extends ComponentView {
const inactiveColor = itemModel.get('inactiveColor');
const inactiveBorderColor = itemModel.get('inactiveBorderColor');
const symbolKeepAspect = itemModel.get('symbolKeepAspect');
- const legendModelItemStyle = itemModel.getModel('itemStyle');
-
- let color = dataItemStyle.fill;
- if (!isColorBySeries) {
- const colorArr = parse(color as ColorString);
- // Color may be set to transparent in visualMap when data is out of range.
- // Do not show nothing.
- if (colorArr && colorArr[3] === 0) {
- colorArr[3] = 0.2;
- // TODO color is set to 0, 0, 0, 0. Should show correct RGBA
- color = stringify(colorArr, 'rgba');
- }
- }
+
+ const style = getLegendStyle(itemModel, lineVisualStyle, itemVisualStyle, isColorBySeries);
+ console.log(style)
symbolType = symbolType || 'roundRect';
- const borderColor = dataItemStyle[symbolType.indexOf('empty') > -1 ? 'fill' : 'stroke'];
- const borderWidth = dataItemStyle.lineWidth;
- const decal = dataItemStyle.decal;
const itemGroup = new Group();
@@ -387,55 +379,17 @@ class LegendView extends ComponentView {
// At least show one symbol, can't be all none
&& ((symbolType !== legendSymbolType) || symbolType === 'none');
- // Draw line if hasHorizontalLine, else draw symbol
- let legendBorderColor = isSelected
- ? (hasHorizontalLine
- ? legendSymbolStyle.horizontalLineColor
- : borderColor
+ // Draw line
+ if (legendSymbolType === 'line' || itemIcon === 'line') {
+ itemGroup.add(
+ createHorizontalLine(itemWidth, itemHeight, style.lineStyle)
)
- : inactiveBorderColor;
- legendBorderColor = legendBorderColor === 'auto'
- ? color : legendBorderColor;
- const legendBorderWidth = hasHorizontalLine
- ? (legendSymbolStyle.horizontalLineWidth == null
- ? borderWidth
- : legendSymbolStyle.horizontalLineWidth)
- : borderWidth;
- const legendSymbol = createSymbol(
- legendSymbolType,
- 0,
- 0,
- itemWidth,
- itemHeight,
- legendBorderColor,
- // symbolKeepAspect default true for legend
- symbolKeepAspect == null ? true : symbolKeepAspect
- );
- itemGroup.add(
- setSymbolStyle(legendSymbol, legendSymbolType, null, legendBorderWidth, decal)
- );
+ }
- // Draw symbol if hasHorizontalLine
- if (hasHorizontalLine) {
- const size = symbolSize == null
- ? itemHeight * 0.8
- : Math.min(itemHeight, symbolSize as number);
- if (symbolType === 'none') {
- symbolType = 'circle';
- }
- const legendSymbolCenter = createSymbol(
- symbolType,
- (itemWidth - size) / 2,
- (itemHeight - size) / 2,
- size,
- size,
- isSelected ? color : inactiveColor,
- // symbolKeepAspect default true for legend
- symbolKeepAspect == null ? true : symbolKeepAspect
- );
- // Put symbol in the center
+ // Put symbol in the center
+ if (itemIcon !== 'line') {
itemGroup.add(
- setSymbolStyle(legendSymbolCenter, symbolType, borderColor, borderWidth, decal)
+ createItem(symbolType, symbolSize, symbolKeepAspect, itemWidth, itemHeight, style.itemStyle)
);
}
@@ -583,23 +537,129 @@ class LegendView extends ComponentView {
}
-function setSymbolStyle(
- symbol: graphic.Path | graphic.Image,
+function getLegendStyle(
+ legendModel: LegendModel['_data'][number],
+ lineVisualStyle: LineStyleProps,
+ itemVisualStyle: PathStyleProps,
+ isColorBySeries: boolean
+) {
+ let color = itemVisualStyle.fill;
+ if (!isColorBySeries) {
+ const colorArr = parse(color as ColorString);
+ // Color may be set to transparent in visualMap when data is out of range.
+ // Do not show nothing.
+ if (colorArr && colorArr[3] === 0) {
+ colorArr[3] = 0.2;
+ // TODO color is set to 0, 0, 0, 0. Should show correct RGBA
+ color = stringify(colorArr, 'rgba');
+ }
+ }
+
+ /**
+ * Use series style if is inherit;
+ * elsewise, use legend style
+ */
+
+ // itemStyle
+ const legendItemModel = legendModel.getModel('itemStyle') as Model<LegendItemStyleOption>;
+ const itemProperties = [
+ ['fill', 'color'],
+ ['lineWidth', 'borderWidth'],
+ ['stroke', 'borderColor'],
+ ['width', 'width'],
+ ['opacity', 'opacity']
+ ];
+ const itemStyle: PathStyleProps = {};
+ for (let i = 0; i < itemProperties.length; ++i) {
+ const propName = itemProperties[i][1] as keyof LegendItemStyleOption;
+ const visualName = itemProperties[i][0] as keyof PathStyleProps;
+ const value = legendItemModel.getShallow(propName) as LegendItemStyleOption[keyof LegendItemStyleOption];
+ if (value === 'inherit') {
+ (itemStyle as any)[visualName] = itemVisualStyle[visualName];
+ }
+ else {
+ (itemStyle as any)[visualName] = value;
+ }
+ }
+
+ // lineStyle
+ const legendLineModel = legendModel.getModel('lineStyle') as Model<LegendLineStyleOption>;
+ const lineProperties = [
+ ['stroke', 'color'],
+ ['lineWidth', 'width']
+ ];
+ const lineStyle: LineStyleProps = {};
+ for (let i = 0; i < lineProperties.length; ++i) {
+ const propName = lineProperties[i][1] as keyof LegendLineStyleOption;
+ const visualName = lineProperties[i][0] as keyof LineStyleProps;
+ const value = legendLineModel.getShallow(propName) as LegendLineStyleOption[keyof LegendLineStyleOption];
+ if (value === 'inherit') {
+ (lineStyle as any)[visualName] = lineVisualStyle[visualName];
+ }
+ else if (value === 'auto' && visualName === 'lineWidth') {
+ // If lineStyle.width is 'auto', it is set to be 2 if series has border
+ lineStyle.lineWidth = lineVisualStyle.lineWidth > 0 ? 2 : 0;
+ }
+ else {
+ (lineStyle as any)[visualName] = value;
+ }
+ }
+
+ // Fix auto color to real color
+ (itemStyle.fill === 'auto') && (itemStyle.fill = color);
+ (itemStyle.stroke === 'auto') && (itemStyle.stroke = color);
+ (lineStyle.stroke === 'auto') && (lineStyle.stroke = color);
+
+ return { itemStyle, lineStyle };
+}
+
+function createHorizontalLine(
+ itemWidth: number,
+ itemHeight: number,
+ style: LineStyleProps
+) {
+ const symbol = createSymbol(
+ 'line',
+ 0,
+ 0,
+ itemWidth,
+ itemHeight,
+ style.stroke,
+ false
+ );
+ symbol.setStyle(style);
+ return symbol;
+}
+
+function createItem(
symbolType: string,
- borderColor: ZRColor,
- borderWidth: number,
- decal: PatternObject
+ symbolSize: number | number[],
+ symbolKeepAspect: boolean,
+ itemWidth: number,
+ itemHeight: number,
+ style: ItemStyleProps
) {
- const style = (symbol as graphic.Path).style;
- if (symbolType === 'line') {
- style.stroke = style.fill;
- style.fill = 'none';
+ if (symbolType === 'none') {
+ symbolType = 'circle';
}
- else {
- style.decal = decal;
- borderColor && (style.stroke = borderColor);
+ const size = symbolSize == null
+ ? itemHeight
+ : Math.min(itemHeight, symbolSize as number);
+ const symbol = createSymbol(
+ symbolType,
+ (itemWidth - size) / 2,
+ (itemHeight - size) / 2,
+ size,
+ size,
+ style.fill,
+ // symbolKeepAspect default true for legend
+ symbolKeepAspect == null ? true : symbolKeepAspect
+ );
+ symbol.setStyle(style);
+ if (symbolType.indexOf('empty') > -1) {
+ symbol.style.stroke = symbol.style.fill;
+ symbol.style.fill = '#fff';
}
- style.lineWidth = borderWidth;
return symbol;
}
diff --git a/src/model/mixin/lineStyle.ts b/src/model/mixin/lineStyle.ts
index 168102e..712b2fc 100644
--- a/src/model/mixin/lineStyle.ts
+++ b/src/model/mixin/lineStyle.ts
@@ -54,7 +54,7 @@ type LineStyleKeys = 'lineWidth'
| 'lineJoin'
| 'miterLimit';
-type LineStyleProps = Pick<PathStyleProps, LineStyleKeys>;
+export type LineStyleProps = Pick<PathStyleProps, LineStyleKeys>;
class LineStyleMixin {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org