Skip to content

Commit

Permalink
feat: 添加setState逻辑和tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
zengyue committed Sep 3, 2021
1 parent 72f829a commit 0b61e1e
Show file tree
Hide file tree
Showing 18 changed files with 417 additions and 40 deletions.
24 changes: 13 additions & 11 deletions packages/f2-next/src/base/component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import Layout from './layout';

class Component {
container: any;
props: any;
state: any;
context: any;
refs: {
[key: string]: any;
}
container: any;
layout: Layout;
updater: any;

animate: boolean;

Expand All @@ -19,17 +25,13 @@ class Component {
__shouldRender = true;
// actions: any;

// TODO for TypeScript
state: any;
context: any;
refs: {
[key: string]: any;
}

constructor(props: any) {
constructor(props: any, context?, updater?) {
const { animate } = props;
this.__props = props;
this.props = props;
this.context = context;
this.updater = updater;
this.state = {};
this.animate = animate;
}
init({ container, layout }) {
Expand All @@ -42,8 +44,8 @@ class Component {
// TODO mounted
mount() {
}
// TODO
setState() {
setState(partialState) {
this.updater.enqueueSetState(this, partialState);
}
beforeUpdate() {
}
Expand Down
6 changes: 3 additions & 3 deletions packages/f2-next/src/base/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import equal from './equal';
class ContainerComponent extends Component {
components: Component[];

constructor(props: any) {
super(props);
constructor(props: any, context?, updater?) {
super(props, context, updater);

const { children } = props;
const components = map(children, (child: JSX.Element) => {
Expand Down Expand Up @@ -62,7 +62,7 @@ class ContainerComponent extends Component {

// 这里 一定是 F2 Component 了
// @ts-ignore
const component = new type(props);
const component = new type(props, {}, this.updater);

// 设置ref
if (ref) {
Expand Down
5 changes: 4 additions & 1 deletion packages/f2-next/src/canvas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Container from '../base/container';
import Layout from '../base/layout';
import Animation from './animation';
import { px2hd } from '../util';
import { createUpdater } from './updater';

interface ChartUpdateProps {
pixelRatio?: number,
Expand Down Expand Up @@ -54,8 +55,10 @@ class Canvas extends Component implements IF2Canvas {
height: canvasHeight
});

const updater = createUpdater(this);

const componentTree = createComponentTree(children, { canvas: this, width: canvasWidth, height: canvasHeight, context, layout });
const component = new Container({ children: componentTree, animate });
const component = new Container({ children: componentTree, animate }, {}, updater);
component.init({ layout, container: canvas });

this.canvas = canvas;
Expand Down
70 changes: 70 additions & 0 deletions packages/f2-next/src/canvas/updater.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

function createUpdater(canvas) {
const setStateQueue = [];
const renderQueue = [];

function process() {
let item;
let component;
let shouldRender = false;
while ((item = setStateQueue.shift())) {
const { state, component } = item;

// 如果没有prevState,则将当前的state作为初始的prevState
if (!component.prevState) {
component.prevState = Object.assign({}, component.state);
}

// 如果stateChange是一个方法,也就是setState的第二种形式
if (typeof state === "function") {
Object.assign(
component.state,
state(component.prevState, component.props)
);
} else {
// 如果stateChange是一个对象,则直接合并到setState中
Object.assign(component.state, state);
}

component.prevState = component.state;
}

while ((component = renderQueue.shift())) {
component.__shouldRender = true;
component.render();
shouldRender = true;
}

if (shouldRender) {
canvas.render();
}
}

function enqueueSetState(component, state) {
if (setStateQueue.length === 0) {
setTimeout(process, 0);
}
setStateQueue.push({
component,
state,
});
if (renderQueue.indexOf(component) < 0) {
renderQueue.push(component);
}
}

const updater = {
// isMounted: function(publicInstance) {
// return false;
// },
// enqueueForceUpdate: function(publicInstance) {
// },
// enqueueReplaceState: function(publicInstance, completeState) {
// },
enqueueSetState,
};

return updater;
}

export { createUpdater };
27 changes: 18 additions & 9 deletions packages/f2-next/src/chart/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class Chart extends Container implements IChart, ThemeMixin, CoordMixin, ScaleMi
theme: any;
setTheme: (theme) => any;

constructor(props) {
super(props)
constructor(props, context?, updater?) {
super(props, context, updater);

const { data } = props;
// 记录data, 全局唯一
Expand Down Expand Up @@ -106,23 +106,32 @@ class Chart extends Container implements IChart, ThemeMixin, CoordMixin, ScaleMi
// 1. _syncYScales
}

getXScales() {
getGeometrys() {
const { components } = this;
return components.filter(component => {
// @ts-ignore
return component.isGeometry;
}).map(component => {
});
}

getSnapRecords(point) {
const geometrys = this.getGeometrys();
if (!geometrys.length) return;
// @ts-ignore
return geometrys[0].getSnapRecords(point);
}

getXScales() {
const geometrys = this.getGeometrys();
return geometrys.map(component => {
// @ts-ignore
return component.getXScale();
});
}

getYScales() {
const { components } = this;
return components.filter(component => {
// @ts-ignore
return component.isGeometry;
}).map(component => {
const geometrys = this.getGeometrys();
return geometrys.map(component => {
// @ts-ignore
return component.getYScale();
});
Expand Down
54 changes: 44 additions & 10 deletions packages/f2-next/src/components/geometry/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {
mix,
} from "@antv/util";
import Component from "../../base/component";
import { group as arrayGroup, merge as arrayMerge } from '../../util/array'
import { group as arrayGroup, merge as arrayMerge, values } from '../../util/array'
import Chart from '../../chart';
import * as Adjust from "../../adjust";
import { Linear, Category } from '../../attr';
import { applyMixins } from '../../mixins';
import AttrMixin from '../../mixins/attr';
import { toTimeStamp } from '../../util/index'

// 保留原始数据的字段
const FIELD_ORIGIN = "origin";
Expand Down Expand Up @@ -48,6 +49,7 @@ class Geometry extends Component implements AttrMixin {
createAttr: (option) => any;
setAttrRange: (attrName: string, range) => any;
getAttr: (attrName: string) => any;
getAttrOption: (attrName: string) => any;
getAttrValue: (attrName, record) => any;


Expand Down Expand Up @@ -366,32 +368,64 @@ class Geometry extends Component implements AttrMixin {
return chart.getScale(field);
}

_getSnap(scale, invertPointX) {
if (scale.isCategory) {
return scale.invert(invertPointX);
}

// linear 类型
const invertValue = scale.invert(invertPointX);
const values = scale.values;
const len = values.length;
// 如果只有1个点直接返回第1个点
if (len === 1) {
return values[0];
}
// 第1个点和第2个点之间
if ((values[0] + values[1]) / 2 > invertValue) {
return values[0];
}
// 最后2个点
if ((values[len - 2] + values[len - 1]) / 2 <= invertValue) {
return values[len - 1];
}
for (let i = 1; i < len; i++) {
// 中间的点
if ((values[i - 1] + values[i]) / 2 <= invertValue && (values[i + 1] + values[i]) / 2 > invertValue) {
return values[i];
}
}
return null;
}

getSnapRecords(point) {
const { chart, mappedArray } = this;
const { coord } = chart;
const invertPoint = coord.invertPoint(point);
const xScale = this.getXScale();

// 如果不在coord坐标范围内,直接返回空
if (invertPoint.x < 0 || invertPoint.y < 0) {
return [];
}

let rst = [];
const value = this._getSnap(xScale, invertPoint.x);
if (!value) {
return rst;
}
const { field: xfield } = xScale;
for (let i = 0; i < mappedArray.length; i++) {
const data = mappedArray[i];

let min = Infinity;
let minRecord = null;
for (let j = 0, len = data.length; j < len; j++) {
const record = data[j];
const { position } = record;
const offset = Math.abs(invertPoint.x - position.x);
if (min > offset) {
min = offset;
minRecord = record;
const originValue = record[FIELD_ORIGIN][xfield];
if (xScale.type === 'timeCat' && toTimeStamp(originValue) === value) {
rst.push(record);
} else if (originValue === value){
rst.push(record);
}
}
rst.push(minRecord);
}
return rst;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/f2-next/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export { default as Line, withLine, LineView } from './line';
export { default as Interval, withInterval, IntervalView } from './interval';
// // export { default as Point, withPoint, PointView } from './point';
export { default as Axis, withAxis, AxisView } from './axis';
// // export { default as Legend, withLegend, LegendView } from './legend';
export { default as Legend, withLegend, LegendView } from './legend';
// // export { default as Guide, withGuide, ImageGuide, TextGuide, PointGuide, LineGuide } from './guide';
// // export { default as Tooltip, withTooltip, TooltipView } from './tooltip';
export { default as Tooltip, withTooltip, TooltipView } from './tooltip';
// // export { default as Treemap, withTreemap, TreemapView } from './treemap';
export { default as Sunburst, withSunburst, SunburstView } from './sunburst';
// // export { default as Gauge } from './gauge';
Expand Down
1 change: 1 addition & 0 deletions packages/f2-next/src/components/interval/withInterval.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default View => {
const record = data[j];
const { position, size = defaultSize } = record;
const rect = convertRect({ ...position, size, y0 });
mix(position, rect);
mix(record, coord.convertRect(rect));
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/f2-next/src/components/legend/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import withLegend from './withLegend';
import LegendView from './legendView';

export { withLegend, LegendView };
export default withLegend(LegendView);
51 changes: 51 additions & 0 deletions packages/f2-next/src/components/legend/legendView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { jsx } from '../../jsx';

export default (props) => {
const { items } = props;
return null;
return (
<group style={{
left: 50,
top: 50,
width: 100,
flexDirection: 'row'
}}>
{
items.map(item => {
const { color, name, value } = item;
return (
<group style={{ flexDirection: 'row', flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<circle
style={{
width: '20px',
height: '20px',
}}
attrs={{
fill: color,
r: '6px'
}}
/>
<text
attrs={{
fill: 'black',
text: item.name,
}}
/>
{
value ?
<text
attrs={{
fill: 'black',
text: `: ${value}`,
}}
/>
:
null
}
</group>
)
})
}
</group>
);
}
Loading

0 comments on commit 0b61e1e

Please sign in to comment.