未验证 提交 9963aa4f 编写于 作者: S sushuang 提交者: GitHub

Merge pull request #12775 from apache/custom-series-enhance

Custom series enhancement (for-next)
此差异已折叠。
......@@ -42,11 +42,18 @@ class RadiusAxisView extends AxisView {
axisPointerClass = 'PolarAxisPointer';
private _axisGroup: graphic.Group;
render(radiusAxisModel: RadiusAxisModel, ecModel: GlobalModel) {
this.group.removeAll();
if (!radiusAxisModel.get('show')) {
return;
}
const oldAxisGroup = this._axisGroup;
const newAxisGroup = this._axisGroup = new graphic.Group();
this.group.add(newAxisGroup);
const radiusAxis = radiusAxisModel.axis;
const polar = radiusAxis.polar;
const angleAxis = polar.getAngleAxis();
......@@ -58,7 +65,9 @@ class RadiusAxisView extends AxisView {
const layout = layoutAxis(polar, radiusAxisModel, axisAngle);
const axisBuilder = new AxisBuilder(radiusAxisModel, layout);
zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
this.group.add(axisBuilder.getGroup());
newAxisGroup.add(axisBuilder.getGroup());
graphic.groupTransition(oldAxisGroup, newAxisGroup, radiusAxisModel);
zrUtil.each(selfBuilderAttrs, function (name) {
if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) {
......
......@@ -185,7 +185,7 @@ class PiecewiseModel extends VisualMapModel<PiecewiseVisualMapOption> {
const isCategory = this.isCategory();
zrUtil.each(option.pieces, function (piece) {
zrUtil.each(visualTypes, function (visualType) {
zrUtil.each(visualTypes, function (visualType: BuiltinVisualProperty) {
if (piece.hasOwnProperty(visualType)) {
visualTypesInPieces[visualType] = 1;
}
......
......@@ -26,6 +26,7 @@ import { BoundingRect } from '../util/graphic';
import { MatrixArray } from 'zrender/src/core/matrix';
import ComponentModel from '../model/Component';
import { RectLike } from 'zrender/src/core/BoundingRect';
import { PrepareCustomInfo } from '../chart/custom';
export interface CoordinateSystemCreator {
......@@ -151,6 +152,8 @@ export interface CoordinateSystem {
// Currently only Cartesian2D implements it.
// But if other coordinate systems implement it, should follow this signature.
getAxesByScale?: (scaleType: string) => Axis[];
prepareCustoms?: PrepareCustomInfo;
}
/**
......
......@@ -24,6 +24,7 @@ import RadiusAxis from './RadiusAxis';
function dataToCoordSize(this: Polar, dataSize: number[], dataItem: number[]) {
// dataItem is necessary in log axis.
dataItem = dataItem || [0, 0];
return zrUtil.map(['Radius', 'Angle'], function (dim, dimIdx) {
const getterName = 'get' + dim + 'Axis' as 'getAngleAxis'| 'getRadiusAxis';
// TODO: TYPE Check Angle Axis
......
......@@ -1802,6 +1802,9 @@ class ECharts extends Eventful {
};
updateZ = function (model: ComponentModel, view: ComponentView | ChartView): void {
if (model.preventAutoZ) {
return;
}
const z = model.get('z');
const zlevel = model.get('zlevel');
// Set z and zlevel
......@@ -1816,6 +1819,7 @@ class ECharts extends Eventful {
textContent.z = el.z;
textContent.zlevel = el.zlevel;
// lift z2 of text content
// TODO if el.emphasis.z2 is spcefied, what about textContent.
textContent.z2 = el.z2 + 1;
}
}
......
......@@ -127,6 +127,11 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
*/
static layoutMode: ComponentLayoutMode | ComponentLayoutMode['type'];
/**
* Prevent from auto set z, zlevel, z2 by the framework.
*/
preventAutoZ: boolean;
// Injectable properties:
__viewId: string;
......
......@@ -44,7 +44,7 @@ type ItemStyleKeys = 'fill'
| 'shadowOffsetY'
| 'shadowColor';
type ItemStyleProps = Pick<PathStyleProps, ItemStyleKeys>;
export type ItemStyleProps = Pick<PathStyleProps, ItemStyleKeys>;
class ItemStyleMixin {
......
......@@ -59,6 +59,7 @@ import {
DataModel,
ECEventData,
ZRStyleProps,
TextCommonOption,
SeriesOption,
ParsedValue,
CallbackDataParams
......@@ -73,13 +74,13 @@ import {
trim,
isArrayLike,
map,
defaults
defaults,
isObject
} from 'zrender/src/core/util';
import * as numberUtil from './number';
import SeriesModel from '../model/Series';
import {OnframeCallback, interpolateNumber} from 'zrender/src/animation/Animator';
import {interpolateNumber} from 'zrender/src/animation/Animator';
import List from '../data/List';
import DataFormatMixin from '../model/mixin/dataFormat';
const mathMax = Math.max;
......@@ -89,13 +90,6 @@ const EMPTY_OBJ = {};
export const Z2_EMPHASIS_LIFT = 10;
// key: label model property nane, value: style property name.
export const CACHED_LABEL_STYLE_PROPERTIES = {
color: 'textFill',
textBorderColor: 'textStroke',
textBorderWidth: 'textStrokeWidth'
};
const EMPHASIS = 'emphasis';
const NORMAL = 'normal';
......@@ -134,8 +128,6 @@ type TextCommonParams = {
forceRich?: boolean
getTextPosition?: (textStyleModel: Model, isEmphasis?: boolean) => string | string[] | number[]
defaultOutsidePosition?: LabelOption['position']
textStyle?: ZRStyleProps
......@@ -398,12 +390,14 @@ function singleEnterEmphasis(el: Element) {
if (!hasFillOrStroke(emphasisStyle.stroke)) {
disp.style.stroke = liftColor(currentStroke);
}
disp.z2 += Z2_EMPHASIS_LIFT;
const z2EmphasisLift = (disp as ECElement).z2EmphasisLift;
disp.z2 += z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT;
}
const textContent = el.getTextContent();
if (textContent) {
textContent.z2 += Z2_EMPHASIS_LIFT;
const z2EmphasisLift = (textContent as ECElement).z2EmphasisLift;
textContent.z2 += z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT;
}
// TODO hover layer
}
......@@ -793,6 +787,7 @@ export function createTextConfig(
opt: TextCommonParams,
isEmphasis: boolean
) {
opt = opt || {};
const textConfig: ElementTextConfig = {};
let labelPosition;
let labelRotate = textStyleModel.getShallow('rotate');
......@@ -801,16 +796,11 @@ export function createTextConfig(
);
const labelOffset = textStyleModel.getShallow('offset');
if (opt.getTextPosition) {
labelPosition = opt.getTextPosition(textStyleModel, isEmphasis);
}
else {
labelPosition = textStyleModel.getShallow('position')
|| (isEmphasis ? null : 'inside');
// 'outside' is not a valid zr textPostion value, but used
// in bar series, and magric type should be considered.
labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');
}
labelPosition = textStyleModel.getShallow('position')
|| (isEmphasis ? null : 'inside');
// 'outside' is not a valid zr textPostion value, but used
// in bar series, and magric type should be considered.
labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');
if (labelPosition != null) {
textConfig.position = labelPosition;
......@@ -1054,7 +1044,10 @@ function setTokenTextStyle(
}
}
export function getFont(opt: LabelOption, ecModel: GlobalModel) {
export function getFont(
opt: Pick<TextCommonOption, 'fontStyle' | 'fontWeight' | 'fontSize' | 'fontFamily'>,
ecModel: GlobalModel
) {
const gTextStyleModel = ecModel && ecModel.getModel('textStyle');
return trim([
// FIXME in node-canvas fontWeight is before fontStyle
......@@ -1065,6 +1058,13 @@ export function getFont(opt: LabelOption, ecModel: GlobalModel) {
].join(' '));
}
type AnimateOrSetPropsOption = {
dataIndex?: number;
cb?: () => void;
during?: (percent: number) => void;
isFrom?: boolean;
};
function animateOrSetProps<Props>(
isUpdate: boolean,
el: Element<Props>,
......@@ -1072,15 +1072,22 @@ function animateOrSetProps<Props>(
animatableModel?: Model<AnimationOptionMixin> & {
getAnimationDelayParams?: (el: Element<Props>, dataIndex: number) => AnimationDelayCallbackParam
},
dataIndex?: number | (() => void),
cb?: () => void,
during?: (percent: number) => void
dataIndex?: AnimateOrSetPropsOption['dataIndex'] | AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption,
cb?: AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption['during'],
during?: AnimateOrSetPropsOption['during']
) {
let isFrom = false;
if (typeof dataIndex === 'function') {
during = cb;
cb = dataIndex;
dataIndex = null;
}
else if (isObject(dataIndex)) {
cb = dataIndex.cb;
during = dataIndex.during;
isFrom = dataIndex.isFrom;
dataIndex = dataIndex.dataIndex;
}
// Do not check 'animation' property directly here. Consider this case:
// animation model is an `itemModel`, whose does not have `isAnimationEnabled`
// but its parent model (`seriesModel`) does.
......@@ -1109,20 +1116,31 @@ function animateOrSetProps<Props>(
}
duration > 0
? el.animateTo(props, {
duration,
delay: animationDelay || 0,
easing: animationEasing,
done: cb,
force: !!cb || !!during,
during: during
})
: (el.stopAnimation(), el.attr(props), cb && cb());
? (
isFrom
? el.animateFrom(props, {
duration,
delay: animationDelay || 0,
easing: animationEasing,
done: cb,
force: !!cb || !!during,
during: during
})
: el.animateTo(props, {
duration,
delay: animationDelay || 0,
easing: animationEasing,
done: cb,
force: !!cb || !!during,
during: during
})
)
: (el.stopAnimation(), el.attr(props), cb && (cb as AnimateOrSetPropsOption['cb'])());
}
else {
el.stopAnimation();
el.attr(props);
cb && cb();
!isFrom && el.attr(props);
cb && (cb as AnimateOrSetPropsOption['cb'])();
}
}
......@@ -1147,9 +1165,9 @@ function updateProps<Props>(
props: Props,
// TODO: TYPE AnimatableModel
animatableModel?: Model<AnimationOptionMixin>,
dataIndex?: number | (() => void),
cb?: () => void,
during?: () => void
dataIndex?: AnimateOrSetPropsOption['dataIndex'] | AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption,
cb?: AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption['during'],
during?: AnimateOrSetPropsOption['during']
) {
animateOrSetProps(true, el, props, animatableModel, dataIndex, cb, during);
}
......@@ -1168,9 +1186,9 @@ export function initProps<Props>(
el: Element<Props>,
props: Props,
animatableModel?: Model<AnimationOptionMixin>,
dataIndex?: number | (() => void),
cb?: () => void,
during?: () => void
dataIndex?: AnimateOrSetPropsOption['dataIndex'] | AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption,
cb?: AnimateOrSetPropsOption['cb'] | AnimateOrSetPropsOption['during'],
during?: AnimateOrSetPropsOption['during']
) {
animateOrSetProps(false, el, props, animatableModel, dataIndex, cb, during);
}
......
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Dictionary, ZRStyleProps } from './types';
import { ElementTextConfig } from 'zrender/src/Element';
import { TextStyleProps, TextStylePropsPart, TextProps } from 'zrender/src/graphic/Text';
import { each, hasOwn } from 'zrender/src/core/util';
import { __DEV__ } from '../config';
import { ItemStyleProps } from '../model/mixin/itemStyle';
export interface LegacyStyleProps {
legacy?: boolean
}
const deprecatedLogs = {} as Dictionary<boolean>;
/**
* Whether need to call `convertEC4CompatibleStyle`.
*/
export function isEC4CompatibleStyle(
style: ZRStyleProps & LegacyStyleProps,
elType: string,
hasOwnTextContentOption: boolean,
hasOwnTextConfig: boolean
): boolean {
// Since echarts5, `RectText` is separated from its host element and style.text
// does not exist any more. The compat work brings some extra burden on performance.
// So we provide:
// `legacy: true` force make compat.
// `legacy: false`, force do not compat.
// `legacy` not set: auto detect wheter legacy.
// But in this case we do not compat (difficult to detect and rare case):
// Becuse custom series and graphic component support "merge", users may firstly
// only set `textStrokeWidth` style or secondly only set `text`.
return style && (
style.legacy
|| (
style.legacy !== false
&& !hasOwnTextContentOption
&& !hasOwnTextConfig
&& elType !== 'tspan'
// Difficult to detect whether legacy for a "text" el.
&& (elType === 'text' || hasOwn(style, 'text'))
)
);
}
/**
* `EC4CompatibleStyle` is style that might be in echarts4 format or echarts5 format.
* @param hostStyle The properties might be modified.
* @return If be text el, `textContentStyle` and `textConfig` will not be retured.
* Otherwise a `textContentStyle` and `textConfig` will be created, whose props area
* retried from the `hostStyle`.
*/
export function convertFromEC4CompatibleStyle(hostStyle: ZRStyleProps, elType: string, isNormal: boolean): {
textContent: TextProps & {type: string},
textConfig: ElementTextConfig
} {
const srcStyle = hostStyle as Dictionary<any>;
let textConfig: ElementTextConfig;
let textContent: TextProps & {type: string};
let textContentStyle: TextStyleProps;
if (elType === 'text') {
textContentStyle = srcStyle;
}
else {
textContentStyle = {};
hasOwn(srcStyle, 'text') && (textContentStyle.text = srcStyle.text);
hasOwn(srcStyle, 'rich') && (textContentStyle.rich = srcStyle.rich);
hasOwn(srcStyle, 'textFill') && (textContentStyle.fill = srcStyle.textFill);
hasOwn(srcStyle, 'textStroke') && (textContentStyle.stroke = srcStyle.textStroke);
textContent = {
type: 'text',
style: textContentStyle,
// ec4 do not support rectText trigger.
// And when text postion is different in normal and emphasis
// => hover text trigger emphasis;
// => text position changed, leave mouse pointer immediately;
// That might cause state incorrect.
silent: true
};
textConfig = {};
const hasOwnPos = hasOwn(srcStyle, 'textPosition');
if (isNormal) {
textConfig.position = hasOwnPos ? srcStyle.textPosition : 'inside';
}
else {
hasOwnPos && (textConfig.position = srcStyle.textPosition);
}
hasOwn(srcStyle, 'textPosition') && (textConfig.position = srcStyle.textPosition);
hasOwn(srcStyle, 'textOffset') && (textConfig.offset = srcStyle.textOffset);
hasOwn(srcStyle, 'textRotation') && (textConfig.rotation = srcStyle.textRotation);
hasOwn(srcStyle, 'textDistance') && (textConfig.distance = srcStyle.textDistance);
}
convertEC4CompatibleRichItem(textContentStyle, hostStyle);
each(textContentStyle.rich, function (richItem) {
convertEC4CompatibleRichItem(richItem as TextStyleProps, richItem);
});
return {
textConfig: textConfig,
textContent: textContent
};
}
/**
* The result will be set to `out`.
*/
function convertEC4CompatibleRichItem(out: TextStylePropsPart, richItem: Dictionary<any>): void {
if (!richItem) {
return;
}
// (1) For simplicity, make textXXX properties (deprecated since ec5) has
// higher priority. For example, consider in ec4 `borderColor: 5, textBorderColor: 10`
// on a rect means `borderColor: 4` on the rect and `borderColor: 10` on an attached
// richText in ec5.
// (2) `out === richItem` if and only if `out` is text el or rich item.
// So we can overwite existing props in `out` since textXXX has higher priority.
richItem.font = richItem.textFont || richItem.font;
hasOwn(richItem, 'textStrokeWidth') && (out.lineWidth = richItem.textStrokeWidth);
hasOwn(richItem, 'textAlign') && (out.align = richItem.textAlign);
hasOwn(richItem, 'textVerticalAlign') && (out.verticalAlign = richItem.textVerticalAlign);
hasOwn(richItem, 'textLineHeight') && (out.lineHeight = richItem.textLineHeight);
hasOwn(richItem, 'textWidth') && (out.width = richItem.textWidth);
hasOwn(richItem, 'textHeight') && (out.height = richItem.textHeight);
hasOwn(richItem, 'textBackgroundColor') && (out.backgroundColor = richItem.textBackgroundColor);
hasOwn(richItem, 'textPadding') && (out.padding = richItem.textPadding);
hasOwn(richItem, 'textBorderColor') && (out.borderColor = richItem.textBorderColor);
hasOwn(richItem, 'textBorderWidth') && (out.borderWidth = richItem.textBorderWidth);
hasOwn(richItem, 'textBorderRadius') && (out.borderRadius = richItem.textBorderRadius);
hasOwn(richItem, 'textBoxShadowColor') && (out.shadowColor = richItem.textBoxShadowColor);
hasOwn(richItem, 'textBoxShadowBlur') && (out.shadowBlur = richItem.textBoxShadowBlur);
hasOwn(richItem, 'textBoxShadowOffsetX') && (out.shadowOffsetX = richItem.textBoxShadowOffsetX);
hasOwn(richItem, 'textBoxShadowOffsetY') && (out.shadowOffsetY = richItem.textBoxShadowOffsetY);
}
/**
* Convert to pure echarts4 format style.
* `itemStyle` will be modified, added with ec4 style properties from
* `textStyle` and `textConfig`.
*
* [Caveat]: For simplicity, `insideRollback` in ec4 does not compat, where
* `styleEmphasis: {textFill: 'red'}` will remove the normal auto added stroke.
*/
export function convertToEC4StyleForCustomSerise(
itemStl: ItemStyleProps,
txStl: TextStyleProps,
txCfg: ElementTextConfig
): ZRStyleProps {
const out = itemStl as Dictionary<unknown>;
// See `custom.ts`, a trick to set extra `textPosition` firstly.
out.textPosition = out.textPosition || txCfg.position || 'inside';
txCfg.offset != null && (out.textOffset = txCfg.offset);
txCfg.rotation != null && (out.textRotation = txCfg.rotation);
txCfg.distance != null && (out.textDistance = txCfg.distance);
const isInside = (out.textPosition as string).indexOf('inside') >= 0;
const hostFill = itemStl.fill || '#000';
convertToEC4RichItem(out, txStl);
const textFillNotSet = out.textFill == null;
if (isInside) {
if (textFillNotSet) {
out.textFill = txCfg.insideFill || '#fff';
!out.textStroke && txCfg.insideStroke && (out.textStroke = txCfg.insideStroke);
!out.textStroke && (out.textStroke = hostFill);
out.textStrokeWidth == null && (out.textStrokeWidth = 2);
}
}
else {
if (textFillNotSet) {
out.textFill = txCfg.outsideFill || hostFill;
}
!out.textStroke && txCfg.outsideStroke && (out.textStroke = txCfg.outsideStroke);
}
out.text = txStl.text;
out.rich = txStl.rich;
each(txStl.rich, function (richItem) {
convertToEC4RichItem(richItem as Dictionary<unknown>, richItem);
});
return out;
}
function convertToEC4RichItem(out: Dictionary<unknown>, richItem: TextStylePropsPart) {
if (!richItem) {
return;
}
hasOwn(richItem, 'fill') && (out.textFill = richItem.fill);
hasOwn(richItem, 'stroke') && (out.textStroke = richItem.fill);
hasOwn(richItem, 'lineWidth') && (out.textStrokeWidth = richItem.lineWidth);
hasOwn(richItem, 'font') && (out.textStrokeWidth = richItem.font);
hasOwn(richItem, 'fontStyle') && (out.fontStyle = richItem.fontStyle);
hasOwn(richItem, 'fontWeight') && (out.fontWeight = richItem.fontWeight);
hasOwn(richItem, 'fontSize') && (out.fontSize = richItem.fontSize);
hasOwn(richItem, 'fontFamily') && (out.fontFamily = richItem.fontFamily);
hasOwn(richItem, 'align') && (out.textAlign = richItem.align);
hasOwn(richItem, 'verticalAlign') && (out.textVerticalAlign = richItem.verticalAlign);
hasOwn(richItem, 'lineHeight') && (out.textLineHeight = richItem.lineHeight);
hasOwn(richItem, 'width') && (out.textWidth = richItem.width);
hasOwn(richItem, 'height') && (out.textHeight = richItem.height);
hasOwn(richItem, 'backgroundColor') && (out.textBackgroundColor = richItem.backgroundColor);
hasOwn(richItem, 'padding') && (out.textPadding = richItem.padding);
hasOwn(richItem, 'borderColor') && (out.textBorderColor = richItem.borderColor);
hasOwn(richItem, 'borderWidth') && (out.textBorderWidth = richItem.borderWidth);
hasOwn(richItem, 'borderRadius') && (out.textBorderRadius = richItem.borderRadius);
hasOwn(richItem, 'shadowColor') && (out.textBoxShadowColor = richItem.shadowColor);
hasOwn(richItem, 'shadowBlur') && (out.textBoxShadowBlur = richItem.shadowBlur);
hasOwn(richItem, 'shadowOffsetX') && (out.textBoxShadowOffsetX = richItem.shadowOffsetX);
hasOwn(richItem, 'shadowOffsetY') && (out.textBoxShadowOffsetY = richItem.shadowOffsetY);
hasOwn(richItem, 'textShadowColor') && (out.textShadowColor = richItem.textShadowColor);
hasOwn(richItem, 'textShadowBlur') && (out.textShadowBlur = richItem.textShadowBlur);
hasOwn(richItem, 'textShadowOffsetX') && (out.textShadowOffsetX = richItem.textShadowOffsetX);
hasOwn(richItem, 'textShadowOffsetY') && (out.textShadowOffsetY = richItem.textShadowOffsetY);
}
export function warnDeprecated(deprecated: string, insteadApproach: string): void {
if (__DEV__) {
const key = deprecated + '^_^' + insteadApproach;
if (!deprecatedLogs[key]) {
console.warn(`DEPRECATED: "${deprecated}" has been deprecated. ${insteadApproach}`);
deprecatedLogs[key] = true;
}
}
}
......@@ -106,6 +106,7 @@ export interface ECElement extends Element {
};
highDownSilentOnTouch?: boolean;
onStateChange?: (fromState: 'normal' | 'emphasis', toState: 'normal' | 'emphasis') => void;
z2EmphasisLift?: number;
}
export interface DataHost {
......@@ -426,6 +427,7 @@ export type ModelOption = any;
export type ThemeOption = Dictionary<any>;
export type DisplayState = 'normal' | 'emphasis';
export type DisplayStateNonNormal = 'emphasis';
export type DisplayStateHostOption = {
emphasis?: Dictionary<any>,
[key: string]: any
......
<!DOCTYPE html>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<meta charset="utf-8">
<style>
text {
font: 10px sans-serif;
text-anchor: middle;
}
.node--hover circle {
stroke: #000;
stroke-width: 1.2px;
}
#main {
width: 1000px;
height: 500px;
}
</style>
<div id="main" style="width:960px; height:960px;"></div>
<svg width="960" height="960"><g transform="translate(1,1)"></g></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="../dist/echarts.js"></script>
<script>
var stratify = d3.stratify()
.parentId(function(d) {
return d.id.substring(0, d.id.lastIndexOf("."));
});
d3.csv("data/flare.csv", function(error, rawData) {
if (error) throw error;
var root = stratify(rawData)
.sum(function(d) {
return d.value;
})
.sort(function(a, b) {
return b.value - a.value;
});
var maxDepth = 0;
var seriesData = root.descendants().map(function (node) {
maxDepth = Math.max(maxDepth, node.depth);
return [
node.value,
node.depth,
node.id
];
});
var chart = echarts.init(document.getElementById('main'));
function renderItem(params, api) {
var context = params.context;
if (!context.layout) {
d3.pack()
.size([api.getWidth() - 2, api.getHeight() - 2])
.padding(3)(root);
context.layout = {};
root.descendants().forEach(function (node) {
context.layout[node.id] = {
x: node.x,
y: node.y,
r: node.r,
isLeaf: !node.children || !node.children.length
};
});
}
var nodePath = api.value(2);
var itemLayout = context.layout[nodePath];
var nodeName = '';
var textFont = api.font({
fontSize: 12,
fontFamily: 'Arial'
});
if (itemLayout.isLeaf && itemLayout.r > 10) {
nodeName = nodePath.slice(nodePath.lastIndexOf('.') + 1).split(/(?=[A-Z][^A-Z])/g).join('\n');
nodeName = echarts.format.truncateText(nodeName, itemLayout.r, textFont, '.');
}
return {
type: 'circle',
shape: {
cx: itemLayout.x,
cy: itemLayout.y,
r: itemLayout.r
},
z2: api.value(1) * 2,
style: api.style({
text: nodeName,
textFont: textFont,
textPosition: 'inside'
}),
styleEmphasis: api.style({
text: nodeName,
textPosition: 'inside',
textFont: textFont,
stroke: 'rgba(0,0,0,0.5)',
lineWidth: 3
})
};
}
var option = {
xAxis: {
axisLine: {show: false},
axisTick: {show: false},
axisLabel: {show: false},
splitLine: {show: false}
},
yAxis: {
axisLine: {show: false},
axisTick: {show: false},
axisLabel: {show: false},
splitLine: {show: false}
},
tooltip: {},
visualMap: {
show: false,
min: 0,
max: maxDepth,
dimension: 1,
inRange: {
color: ['#006edd', '#e0ffff']
}
},
series: {
type: 'custom',
renderItem: renderItem,
encode: {
tooltip: 0,
itemName: 2
},
data: seriesData
}
};
chart.setOption(option);
});
</script>
......@@ -45,6 +45,7 @@ text {
<svg width="960" height="960"><g transform="translate(1,1)"></g></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="../dist/echarts.js"></script>
<script src="./lib/testHelper.js"></script>
<script>
var stratify = d3.stratify()
......@@ -105,6 +106,8 @@ d3.csv("data/flare.csv", function(error, rawData) {
nodeName = nodePath.slice(nodePath.lastIndexOf('.') + 1).split(/(?=[A-Z][^A-Z])/g).join('\n');
nodeName = echarts.format.truncateText(nodeName, itemLayout.r, textFont, '.');
}
var z2 = api.value(1) * 2;
// console.log(api.style());
return {
type: 'circle',
......@@ -113,19 +116,35 @@ d3.csv("data/flare.csv", function(error, rawData) {
cy: itemLayout.y,
r: itemLayout.r
},
z2: api.value(1) * 2,
style: api.style({
text: nodeName,
textFont: textFont,
textPosition: 'inside'
}),
styleEmphasis: api.style({
z2: z2,
textContent: {
type: 'text',
style: {
text: nodeName,
// fill: 'blue'
},
emphasis: {
style: {
fontSize: 16,
// fill: 'red'
}
}
},
textConfig: {
position: 'inside'
},
style: {
fill: api.visual('color'),
text: nodeName,
textPosition: 'inside',
textFont: textFont,
stroke: 'rgba(0,0,0,0.5)',
lineWidth: 3
})
font: textFont,
},
emphasis: {
style: {
font: textFont,
stroke: 'rgba(0,0,0,0.5)',
lineWidth: 3
}
}
};
}
......@@ -165,6 +184,13 @@ d3.csv("data/flare.csv", function(error, rawData) {
chart.setOption(option);
// testHelper.printElements(chart, {
// attr: ['z', 'z2', 'style.text', 'style.fill', 'style.stroke'],
// filter: function (el) {
// return el.style && el.style.text;
// }
// });
});
</script>
......@@ -35,10 +35,10 @@ under the License.
</style>
<div id="main0"></div>
<div id="main2"></div>
<div id="main3"></div>
<!-- <div id="main1"></div> -->
<div id="main-eventful"></div>
<div id="main-clip-by-system"></div>
<div id="main-clip-by-self"></div>
<div id="main-SVG-Path"></div>
<script>
......@@ -85,6 +85,7 @@ under the License.
style: {
fill: 'red',
text: 'dataIndex: ' + params.dataIndex,
textFill: '#000',
textStroke: '#fff',
textStrokeWidth: 1
}
......@@ -107,7 +108,7 @@ under the License.
}]
};
var chart = testHelper.create(echarts, 'main0', {
var chart = testHelper.create(echarts, 'main-eventful', {
title: [
'Eventful: ',
'Only this el trigger events: **red circle** and **red rect** of **dataIndex: 1**',
......@@ -138,8 +139,6 @@ under the License.
'echarts'/*, 'map/js/china' */
], function (echarts) {
// deprecated: this case would be wrong.
var option = {
xAxis: {
min: 90,
......@@ -151,13 +150,11 @@ under the License.
max: 500,
scale: true
},
dataZoom: [{
type: 'inside',
filterMode: 'none'
}, {
type: 'slider',
filterMode: 'none'
}],
dataZoom: [
{type: 'inside', filterMode: 'none'},
{type: 'slider', filterMode: 'none'},
{type: 'slider', filterMode: 'none', orient: 'vertical'},
],
series: [{
type: 'custom',
renderItem: function (params, api) {
......@@ -173,24 +170,19 @@ under the License.
[90, 50]
]
},
clip: {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
},
style: {
fill: 'green'
}
}
},
clip: true,
data: [[100, 300]]
}]
};
var chart = testHelper.create(echarts, 'main2', {
var chart = testHelper.create(echarts, 'main-clip-by-system', {
title: [
'The shape should be **clipped** by the grid. (TODO)',
'The shape should be **clipped** by the grid (by series.clip).',
],
option: option
});
......@@ -204,13 +196,82 @@ under the License.
<script>
require([
'echarts'/*, 'map/js/china' */
], function (echarts) {
var option = {
xAxis: {
min: 90,
max: 120,
scale: true
},
yAxis: {
min: 50,
max: 500,
scale: true
},
dataZoom: [
{type: 'inside', filterMode: 'none'},
{type: 'slider', filterMode: 'none'},
{type: 'slider', filterMode: 'none', orient: 'vertical'},
],
series: [{
type: 'custom',
renderItem: function (params, api) {
return {
type: 'group',
children: [{
type: 'polygon',
position: api.coord([api.value(0), api.value(1)]),
shape: {
points: [
[0, 0],
[50, -50],
[90, -50],
[140, 0],
[90, 50]
]
},
style: {
fill: 'blue'
}
}],
clipPath: {
type: 'rect',
shape: {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}
}
}
},
data: [[100, 300]]
}]
};
var chart = testHelper.create(echarts, 'main-clip-by-self', {
title: [
'The shape should be **clipped** by the grid (by custom clipPath).',
],
option: option
});
});
</script>
<script>
require(['echarts'], function (echarts) {
// deprecated: this case would be wrong.
var data = [];
......@@ -224,23 +285,6 @@ under the License.
tooltip: {
},
dataZoom: [{
type: 'slider',
xAxisIndex: 0,
filterMode: 'weakFilter',
height: 20,
bottom: 0,
start: -26,
end: 26,
showDetail: false
}, {
type: 'inside',
xAxisIndex: 0,
filterMode: 'weakFilter',
start: -26,
end: 26,
zoomOnMouseWheel: false,
moveOnMouseMove: true
}, {
type: 'slider',
yAxisIndex: 0,
zoomLock: true,
......@@ -350,7 +394,7 @@ under the License.
};
}
var chart = testHelper.create(echarts, 'main3', {
var chart = testHelper.create(echarts, 'main-SVG-Path', {
title: [
'Test SVG path data auto fit to rect: ',
'the y axis label (made by custom series) should be center',
......@@ -365,5 +409,9 @@ under the License.
</body>
</html>
\ No newline at end of file
此差异已折叠。
window.BAR_ROUND_GRADIENT_TEXTURE = 'data:image/png;base64,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';
\ No newline at end of file
此差异已折叠。
此差异已折叠。
......@@ -680,7 +680,8 @@ under the License.
// silent: true,
label: {
show: true,
silent: true,
// silent: true,
position: 'top'
},
itemStyle: {
color: 'green',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册