Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/chart/sankey/SankeySeries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ import {
GraphEdgeItemObject,
OptionDataValueNumeric,
DefaultEmphasisFocus,
CallbackDataParams
CallbackDataParams,
RoamOptionMixin
} from '../../util/types';
import GlobalModel from '../../model/Global';
import SeriesData from '../../data/SeriesData';
import { LayoutRect } from '../../util/layout';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
import type View from '../../coord/View';


type FocusNodeAdjacency = boolean | 'inEdges' | 'outEdges' | 'allEdges';
Expand Down Expand Up @@ -95,7 +97,8 @@ export interface SankeyLevelOption extends SankeyNodeStateOption, SankeyEdgeStat
export interface SankeySeriesOption
extends SeriesOption<SankeyBothStateOption<CallbackDataParams>, ExtraStateOption>,
SankeyBothStateOption<CallbackDataParams>,
BoxLayoutOptionMixin {
BoxLayoutOptionMixin,
RoamOptionMixin {
type?: 'sankey'

/**
Expand Down Expand Up @@ -148,6 +151,8 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
static readonly type = 'series.sankey';
readonly type = SankeySeriesModel.type;

coordinateSystem: View;

levelModels: Model<SankeyLevelOption>[];

layoutInfo: LayoutRect;
Expand Down Expand Up @@ -213,6 +218,14 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
dataItem.localY = localPosition[1];
}

setCenter(center: number[]) {
this.option.center = center;
}

setZoom(zoom: number) {
this.option.zoom = zoom;
}

/**
* Return the graphic data structure
*
Expand Down Expand Up @@ -297,6 +310,11 @@ class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {

layoutIterations: 32,

// true | false | 'move' | 'scale', see module:component/helper/RoamController.
roam: false,
center: null,
zoom: 1,

label: {
show: true,
position: 'right',
Expand Down
89 changes: 85 additions & 4 deletions src/chart/sankey/SankeyView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle';
import { getECData } from '../../util/innerStore';
import { isString, retrieve3 } from 'zrender/src/core/util';
import type { GraphEdge } from '../../data/Graph';
import RoamController from '../../component/helper/RoamController';
import { onIrrelevantElement } from '../../component/helper/cursorHelper';
import * as roamHelper from '../../component/helper/roamHelper';
import View from '../../coord/View';

class SankeyPathShape {
x1 = 0;
Expand Down Expand Up @@ -106,15 +110,28 @@ class SankeyView extends ChartView {
readonly type = SankeyView.type;

private _model: SankeySeriesModel;

private _mainGroup = new graphic.Group();
private _focusAdjacencyDisabled = false;

private _data: SeriesData;

private _controller: RoamController;
private _controllerHost: roamHelper.RoamControllerHost;

init(ecModel: GlobalModel, api: ExtensionAPI): void {
this._controller = new RoamController(api.getZr());

this._controllerHost = {
target: this.group
} as roamHelper.RoamControllerHost;

this.group.add(this._mainGroup);
}

render(seriesModel: SankeySeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
const sankeyView = this;
const graph = seriesModel.getGraph();
const group = this.group;
const group = this._mainGroup;
const layoutInfo = seriesModel.layoutInfo;
// view width
const width = layoutInfo.width;
Expand All @@ -128,8 +145,8 @@ class SankeyView extends ChartView {

group.removeAll();

group.x = layoutInfo.x;
group.y = layoutInfo.y;
this._updateViewCoordSys(seriesModel, api);
this._updateController(seriesModel, ecModel, api);

// generate a bezire Curve for each edge
graph.eachEdge(function (edge) {
Expand Down Expand Up @@ -346,6 +363,70 @@ class SankeyView extends ChartView {
}

dispose() {
this._controller && this._controller.dispose();
this._controllerHost = null;
}

private _updateController(
seriesModel: SankeySeriesModel,
ecModel: GlobalModel,
api: ExtensionAPI
) {
const controller = this._controller;
const controllerHost = this._controllerHost;
const group = this.group;
controller.setPointerChecker(function (e, x, y) {
const rect = group.getBoundingRect();
rect.applyTransform(group.transform);
return rect.contain(x, y)
&& !onIrrelevantElement(e, api, seriesModel);
});

controller.enable(seriesModel.get('roam'));
controllerHost.zoomLimit = seriesModel.get('scaleLimit');
controllerHost.zoom = seriesModel.coordinateSystem.getZoom();

controller
.off('pan')
.off('zoom')
.on('pan', (e) => {
roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
api.dispatchAction({
seriesId: seriesModel.id,
type: 'sankeyRoam',
dx: e.dx,
dy: e.dy
});
})
.on('zoom', (e) => {
roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
api.dispatchAction({
seriesId: seriesModel.id,
type: 'sankeyRoam',
zoom: e.scale,
originX: e.originX,
originY: e.originY
});
// Only update label layout on zoom
api.updateLabelLayout();
});
}

private _updateViewCoordSys(seriesModel: SankeySeriesModel, api: ExtensionAPI) {
const layoutInfo = seriesModel.layoutInfo;
const width = layoutInfo.width;
const height = layoutInfo.height;

const viewCoordSys = seriesModel.coordinateSystem = new View();
viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');

viewCoordSys.setBoundingRect(0, 0, width, height);

viewCoordSys.setCenter(seriesModel.get('center'), api);
viewCoordSys.setZoom(seriesModel.get('zoom'));

this._mainGroup.x = layoutInfo.x;
this._mainGroup.y = layoutInfo.y;
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/chart/sankey/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import sankeyLayout from './sankeyLayout';
import sankeyVisual from './sankeyVisual';
import { Payload } from '../../util/types';
import GlobalModel from '../../model/Global';
import { updateCenterAndZoom, RoamPayload } from '../../action/roamHelper';
import type ExtensionAPI from '../../core/ExtensionAPI';

interface SankeyDragNodePayload extends Payload {
localX: number
Expand Down Expand Up @@ -53,4 +55,21 @@ export function install(registers: EChartsExtensionInstallRegisters) {
});
});

}
registers.registerAction({
type: 'sankeyRoam',
event: 'sankeyRoam',
update: 'none'
}, function (payload: RoamPayload, ecModel: GlobalModel, api: ExtensionAPI) {
ecModel.eachComponent({
mainType: 'series', subType: 'sankey', query: payload
}, function (seriesModel: SankeySeriesModel) {
const coordSys = seriesModel.coordinateSystem;
const res = updateCenterAndZoom(coordSys, payload, undefined, api);

seriesModel.setCenter
&& seriesModel.setCenter(res.center);
seriesModel.setZoom
&& seriesModel.setZoom(res.zoom);
});
});
}
139 changes: 139 additions & 0 deletions test/sankey-roam.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.