From c3ca64a25e8348b31c492351bb8385926e2dca95 Mon Sep 17 00:00:00 2001 From: chell <361531684@qq.com> Date: Fri, 3 Mar 2023 16:16:27 +0800 Subject: [PATCH 1/3] feat(funnel): add funnel new styles #14863 https://github.com/apache/echarts/pull/17461 --- src/chart/funnel/FunnelSeries.ts | 22 ++- src/chart/funnel/FunnelView.ts | 203 ++++++++++++++++--- src/chart/funnel/funnelLayout.ts | 329 +++++++++++++++++++++++++------ 3 files changed, 457 insertions(+), 97 deletions(-) diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts index 152cdb37da..218116ef7d 100644 --- a/src/chart/funnel/FunnelSeries.ts +++ b/src/chart/funnel/FunnelSeries.ts @@ -48,6 +48,10 @@ type FunnelLabelOption = Omit & { | 'outer' | 'inner' | 'center' | 'rightTop' | 'rightBottom' | 'leftTop' | 'leftBottom' }; +type FunnelRateLabelOption = Omit & { + precision: number +}; + interface FunnelStatesMixin { emphasis?: DefaultStatesMixinEmphasis } @@ -59,6 +63,8 @@ export interface FunnelStateOption { itemStyle?: ItemStyleOption label?: FunnelLabelOption labelLine?: LabelLineOption + rateLabel?: FunnelRateLabelOption + overallRateLabel?: FunnelRateLabelOption } export interface FunnelDataItemOption @@ -95,6 +101,12 @@ export interface FunnelSeriesOption funnelAlign?: HorizontalAlign | VerticalAlign data?: (OptionDataValueNumeric | OptionDataValueNumeric[] | FunnelDataItemOption)[] + + exitWidth?: string + + showRate?: boolean + + dynamicHeight?: boolean } class FunnelSeriesModel extends SeriesModel { @@ -172,6 +184,14 @@ class FunnelSeriesModel extends SeriesModel { position: 'outer' // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 }, + rateLabel: { + show: true, + precision: 2 + }, + overallRateLabel: { + show: true, + precision: 2 + }, labelLine: { show: true, length: 20, @@ -199,4 +219,4 @@ class FunnelSeriesModel extends SeriesModel { } -export default FunnelSeriesModel; +export default FunnelSeriesModel; \ No newline at end of file diff --git a/src/chart/funnel/FunnelView.ts b/src/chart/funnel/FunnelView.ts index e4a922afca..217f751ec2 100644 --- a/src/chart/funnel/FunnelView.ts +++ b/src/chart/funnel/FunnelView.ts @@ -16,27 +16,100 @@ * specific language governing permissions and limitations * under the License. */ - +import * as zrUtil from 'zrender/src/core/util'; import * as graphic from '../../util/graphic'; import { setStatesStylesFromModel, toggleHoverEmphasis } from '../../util/states'; import ChartView from '../../view/Chart'; -import FunnelSeriesModel, {FunnelDataItemOption} from './FunnelSeries'; +import FunnelSeriesModel, { FunnelDataItemOption } from './FunnelSeries'; import GlobalModel from '../../model/Global'; import ExtensionAPI from '../../core/ExtensionAPI'; import SeriesData from '../../data/SeriesData'; -import { ColorString } from '../../util/types'; +import { + ColorString, + DisplayState, + InterpolatableValue, + SeriesDataType +} from '../../util/types'; import { setLabelLineStyle, getLabelLineStatesModels } from '../../label/labelGuideHelper'; import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle'; import { saveOldStyle } from '../../animation/basicTransition'; const opacityAccessPath = ['itemStyle', 'opacity'] as const; +const rateLabelFetcher = { + getFormattedLabel( + // In MapDraw case it can be string (region name) + labelDataIndex: number, + status: DisplayState, + dataType?: SeriesDataType, + labelDimIndex?: number, + formatter?: string | ((params: object) => string), + // If provided, the implementation of `getFormattedLabel` can use it + // to generate the final label text. + extendParams?: { + interpolatedValue: InterpolatableValue + } + ): string { + status = status || 'normal'; + const { hostModel, layout } = this as unknown as { hostModel: FunnelSeriesModel, layout: any }; + const data = hostModel.getData(dataType); + + if (!formatter) { + const itemModel = data.getItemModel(labelDataIndex); + // @ts-ignore + formatter = itemModel.get(status === 'normal' + ? ['rateLabel', 'formatter'] + : [status, 'rateLabel', 'formatter'] + ); + } + + const { rate, isLastPiece, nextName, preName, preDataIndex, nextDataIndex } = layout; + + if (isLastPiece) { + const itemModel = data.getItemModel(labelDataIndex); + // @ts-ignore + formatter = itemModel.get(status === 'normal' + ? ['overallRateLabel', 'formatter'] + : [status, 'overallRateLabel', 'formatter'] + ); + } + + type RateParams = { + rate: string, + preName: string, + nextName: string, + preDataIndex: string, + nextDataIndex: string, + formatter: string | ((params: object) => string) + }; + + const params: RateParams = { + rate, // a + preName, // b + nextName, // c + preDataIndex, // d + nextDataIndex, // e + formatter + }; + + if (zrUtil.isFunction(formatter)) { + return formatter(params); + } + + return ''; + } +}; + /** * Piece of pie including Sector, Label, LabelLine */ class FunnelPiece extends graphic.Polygon { - constructor(data: SeriesData, idx: number) { + /** + * @param type judge is data blocks or conversion blocks + */ + + constructor(data: SeriesData, idx: number, type: 'data' | 'rate') { super(); const polygon = this; @@ -45,10 +118,10 @@ class FunnelPiece extends graphic.Polygon { polygon.setTextContent(text); this.setTextGuideLine(labelLine); - this.updateData(data, idx, true); + this.updateData(data, idx, type, true); } - updateData(data: SeriesData, idx: number, firstCreate?: boolean) { + updateData(data: SeriesData, idx: number, type: 'data' | 'rate', firstCreate?: boolean) { const polygon = this; @@ -58,17 +131,29 @@ class FunnelPiece extends graphic.Polygon { const emphasisModel = itemModel.getModel('emphasis'); let opacity = itemModel.get(opacityAccessPath); opacity = opacity == null ? 1 : opacity; + if (type === 'rate') { + // the opacity of rate piece is half of data + opacity /= 2; + } if (!firstCreate) { saveOldStyle(polygon); } + // hide the last rate piece and when it not the last one show it again + polygon.invisible = false; + if (layout.isLastPiece && type === 'rate') { + // hide last rate piece + polygon.invisible = true; + } // Update common style polygon.useStyle(data.getItemVisual(idx, 'style')); polygon.style.lineJoin = 'round'; + const points = type === 'data' ? layout.points : layout.ratePoints; + if (firstCreate) { polygon.setShape({ - points: layout.points + points }); polygon.style.opacity = 0; graphic.initProps(polygon, { @@ -83,49 +168,62 @@ class FunnelPiece extends graphic.Polygon { opacity: opacity }, shape: { - points: layout.points + points } }, seriesModel, idx); } - setStatesStylesFromModel(polygon, itemModel); - - this._updateLabel(data, idx); + this._updateLabel(data, idx, type); - toggleHoverEmphasis( - this, - emphasisModel.get('focus'), - emphasisModel.get('blurScope'), - emphasisModel.get('disabled') - ); + setStatesStylesFromModel(polygon, itemModel); + if (type === 'data') { + toggleHoverEmphasis( + this, + emphasisModel.get('focus'), + emphasisModel.get('blurScope'), + emphasisModel.get('disabled') + ); + } } - _updateLabel(data: SeriesData, idx: number) { + _updateLabel(data: SeriesData, idx: number, type: 'data' | 'rate') { const polygon = this; const labelLine = this.getTextGuideLine(); const labelText = polygon.getTextContent(); - const seriesModel = data.hostModel; + const seriesModel = data.hostModel as FunnelSeriesModel; const itemModel = data.getItemModel(idx); const layout = data.getItemLayout(idx); - const labelLayout = layout.label; + const labelLayout = layout[type === 'data' ? 'label' : 'rateLabel']; const style = data.getItemVisual(idx, 'style'); const visualColor = style.fill as ColorString; + // bind this to data of rateLabelFetherFunc + let rateFetcher: any; // clone default fechter + if (type === 'rate') { + rateFetcher = { + getFormattedLabel: rateLabelFetcher.getFormattedLabel.bind( + { hostModel: data.hostModel, layout } + ) + }; + } + const rateLabel = layout.isLastPiece ? 'overallRateLabel' : 'rateLabel'; setLabelStyle( // position will not be used in setLabelStyle labelText, - getLabelStatesModels(itemModel), + getLabelStatesModels(itemModel, type === 'data' ? undefined : rateLabel), { - labelFetcher: data.hostModel as FunnelSeriesModel, + labelFetcher: type === 'data' ? data.hostModel as FunnelSeriesModel : rateFetcher, labelDataIndex: idx, defaultOpacity: style.opacity, - defaultText: data.getName(idx) + defaultText: type === 'data' ? data.getName(idx) : layout.rate }, - { normal: { - align: labelLayout.textAlign, - verticalAlign: labelLayout.verticalAlign - } } + { + normal: { + align: labelLayout.textAlign, + verticalAlign: labelLayout.verticalAlign + } + } ); polygon.setTextConfig({ @@ -167,6 +265,9 @@ class FunnelPiece extends graphic.Polygon { stroke: visualColor }); } + + // relate ratePiece with dataPiece + ratePiece: FunnelPiece; } class FunnelView extends ChartView { @@ -182,26 +283,64 @@ class FunnelView extends ChartView { const oldData = this._data; const group = this.group; + // rate in other two mode did not support yet + const showRate = + seriesModel.get('showRate') + && !( + seriesModel.get('dynamicHeight') + || seriesModel.get('sort') === 'none' + ); data.diff(oldData) .add(function (idx) { - const funnelPiece = new FunnelPiece(data, idx); + const funnelPiece = new FunnelPiece(data, idx, 'data'); data.setItemGraphicEl(idx, funnelPiece); group.add(funnelPiece); + + if (showRate) { + const ratePiece = new FunnelPiece(data, idx, 'rate'); + group.add(ratePiece); + funnelPiece.ratePiece = ratePiece; + } }) .update(function (newIdx, oldIdx) { const piece = oldData.getItemGraphicEl(oldIdx) as FunnelPiece; - piece.updateData(data, newIdx); + piece.updateData(data, newIdx, 'data'); group.add(piece); data.setItemGraphicEl(newIdx, piece); + + // rate funnel piece may remove in this mount func + const ratePiece = piece.ratePiece; + if (showRate) { + if (ratePiece) { + ratePiece.updateData(data, newIdx, 'rate'); + group.add(ratePiece); + } + else { + const ratePiece = new FunnelPiece(data, newIdx, 'rate'); + group.add(ratePiece); + piece.ratePiece = ratePiece; + } + } + else { + if (ratePiece) { + graphic.removeElementWithFadeOut(ratePiece, seriesModel, oldIdx); + piece.ratePiece = null; + } + } }) .remove(function (idx) { - const piece = oldData.getItemGraphicEl(idx); + const piece = oldData.getItemGraphicEl(idx) as FunnelPiece; graphic.removeElementWithFadeOut(piece, seriesModel, idx); + + if (showRate) { + const ratePiece = piece.ratePiece; + graphic.removeElementWithFadeOut(ratePiece, seriesModel, idx); + } }) .execute(); @@ -213,8 +352,8 @@ class FunnelView extends ChartView { this._data = null; } - dispose() {} + dispose() { } } -export default FunnelView; +export default FunnelView; \ No newline at end of file diff --git a/src/chart/funnel/funnelLayout.ts b/src/chart/funnel/funnelLayout.ts index 4d433c1b1e..ccb301db33 100644 --- a/src/chart/funnel/funnelLayout.ts +++ b/src/chart/funnel/funnelLayout.ts @@ -246,26 +246,78 @@ function labelLayout(data: SeriesData) { }); } +function rateLabelLayout(data: SeriesData) { + data.each(function (idx) { + const layout = data.getItemLayout(idx); + const points = layout.ratePoints; + + const isLabelInside = true; + + const textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4; + const textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4; + const textAlign = 'center'; + + const linePoints = [ + [textX, textY], [textX, textY] + ]; + + layout.rateLabel = { + linePoints: linePoints, + x: textX, + y: textY, + verticalAlign: 'middle', + textAlign: textAlign, + inside: isLabelInside + }; + }); +} + export default function funnelLayout(ecModel: GlobalModel, api: ExtensionAPI) { ecModel.eachSeriesByType('funnel', function (seriesModel: FunnelSeriesModel) { + // data about const data = seriesModel.getData(); const valueDim = data.mapDimension('value'); + const valueArr = data.mapArray(valueDim, function (val: number) { + return val; + }); + const valueSum = valueArr.reduce((pre, cur) => pre + cur); + // direction about const sort = seriesModel.get('sort'); - const viewRect = getViewRect(seriesModel, api); const orient = seriesModel.get('orient'); + + // size and pos about + const viewRect = getViewRect(seriesModel, api); const viewWidth = viewRect.width; const viewHeight = viewRect.height; - let indices = getSortedIndices(data, sort); let x = viewRect.x; let y = viewRect.y; - const sizeExtent = orient === 'horizontal' ? [ - parsePercent(seriesModel.get('minSize'), viewHeight), - parsePercent(seriesModel.get('maxSize'), viewHeight) - ] : [ - parsePercent(seriesModel.get('minSize'), viewWidth), - parsePercent(seriesModel.get('maxSize'), viewWidth) - ]; + let indices = getSortedIndices(data, sort); + + let gap = seriesModel.get('gap'); + const gapSum = gap * (data.count() - 1); + + // mapping mode about + const dynamicHeight = seriesModel.get('dynamicHeight'); + const showRate = seriesModel.get('showRate'); + // size extent based on orient and mapping mode + // determine the width extent of the funnel piece when dynamicHeight is false + // determine the height extent of the funnel piece when dynamicHeight if true + const isHorizontal = orient === 'horizontal'; + const size = dynamicHeight ? ( + isHorizontal ? viewWidth - gapSum : viewHeight - gapSum + ) : ( + isHorizontal ? viewHeight : viewWidth + ); + const sizeExtent = [ + parsePercent(seriesModel.get('minSize'), size), + size + ]; + if (!dynamicHeight) { + sizeExtent[1] = parsePercent(seriesModel.get('maxSize'), size); + } + + // data extent const dataExtent = data.getDataExtent(valueDim); let min = seriesModel.get('min'); let max = seriesModel.get('max'); @@ -276,16 +328,36 @@ export default function funnelLayout(ecModel: GlobalModel, api: ExtensionAPI) { max = dataExtent[1]; } + // determine the height of the funnel + let viewSize = dynamicHeight ? (isHorizontal ? viewHeight : viewWidth + ) : ( + isHorizontal ? viewWidth : viewHeight); + let itemSize = (viewSize - gapSum) / data.count(); + + if (dynamicHeight) { + viewSize = parsePercent(seriesModel.get('maxSize'), viewSize); + } + const funnelAlign = seriesModel.get('funnelAlign'); - let gap = seriesModel.get('gap'); - const viewSize = orient === 'horizontal' ? viewWidth : viewHeight; - let itemSize = (viewSize - gap * (data.count() - 1)) / data.count(); - const getLinePoints = function (idx: number, offset: number) { - // End point index is data.count() and we assign it 0 + // adjust related param + if (sort === 'ascending') { + // From bottom to top + itemSize = -itemSize; + gap = -gap; + if (orient === 'horizontal') { + x += viewWidth; + } + else { + y += viewHeight; + } + indices = indices.reverse(); + } + + const getLinePoints = function (offset: number, itemSize: number) { + // do not caculate line width in this func if (orient === 'horizontal') { - const val = data.get(valueDim, idx) as number || 0; - const itemHeight = linearMap(val, [min, max], sizeExtent, true); + const itemHeight = itemSize; let y0; switch (funnelAlign) { case 'top': @@ -304,8 +376,7 @@ export default function funnelLayout(ecModel: GlobalModel, api: ExtensionAPI) { [offset, y0 + itemHeight] ]; } - const val = data.get(valueDim, idx) as number || 0; - const itemWidth = linearMap(val, [min, max], sizeExtent, true); + const itemWidth = itemSize; let x0; switch (funnelAlign) { case 'left': @@ -324,68 +395,198 @@ export default function funnelLayout(ecModel: GlobalModel, api: ExtensionAPI) { ]; }; - if (sort === 'ascending') { - // From bottom to top - itemSize = -itemSize; - gap = -gap; - if (orient === 'horizontal') { - x += viewWidth; - } - else { - y += viewHeight; - } - indices = indices.reverse(); + const getItemSize = function (idx: number) { + const itemVal = data.get(valueDim, idx) as number || 0; + const itemSize = linearMap(itemVal, [min, max], sizeExtent, true); + return itemSize; + }; + + // exit shape control + const exitWidth = parsePercent(seriesModel.get('exitWidth'), 100); + + // dy height funnel piece about + let setDynamicHeightPoints: + ( + index: number, + idx: number, + pos: number, + pieceHeight: number + ) => void | null = null; + + if (dynamicHeight) { + setDynamicHeightPoints = (function () { + const dyminSize = parsePercent(seriesModel.get('minSize'), 100); + const dymaxSize = dyminSize < 100 ? sizeExtent[1] * 100 / (100 - dyminSize) : sizeExtent[1]; + let resSize = dymaxSize; + return function (index: number, idx: number, pos: number, pieceHeight: number) { + const start = getLinePoints(pos, resSize / dymaxSize * viewSize); + index === indices.length - 1 && exitWidth === 100 + || ( + resSize += sort === 'ascending' ? pieceHeight : -pieceHeight + ); + const end = getLinePoints(pos + pieceHeight, resSize / dymaxSize * viewSize); + + data.setItemLayout(idx, { + points: start.concat(end.slice().reverse()) + }); + }; + })(); } - for (let i = 0; i < indices.length; i++) { - const idx = indices[i]; - const nextIdx = indices[i + 1]; - const itemModel = data.getItemModel(idx); + // rate funnel about + let setRatePiecePoint: ( + index: number, + idx: number, + nextIdx: number, + pos: number, + pieceHeight: number + ) => void | null = null; - if (orient === 'horizontal') { - let width = itemModel.get(['itemStyle', 'width']); - if (width == null) { - width = itemSize; - } - else { - width = parsePercent(width, viewWidth); - if (sort === 'ascending') { - width = -width; + if (showRate) { + const getConverRate = (function () { + let firstVal: number; + let firstName: string; + let firstDataIndex: number; + // get rate fixed decimal places + const ratePrecision = seriesModel.get(['rateLabel', 'precision']); + const overallRatePrecision = seriesModel.get(['overallRateLabel', 'precision']); + return function (index: number, idx: number, nextIdx: number) { + const val = data.get(valueDim, idx) as number || 0; + const nextVal = data.get(valueDim, nextIdx) as number || 0; + let preName = data.getName(idx); + let nextName = data.getName(nextIdx); + let preDataIndex = idx; + let nextDataIndex = nextIdx; + let rate: number | string = nextVal / val; + rate = (rate * 100).toFixed(ratePrecision) + '%'; + if (index === 0) { + firstVal = val; + firstName = data.getName(idx); + firstDataIndex = idx; } + else if (index === indices.length - 1) { + const lastVal = val; + rate = lastVal / firstVal; + rate = (rate * 100).toFixed(overallRatePrecision) + '%'; + nextName = preName; + preName = firstName; + preDataIndex = firstDataIndex; + nextDataIndex = idx; + } + preDataIndex = preDataIndex + 1; + nextDataIndex = nextDataIndex + 1; + return { rate, nextName, preName, preDataIndex, nextDataIndex }; + }; + })(); + setRatePiecePoint = function ( + index: number, + idx: number, + nextIdx: number, + pos: number, + pieceHeight: number + ) { + // get this size + const itemSize = getItemSize(idx); + let exitSize = itemSize; + if (exitWidth != null && index === indices.length - 1) { + exitSize = itemSize * (exitWidth > 100 ? 100 : exitWidth) / 100; } + // data piece + const dataStart = getLinePoints(pos, itemSize); + const dataEnd = getLinePoints(pos + pieceHeight / 2, exitSize); + // rate piece + const nextSize = getItemSize(index === indices.length - 1 && exitWidth === 100 ? idx : nextIdx); - const start = getLinePoints(idx, x); - const end = getLinePoints(nextIdx, x + width); - - x += width + gap; + const rateStart = getLinePoints(pos + pieceHeight / 2, itemSize); + const rateEnd = getLinePoints(pos + pieceHeight, nextSize); + // rate string about + const { rate, nextName, preName, preDataIndex, nextDataIndex } = getConverRate(index, idx, nextIdx); data.setItemLayout(idx, { - points: start.concat(end.slice().reverse()) + points: dataStart.concat(dataEnd.slice().reverse()), + ratePoints: rateStart.concat(rateEnd.slice().reverse()), + isLastPiece: index === indices.length - 1, + rate, + nextName, + preName, + preDataIndex, + nextDataIndex }); + }; + + } + + // get the height of funnel piece + const getPieceHeight = function (pieceHeight: number | string, idx?: number): number { + // get funnel piece height pass to getLinePoints func based on data value + const val = data.get(valueDim, idx) as number || 0; + + if (dynamicHeight) { + // in dy height, user can't set itemHeight or itemWidth + pieceHeight = linearMap(val, [0, valueSum], [0, size], true); + pieceHeight = sort === 'ascending' ? -pieceHeight : pieceHeight; + return pieceHeight; + } + + // default mapping or show rate pieceHeight + if (pieceHeight == null) { + pieceHeight = itemSize; } else { - let height = itemModel.get(['itemStyle', 'height']); - if (height == null) { - height = itemSize; - } - else { - height = parsePercent(height, viewHeight); - if (sort === 'ascending') { - height = -height; - } - } + pieceHeight = parsePercent(pieceHeight, orient === 'horizontal' ? viewWidth : viewHeight); + pieceHeight = sort === 'ascending' ? -pieceHeight : pieceHeight; + } + return pieceHeight; + }; - const start = getLinePoints(idx, y); - const end = getLinePoints(nextIdx, y + height); + // set the line piont of the funnel piece + const setLayoutPoints = function ( + index: number, + idx: number, + nextIdx: number, + pieceHeight: number, + pos: number + ): void { + // The subsequent funnel shape modification will be done in this func. + // We don’t need to concern direction when we use this function to set points. + if (dynamicHeight) { + setDynamicHeightPoints(index, idx, pos, pieceHeight); + return; + } + else if (showRate && sort !== 'none') { + setRatePiecePoint(index, idx, nextIdx, pos, pieceHeight); + return; + } + const start = getLinePoints(pos, getItemSize(idx)); + // get end line width; + const nIdx = index === indices.length - 1 && exitWidth === 100 ? idx : nextIdx; + const end = getLinePoints(pos + pieceHeight, getItemSize(nIdx)); - y += height + gap; + data.setItemLayout(idx, { + points: start.concat(end.slice().reverse()) + }); + }; - data.setItemLayout(idx, { - points: start.concat(end.slice().reverse()) - }); + for (let i = 0; i < indices.length; i++) { + const idx = indices[i]; + const nextIdx = indices[i + 1]; + const itemModel = data.getItemModel(idx); + + if (orient === 'horizontal') { + const width = getPieceHeight(itemModel.get(['itemStyle', 'width']), idx); + setLayoutPoints(i, idx, nextIdx, width, x); + x += width + gap; + } + else { + const height = getPieceHeight(itemModel.get(['itemStyle', 'height']), idx); + setLayoutPoints(i, idx, nextIdx, height, y); + y += height + gap; } } labelLayout(data); + if (showRate && !dynamicHeight && sort !== 'none') { + rateLabelLayout(data); + } }); -} +} \ No newline at end of file From 93f57e3745eddb3361c66338e38877d893bc86ef Mon Sep 17 00:00:00 2001 From: chell <361531684@qq.com> Date: Fri, 3 Mar 2023 16:26:50 +0800 Subject: [PATCH 2/3] feat: update package information by tagged appflow --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 802b21d409..e4c6dd39e2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "echarts", + "name": "@appflow-ai/echarts", "version": "5.4.1", "description": "Apache ECharts is a powerful, interactive charting and data visualization library for browser", "license": "Apache-2.0", @@ -20,12 +20,11 @@ "types": "index.d.ts", "homepage": "https://echarts.apache.org", "bugs": { - "url": "https://github.com/apache/echarts/issues", - "email": "dev@echarts.apache.org" + "url": "https://github.com/appflow-ai/echarts/issues" }, "repository": { "type": "git", - "url": "git+https://github.com/apache/echarts.git" + "url": "git+https://github.com/appflow-ai/echarts.git" }, "sideEffects": [ "index.js", From 719ba050fc451eed7ddbf60f294c1fe63dfa1f78 Mon Sep 17 00:00:00 2001 From: chell <361531684@qq.com> Date: Fri, 3 Mar 2023 16:27:08 +0800 Subject: [PATCH 3/3] feat: publish to appflow github registry --- .github/workflows/nightly-next.yml | 4 ++-- .github/workflows/nightly.yml | 6 +++--- .github/workflows/source-release.yml | 2 +- .npmrc | 1 + 4 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 .npmrc diff --git a/.github/workflows/nightly-next.yml b/.github/workflows/nightly-next.yml index c2a6dd870f..0454d5dad1 100644 --- a/.github/workflows/nightly-next.yml +++ b/.github/workflows/nightly-next.yml @@ -25,7 +25,7 @@ jobs: - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: - registry-url: https://registry.npmjs.org/ + registry-url: https://npm.pkg.github.com/ - name: Setup and publish nightly run: | node build/nightly/prepare.js --next @@ -38,4 +38,4 @@ jobs: npm run test:dts npm publish --tag next env: - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index ddbcd98412..078c5c654e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -11,7 +11,7 @@ on: jobs: build: runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'apache' }} + if: ${{ github.repository_owner == 'appflow-ai' }} strategy: matrix: @@ -22,7 +22,7 @@ jobs: - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: - registry-url: https://registry.npmjs.org/ + registry-url: https://npm.pkg.github.com/ - name: Setup and publish nightly run: | node build/nightly/prepare.js @@ -35,4 +35,4 @@ jobs: npm run test:dts npm publish env: - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/source-release.yml b/.github/workflows/source-release.yml index 87b85d5ccb..c1376dc3aa 100644 --- a/.github/workflows/source-release.yml +++ b/.github/workflows/source-release.yml @@ -7,7 +7,7 @@ on: jobs: materials: runs-on: ubuntu-latest - if: ${{ github.repository_owner == 'apache' }} + if: ${{ github.repository_owner == 'appflow-ai' }} strategy: matrix: diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..83159a6a33 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +@appflow-ai:registry=https://npm.pkg.github.com \ No newline at end of file