profile
viewpoint
Zhe Lin / ParroT parrotdance University of Electronic Science and Technology of China Shenzhen, China https://www.parrotdance.art FE main but love everything

parrotdance/parrot-resume 8

A markdown editor

parrotdance/paroflow 6

Paroflow is a simple flow-chart builder which works with D3.js and SVG

parrotdance/worst_code_I_saw 5

Store something code with bad taste

parrotdance/awesome-coding-js 2

用JavaScript实现的算法和数据结构,附详细解释和刷题指南

parrotdance/block_game 2

A not too bad game, base on classical game -- Tetris.

parrotdance/parrot-dark-syntax 2

A pretty syntax theme in Atom editor. Recommend use it with dark UI theme.

parrotdance/parrotdance.github.io 2

Seems to be a blog

parrotdance/vue-accordion 2

Simple accordion menu component for Vue.js

parrotdance/parrot-blog 1

The place where ParroT retell what it thought and what it said.

push eventparrot-cend/speaking-parrot

dependabot[bot]

commit sha a2fdf4e01c767c2a7be64dfb73d185854669d1f8

Bump websocket-extensions from 0.1.3 to 0.1.4 Bumps [websocket-extensions](https://github.com/faye/websocket-extensions-node) from 0.1.3 to 0.1.4. - [Release notes](https://github.com/faye/websocket-extensions-node/releases) - [Changelog](https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md) - [Commits](https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4) Signed-off-by: dependabot[bot] <support@github.com>

view details

Zhe Lin / ParroT

commit sha 9a5efa362d8892deac53c1c7eff0ad9c8f6a3782

Merge pull request #1 from parrot-cend/dependabot/npm_and_yarn/websocket-extensions-0.1.4 Bump websocket-extensions from 0.1.3 to 0.1.4

view details

push time in 14 hours

PR merged parrot-cend/speaking-parrot

Bump websocket-extensions from 0.1.3 to 0.1.4 dependencies

Bumps websocket-extensions from 0.1.3 to 0.1.4. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/faye/websocket-extensions-node/blob/master/CHANGELOG.md">websocket-extensions's changelog</a>.</em></p> <blockquote> <h3>0.1.4 / 2020-06-02</h3> <ul> <li>Remove a ReDoS vulnerability in the header parser (CVE-2020-7662, reported by Robert McLaughlin)</li> <li>Change license from MIT to Apache 2.0</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/faye/websocket-extensions-node/commit/8efd0cd6e35faf9bb9cb08759be1e27082177d43"><code>8efd0cd</code></a> Bump version to 0.1.4</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/3dad4ad44a8c5f74d4f8f4efd3f9d6e0b5df3051"><code>3dad4ad</code></a> Remove ReDoS vulnerability in the Sec-WebSocket-Extensions header parser</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/4a76c75efb1c5d6a2f60550e9501757458d19533"><code>4a76c75</code></a> Add Node versions 13 and 14 on Travis</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/44a677a9c0631daed0b0f4a4b68c095b624183b8"><code>44a677a</code></a> Formatting change: {...} should have spaces inside the braces</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/f6c50aba0c20ff45b0f87cea33babec1217ec3f5"><code>f6c50ab</code></a> Let npm reformat package.json</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/2d211f3705d52d9efb4f01daf5a253adf828592e"><code>2d211f3</code></a> Change markdown formatting of docs.</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/0b620834cc1e1f2eace1d55ab17f71d90d88271d"><code>0b62083</code></a> Update Travis target versions.</li> <li><a href="https://github.com/faye/websocket-extensions-node/commit/729a4653073fa8dd020561113513bfa2e2119415"><code>729a465</code></a> Switch license to Apache 2.0.</li> <li>See full diff in <a href="https://github.com/faye/websocket-extensions-node/compare/0.1.3...0.1.4">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+3 -3

0 comment

1 changed file

dependabot[bot]

pr closed time in 14 hours

push eventparrot-cend/speaking-parrot

dependabot[bot]

commit sha 5450bf3084a16ed1d55abbbbad3be0e025825c4e

Bump elliptic from 6.5.2 to 6.5.3 Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.3. - [Release notes](https://github.com/indutny/elliptic/releases) - [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3) Signed-off-by: dependabot[bot] <support@github.com>

view details

Zhe Lin / ParroT

commit sha 4bb2932e129abc6dcbdbfd5b366a8d38fd340da2

Merge pull request #3 from parrot-cend/dependabot/npm_and_yarn/elliptic-6.5.3 Bump elliptic from 6.5.2 to 6.5.3

view details

push time in 14 hours

PR merged parrot-cend/speaking-parrot

Bump elliptic from 6.5.2 to 6.5.3 dependencies

Bumps elliptic from 6.5.2 to 6.5.3. <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/indutny/elliptic/commit/8647803dc3d90506aa03021737f7b061ba959ae1"><code>8647803</code></a> 6.5.3</li> <li><a href="https://github.com/indutny/elliptic/commit/856fe4d99fe7b6200556e6400b3bf585b1721bec"><code>856fe4d</code></a> signature: prevent malleability and overflows</li> <li>See full diff in <a href="https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.3">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+3 -3

0 comment

1 changed file

dependabot[bot]

pr closed time in 14 hours

push eventparrotdance/parrotdance

Zhe Lin / ParroT

commit sha dfd529a999a857a668016209e72ccc7c0507872d

Update README.md

view details

push time in 14 hours

push eventparrotdance/parrotdance

Zhe Lin / ParroT

commit sha 74f14576ba192e7cb8a47048945d155dd69b54d6

Update README.md

view details

push time in 14 hours

push eventparrotdance/parrotdance

Zhe Lin / ParroT

commit sha d2dfb31f383fc02cc8acf8cc0a55ef43fc2d341f

Update README.md

view details

push time in 14 hours

create barnchparrotdance/parrotdance

branch : master

created branch time in 15 hours

created repositoryparrotdance/parrotdance

created time in 15 hours

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 interface FlowChartNodeOptions {   minWidth?: number   minHeight?: number   extendLength?: number+  borderRadius?: number } interface FlowChartEdgeOptions {   direction?: string   color?: string   width?: number   pattern?: LinkPattern }-interface Node {++class Node {   name: string-  center: [number, number]+  nodeId: number+  center: [number, number] = [0, 0]   width: number   height: number-  text: string[]+  text: string[] = ['']   extendLength: number-  style: Dictionary-  links: Link[]-}-interface EdgeOption {-  name: string-  direction: EdgeDirection-}-interface Edge {-  source: EdgeOption-  target: EdgeOption-  style: Dictionary-  pattern?: LinkPattern+  coordinateXY: Dictionary<Coordinate> = {}+  style: Dictionary = {}+  links: Link[] = []+  targetLinks: Link[] = []+  svgEl: any+  constructor(nodeArg: any) {+    this.name = nodeArg.name+    this.nodeId = nodeArg.nodeId+    this.center = nodeArg.center+    this.width = nodeArg.width || 0+    this.height = nodeArg.height || 0+    this.text = nodeArg.text+    this.extendLength = nodeArg.extendLength || 0+    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)+    this.style = nodeArg.style+    this.svgEl = nodeArg.svgEl+  }++  private getBoundPoint(node: Node, dir: EdgeDirection, extend: boolean) {+    const {+      center: [x, y],+      width,+      height,+      extendLength+    } = node+    let dx = 0,+      dy = 0+    const finalExtendLength = extend+      ? extendLength || this.extendLength+      : 0+    if (dir === 'top') {+      dy = -0.5 * height - finalExtendLength+    } else if (dir === 'right') {+      dx = 0.5 * width + finalExtendLength+    } else if (dir === 'bottom') {+      dy = 0.5 * height + finalExtendLength+    } else {+      dx = -0.5 * width - finalExtendLength+    }+    return [x + dx, y + dy] as Coordinate+  }++  public drawNode(_svg: any, boxId: number) {+    this.nodeId = boxId+    this.svgEl = _svg+    const g = _svg.append('g').attr('class', 'paro-node' + boxId).attr('nodeId', boxId)+    const { width, height } = this+    const [cx, cy] = this.center+    const { borderColor, backgroundColor, fontColor, borderRadius, lineHeight, fontSize } = this.style+    // render rect+    g.append('rect')+      .attr('rectId', boxId)+      .attr('class', 'paro-node-rect')+      .attr('x', cx - width / 2)+      .attr('y', cy - height / 2)+      .attr('width', width)+      .attr('height', height)+      .attr('stroke', borderColor)+      .attr('fill', backgroundColor)+      .attr('stroke-width', '2')+      .attr('rx', borderRadius)+      .attr('ry', borderRadius)+    // render text+    const t = g+      .append('text')+      .attr('textId', boxId)+      .attr('class', 'paro-node-text' + boxId)+      .attr('text-anchor', 'middle')+      .attr('font-size', fontSize)+      .attr('fill', fontColor)+    let textPosYOffset = 0+    const textLines = this.text.length+    if (textLines === 1) {+      textPosYOffset = 0+    } else if (textLines % 2 !== 0) {+      textPosYOffset = ((1 - textLines) / 2) * lineHeight+    } else {+      textPosYOffset = (0.5 - textLines / 2) * lineHeight+    }+    const STATIC_OFFSET = 5 // I don't know why+    this.text.forEach((str: string, i: number) => {+      const y =+        this.center[1] ++        textPosYOffset ++        i * lineHeight ++        STATIC_OFFSET+      t.append('tspan')+        .attr('class', 'paro-node-tspan' + boxId)+        .attr('x', this.center[0])+        .attr('y', y)+        .text(str)+    })+  }++  public drawLinks() {+    this.links.forEach((link: Link) => {+      link.drawLinkLine(this.nodeId, this.svgEl)+    })+  }++  public drawTargetLinks() {+    this.targetLinks.forEach((link: Link) => {+      link.drawLinkLine()+    })+  }++  public changeXY(resetXY: Coordinate) {+    const [x1, y1] = resetXY+    this.center = [x1 + (this.width / 2), y1 + (this.height / 2)]++    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)++    this.links.forEach((link: Link) => {+      link.changeLink();+    })+    this.targetLinks.forEach((link: Link) => {+      link.changeLink();+    })+  } } interface Dictionary<T = any> {   [index: string]: T }+class DirectionPoint {+  posTrunXY: string+  negTrunXY: string+  point: Coordinate = [0, 0]+  otherPoint: Coordinate = [0, 0]+  direction?: PointDirection+  constructor(option: any) {+    this.posTrunXY = option.posTrunXY+    this.negTrunXY = option.negTrunXY+    this.point = option.point+    this.otherPoint = option.otherPoint+    this.direction = option.direction+  }+}+class Link {+  p: any+  pathEl: any+  sourceNode: Node+  targetNode: Node+  sourceXY: [number, number] = [0, 0]+  sourceOriginXY: [number, number] = [0, 0]+  targetXY: [number, number] = [0, 0]+  targetOriginXY: [number, number] = [0, 0]+  centerPoint: [number, number] = [0, 0]+  //InflectionPoint must in rect+  InflectionPoint?: Coordinate+  outDir: EdgeDirection = 'right'+  inDir: EdgeDirection = 'left'+  svgEl: any+  lineId?: number+  style: Dictionary = {}++  private static nodeMap: Dictionary<Node>++  constructor(linkArg: any) {+    this.sourceNode = linkArg.sourceNode+    this.targetNode = linkArg.targetNode+    this.sourceXY = linkArg.sourceXY+    this.sourceOriginXY = linkArg.sourceOriginXY+    this.targetXY = linkArg.targetXY+    this.targetOriginXY = linkArg.targetOriginXY+    this.centerPoint = this.getCentrePoint(this.sourceXY, this.targetXY)+    this.InflectionPoint = linkArg.InflectionPoint+    this.outDir = linkArg.outDir+    this.inDir = linkArg.inDir+    this.style = linkArg.style+  }++  static setNodeMap(nodeMap: Dictionary<Node>) {+    this.nodeMap = nodeMap+  }++  // Is the line formed by two points parallel to the coordinate axis+  private isParallelAxis(a: Coordinate, b: Coordinate) {+    const [x1, y1] = a+    const [x2, y2] = b+    if (x1 == x2 || y1 == y2) {+      return true+    } else {+      return false+    }+  }++  private isSamePoint(p1: Coordinate, p2: Coordinate): boolean {+    return p1.toString() == p2.toString()+  }++  private getCentrePoint(a: Coordinate, b: Coordinate): Coordinate {+    const [x1, y1] = a+    const [x2, y2] = b+    return [(x1 + x2) / 2, (y1 + y2) / 2]+  }

类似的工具函数都可以提取到类定义以外, 或者写在单独的文件中供所有类引用. 否则每次创建该类的实例都会注册新的函数. 参考 line 480: getTextLength() 方法的定义

Mrliuchanghao

comment created time in 4 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 interface FlowChartNodeOptions {   minWidth?: number   minHeight?: number   extendLength?: number+  borderRadius?: number } interface FlowChartEdgeOptions {   direction?: string   color?: string   width?: number   pattern?: LinkPattern }-interface Node {++class Node {   name: string-  center: [number, number]+  nodeId: number+  center: [number, number] = [0, 0]   width: number   height: number-  text: string[]+  text: string[] = ['']   extendLength: number-  style: Dictionary-  links: Link[]-}-interface EdgeOption {-  name: string-  direction: EdgeDirection-}-interface Edge {-  source: EdgeOption-  target: EdgeOption-  style: Dictionary-  pattern?: LinkPattern+  coordinateXY: Dictionary<Coordinate> = {}+  style: Dictionary = {}+  links: Link[] = []+  targetLinks: Link[] = []+  svgEl: any+  constructor(nodeArg: any) {+    this.name = nodeArg.name+    this.nodeId = nodeArg.nodeId+    this.center = nodeArg.center+    this.width = nodeArg.width || 0+    this.height = nodeArg.height || 0+    this.text = nodeArg.text+    this.extendLength = nodeArg.extendLength || 0+    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)+    this.style = nodeArg.style+    this.svgEl = nodeArg.svgEl+  }++  private getBoundPoint(node: Node, dir: EdgeDirection, extend: boolean) {+    const {+      center: [x, y],+      width,+      height,+      extendLength+    } = node+    let dx = 0,+      dy = 0+    const finalExtendLength = extend+      ? extendLength || this.extendLength+      : 0+    if (dir === 'top') {+      dy = -0.5 * height - finalExtendLength+    } else if (dir === 'right') {+      dx = 0.5 * width + finalExtendLength+    } else if (dir === 'bottom') {+      dy = 0.5 * height + finalExtendLength+    } else {+      dx = -0.5 * width - finalExtendLength+    }+    return [x + dx, y + dy] as Coordinate+  }++  public drawNode(_svg: any, boxId: number) {+    this.nodeId = boxId+    this.svgEl = _svg+    const g = _svg.append('g').attr('class', 'paro-node' + boxId).attr('nodeId', boxId)+    const { width, height } = this+    const [cx, cy] = this.center+    const { borderColor, backgroundColor, fontColor, borderRadius, lineHeight, fontSize } = this.style+    // render rect+    g.append('rect')+      .attr('rectId', boxId)+      .attr('class', 'paro-node-rect')+      .attr('x', cx - width / 2)+      .attr('y', cy - height / 2)+      .attr('width', width)+      .attr('height', height)+      .attr('stroke', borderColor)+      .attr('fill', backgroundColor)+      .attr('stroke-width', '2')+      .attr('rx', borderRadius)+      .attr('ry', borderRadius)+    // render text+    const t = g+      .append('text')+      .attr('textId', boxId)+      .attr('class', 'paro-node-text' + boxId)+      .attr('text-anchor', 'middle')+      .attr('font-size', fontSize)+      .attr('fill', fontColor)+    let textPosYOffset = 0+    const textLines = this.text.length+    if (textLines === 1) {+      textPosYOffset = 0+    } else if (textLines % 2 !== 0) {+      textPosYOffset = ((1 - textLines) / 2) * lineHeight+    } else {+      textPosYOffset = (0.5 - textLines / 2) * lineHeight+    }+    const STATIC_OFFSET = 5 // I don't know why+    this.text.forEach((str: string, i: number) => {+      const y =+        this.center[1] ++        textPosYOffset ++        i * lineHeight ++        STATIC_OFFSET+      t.append('tspan')+        .attr('class', 'paro-node-tspan' + boxId)+        .attr('x', this.center[0])+        .attr('y', y)+        .text(str)+    })+  }++  public drawLinks() {+    this.links.forEach((link: Link) => {+      link.drawLinkLine(this.nodeId, this.svgEl)+    })+  }++  public drawTargetLinks() {+    this.targetLinks.forEach((link: Link) => {+      link.drawLinkLine()+    })+  }++  public changeXY(resetXY: Coordinate) {+    const [x1, y1] = resetXY+    this.center = [x1 + (this.width / 2), y1 + (this.height / 2)]++    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)++    this.links.forEach((link: Link) => {+      link.changeLink();+    })+    this.targetLinks.forEach((link: Link) => {+      link.changeLink();+    })+  } } interface Dictionary<T = any> {   [index: string]: T }+class DirectionPoint {+  posTrunXY: string+  negTrunXY: string+  point: Coordinate = [0, 0]+  otherPoint: Coordinate = [0, 0]+  direction?: PointDirection+  constructor(option: any) {+    this.posTrunXY = option.posTrunXY+    this.negTrunXY = option.negTrunXY+    this.point = option.point+    this.otherPoint = option.otherPoint+    this.direction = option.direction+  }+}+class Link {+  p: any+  pathEl: any+  sourceNode: Node+  targetNode: Node+  sourceXY: [number, number] = [0, 0]+  sourceOriginXY: [number, number] = [0, 0]+  targetXY: [number, number] = [0, 0]+  targetOriginXY: [number, number] = [0, 0]+  centerPoint: [number, number] = [0, 0]+  //InflectionPoint must in rect+  InflectionPoint?: Coordinate+  outDir: EdgeDirection = 'right'+  inDir: EdgeDirection = 'left'+  svgEl: any+  lineId?: number+  style: Dictionary = {}++  private static nodeMap: Dictionary<Node>++  constructor(linkArg: any) {+    this.sourceNode = linkArg.sourceNode+    this.targetNode = linkArg.targetNode+    this.sourceXY = linkArg.sourceXY+    this.sourceOriginXY = linkArg.sourceOriginXY+    this.targetXY = linkArg.targetXY+    this.targetOriginXY = linkArg.targetOriginXY+    this.centerPoint = this.getCentrePoint(this.sourceXY, this.targetXY)+    this.InflectionPoint = linkArg.InflectionPoint+    this.outDir = linkArg.outDir+    this.inDir = linkArg.inDir+    this.style = linkArg.style+  }++  static setNodeMap(nodeMap: Dictionary<Node>) {+    this.nodeMap = nodeMap+  }++  // Is the line formed by two points parallel to the coordinate axis+  private isParallelAxis(a: Coordinate, b: Coordinate) {+    const [x1, y1] = a+    const [x2, y2] = b+    if (x1 == x2 || y1 == y2) {+      return true+    } else {+      return false+    }
return x1 === x2 || y1 === y2

这样会不会好点?

Mrliuchanghao

comment created time in 4 days

pull request commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

发现 bug: 存在多行文本的节点一旦被拖拽, 所有文本都会被渲染到起始行.

Mrliuchanghao

comment created time in 4 days

pull request commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

另外尽可能将所有类型声明移动到文件开头或一个独立文件中, 不要将类型和逻辑混在一起.

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 class FlowChart {       console.error(         `[P-Flow warn]: Can't find source node: ${source}.\n\nPlease check if add node correctly before or add it before call render().`       )+      return this     }     if (!targetExist) {       console.error(         `[P-Flow warn]: Can't find target node: ${target}.\n\nPlease check if add node correctly before or add it before call render().`       )+      return this     }     const [outDir, inDir] = direction       ? direction.split('-')       : defaultDir.split('-')-    const from: EdgeOption = {-      name: source,-      direction: outDir as EdgeDirection-    }-    const to = {-      name: target,-      direction: inDir as EdgeDirection-    }-    this.edges.push({-      source: from,-      target: to,-      style: {-        color,-        width-      },-      pattern-    })++    const link = new Link(+      {+        sourceNode: sourceExist,+        targetNode: targetExist,+        outDir: outDir,+        inDir: inDir,+        sourceXY: sourceExist.coordinateXY['ex' + outDir],+        sourceOriginXY: sourceExist.coordinateXY[outDir],+        targetXY: targetExist.coordinateXY['ex' + inDir],+        targetOriginXY: targetExist.coordinateXY[inDir],+        style: {+          color,+          width+        }+      }+    )+    this.links.push(link)+    sourceExist.links.push(link)+    targetExist.targetLinks.push(link)     return this   }+  private init() {+    this.selectAll = selectAll++  }   public render() {-    const nodeMap: Dictionary<Node> = this.nodes.reduce(-      (map, node) => Object.assign(map, { [node.name]: node }),-      {} as Dictionary<Node>-    )-    this.edges.forEach(edge => {-      const { source, target, style, pattern } = edge-      const sourceNode = nodeMap[source.name]-      const targetNode = nodeMap[target.name]-      if (sourceNode === undefined) {-        throw new Error(-          `Can not find Edge source node: ${(sourceNode as Node).name}.`-        )-      }-      if (targetNode === undefined) {-        throw new Error(-          `Can not find Edge source node: ${(targetNode as Node).name}.`-        )-      }-      sourceNode.links.push({-        source: sourceNode,-        target: targetNode,-        outDir: source.direction,-        inDir: target.direction,-        pattern,-        style-      })-    })+    this.init()     this._svg.html('') // clear svg content for rerender-    this._pathGroup = this._svg.append('g')-    Object.values(nodeMap).forEach((d: Node) => {-      const g = this._svg.append('g').attr('class', 'paro-node')-      const { width, height } = d-      const [cx, cy] = d.center-      const { borderColor, backgroundColor, fontColor } = d.style-      // render rect-      g.append('rect')-        .attr('class', 'paro-node-rect')-        .attr('x', cx - width / 2)-        .attr('y', cy - height / 2)-        .attr('width', width)-        .attr('height', height)-        .attr('stroke', borderColor)-        .attr('fill', backgroundColor)-        .attr('stroke-width', '2')-        .attr('rx', '4')-        .attr('ry', '4')-      // render text-      const t = g-        .append('text')-        .attr('text-anchor', 'middle')-        .attr('font-size', this.options.fontSize)-        .attr('fill', fontColor)-      let textPosYOffset = 0-      const textLines = d.text.length-      if (textLines === 1) {-        textPosYOffset = 0-      } else if (textLines % 2 !== 0) {-        textPosYOffset = ((1 - textLines) / 2) * this.options.lineHeight-      } else {-        textPosYOffset = (0.5 - textLines / 2) * this.options.lineHeight-      }-      const STATIC_OFFSET = 5 // I don't know why-      d.text.forEach((str: string, i: number) => {-        const y =-          d.center[1] +-          textPosYOffset +-          i * this.options.lineHeight +-          STATIC_OFFSET-        t.append('tspan')-          .attr('x', d.center[0])-          .attr('y', y)-          .text(str)-      })-      // render link line-      const groupedLinks: GroupedLinks = d.links.reduce(-        (res: GroupedLinks, link: Link) => {-          if (res[link.outDir]) {-            res[link.outDir].push(link)-          } else {-            res[link.outDir] = [link]-          }-          return res-        },-        {} as GroupedLinks-      )-      Object.values(groupedLinks).forEach((links: Link[]) =>-        links.forEach(link => this.drawLinkLine(link))-      )+    this.nodes.forEach((d: Node, ind) => {+      const nodeAndLinksSVG = this._svg.append('g').attr('class', 'paro-box' + ind).attr('boxId', ind)+      d.drawNode(nodeAndLinksSVG, ind)+      d.drawLinks()     })   }++  public drag() {++    //间隔差值 防止拖动原点发生变化+    let xd: number+    let yd: number+    //文字差值+    let xt: number+    let yt: number+    const _nodes = this.nodes++    const currentSvg = this._svg++    const dragEvent: any = drag()+      .on("drag", function (d: any) {+        const id = select(this).attr('rectId')

此处 this 指向不明, 编辑器报错. 尝试提前获取 this 指向的对象或手动声明其类型为 any

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 class FlowChart {       console.error(         `[P-Flow warn]: Can't find source node: ${source}.\n\nPlease check if add node correctly before or add it before call render().`       )+      return this     }     if (!targetExist) {       console.error(         `[P-Flow warn]: Can't find target node: ${target}.\n\nPlease check if add node correctly before or add it before call render().`       )+      return this     }     const [outDir, inDir] = direction       ? direction.split('-')       : defaultDir.split('-')-    const from: EdgeOption = {-      name: source,-      direction: outDir as EdgeDirection-    }-    const to = {-      name: target,-      direction: inDir as EdgeDirection-    }-    this.edges.push({-      source: from,-      target: to,-      style: {-        color,-        width-      },-      pattern-    })++    const link = new Link(+      {+        sourceNode: sourceExist,+        targetNode: targetExist,+        outDir: outDir,+        inDir: inDir,+        sourceXY: sourceExist.coordinateXY['ex' + outDir],+        sourceOriginXY: sourceExist.coordinateXY[outDir],+        targetXY: targetExist.coordinateXY['ex' + inDir],+        targetOriginXY: targetExist.coordinateXY[inDir],+        style: {+          color,+          width+        }+      }+    )+    this.links.push(link)+    sourceExist.links.push(link)+    targetExist.targetLinks.push(link)     return this   }+  private init() {+    this.selectAll = selectAll++  }   public render() {-    const nodeMap: Dictionary<Node> = this.nodes.reduce(-      (map, node) => Object.assign(map, { [node.name]: node }),-      {} as Dictionary<Node>-    )-    this.edges.forEach(edge => {-      const { source, target, style, pattern } = edge-      const sourceNode = nodeMap[source.name]-      const targetNode = nodeMap[target.name]-      if (sourceNode === undefined) {-        throw new Error(-          `Can not find Edge source node: ${(sourceNode as Node).name}.`-        )-      }-      if (targetNode === undefined) {-        throw new Error(-          `Can not find Edge source node: ${(targetNode as Node).name}.`-        )-      }-      sourceNode.links.push({-        source: sourceNode,-        target: targetNode,-        outDir: source.direction,-        inDir: target.direction,-        pattern,-        style-      })-    })+    this.init()     this._svg.html('') // clear svg content for rerender-    this._pathGroup = this._svg.append('g')-    Object.values(nodeMap).forEach((d: Node) => {-      const g = this._svg.append('g').attr('class', 'paro-node')-      const { width, height } = d-      const [cx, cy] = d.center-      const { borderColor, backgroundColor, fontColor } = d.style-      // render rect-      g.append('rect')-        .attr('class', 'paro-node-rect')-        .attr('x', cx - width / 2)-        .attr('y', cy - height / 2)-        .attr('width', width)-        .attr('height', height)-        .attr('stroke', borderColor)-        .attr('fill', backgroundColor)-        .attr('stroke-width', '2')-        .attr('rx', '4')-        .attr('ry', '4')-      // render text-      const t = g-        .append('text')-        .attr('text-anchor', 'middle')-        .attr('font-size', this.options.fontSize)-        .attr('fill', fontColor)-      let textPosYOffset = 0-      const textLines = d.text.length-      if (textLines === 1) {-        textPosYOffset = 0-      } else if (textLines % 2 !== 0) {-        textPosYOffset = ((1 - textLines) / 2) * this.options.lineHeight-      } else {-        textPosYOffset = (0.5 - textLines / 2) * this.options.lineHeight-      }-      const STATIC_OFFSET = 5 // I don't know why-      d.text.forEach((str: string, i: number) => {-        const y =-          d.center[1] +-          textPosYOffset +-          i * this.options.lineHeight +-          STATIC_OFFSET-        t.append('tspan')-          .attr('x', d.center[0])-          .attr('y', y)-          .text(str)-      })-      // render link line-      const groupedLinks: GroupedLinks = d.links.reduce(-        (res: GroupedLinks, link: Link) => {-          if (res[link.outDir]) {-            res[link.outDir].push(link)-          } else {-            res[link.outDir] = [link]-          }-          return res-        },-        {} as GroupedLinks-      )-      Object.values(groupedLinks).forEach((links: Link[]) =>-        links.forEach(link => this.drawLinkLine(link))-      )+    this.nodes.forEach((d: Node, ind) => {+      const nodeAndLinksSVG = this._svg.append('g').attr('class', 'paro-box' + ind).attr('boxId', ind)+      d.drawNode(nodeAndLinksSVG, ind)+      d.drawLinks()     })   }++  public drag() {++    //间隔差值 防止拖动原点发生变化+    let xd: number+    let yd: number+    //文字差值+    let xt: number+    let yt: number+    const _nodes = this.nodes++    const currentSvg = this._svg++    const dragEvent: any = drag()+      .on("drag", function (d: any) {+        const id = select(this).attr('rectId')+        //拖动过程中补充差值+        select(this)+          .attr("x", event.x - xd)+          .attr("y", event.y - yd)+        currentSvg.selectAll('.paro-node-tspan' + id)+          .attr("x", event.x - xt)+          .attr("y", event.y - yt)++        //重绘此id下的line(需要先改变Node的xy等属性)+        _nodes.forEach((d: Node) => {+          if (d.nodeId.toString() == id) {+            d.changeXY([event.x - xd, event.y - yd])++            d.drawLinks()+            d.drawTargetLinks()+          }+        })+++      })+      .on("start", function (d: any) {+        // 设置rect的间隔差值+        xd = event.x - parseFloat(select(this).attr('x'))+        yd = event.y - parseFloat(select(this).attr('y'))+        // 设置tspan的间隔差值+        const id = select(this).attr('rectId')+        xt = event.x - parseFloat(currentSvg.selectAll('.paro-node-tspan' + id).attr('x'))+        yt = event.y - parseFloat(currentSvg.selectAll('.paro-node-tspan' + id).attr('y'))

此处似乎应该用 select 而不是 selectAll?

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 interface FlowChartNodeOptions {   minWidth?: number   minHeight?: number   extendLength?: number+  borderRadius?: number } interface FlowChartEdgeOptions {   direction?: string   color?: string   width?: number   pattern?: LinkPattern }-interface Node {++class Node {   name: string-  center: [number, number]+  nodeId: number+  center: [number, number] = [0, 0]   width: number   height: number-  text: string[]+  text: string[] = ['']   extendLength: number-  style: Dictionary-  links: Link[]-}-interface EdgeOption {-  name: string-  direction: EdgeDirection-}-interface Edge {-  source: EdgeOption-  target: EdgeOption-  style: Dictionary-  pattern?: LinkPattern+  coordinateXY: Dictionary<Coordinate> = {}+  style: Dictionary = {}+  links: Link[] = []+  targetLinks: Link[] = []+  svgEl: any+  constructor(nodeArg: any) {+    this.name = nodeArg.name+    this.nodeId = nodeArg.nodeId+    this.center = nodeArg.center+    this.width = nodeArg.width || 0+    this.height = nodeArg.height || 0+    this.text = nodeArg.text+    this.extendLength = nodeArg.extendLength || 0+    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)+    this.style = nodeArg.style+    this.svgEl = nodeArg.svgEl+  }++  private getBoundPoint(node: Node, dir: EdgeDirection, extend: boolean) {+    const {+      center: [x, y],+      width,+      height,+      extendLength+    } = node+    let dx = 0,+      dy = 0+    const finalExtendLength = extend+      ? extendLength || this.extendLength+      : 0+    if (dir === 'top') {+      dy = -0.5 * height - finalExtendLength+    } else if (dir === 'right') {+      dx = 0.5 * width + finalExtendLength+    } else if (dir === 'bottom') {+      dy = 0.5 * height + finalExtendLength+    } else {+      dx = -0.5 * width - finalExtendLength+    }+    return [x + dx, y + dy] as Coordinate+  }++  public drawNode(_svg: any, boxId: number) {+    this.nodeId = boxId+    this.svgEl = _svg+    const g = _svg.append('g').attr('class', 'paro-node' + boxId).attr('nodeId', boxId)+    const { width, height } = this+    const [cx, cy] = this.center+    const { borderColor, backgroundColor, fontColor, borderRadius, lineHeight, fontSize } = this.style+    // render rect+    g.append('rect')+      .attr('rectId', boxId)+      .attr('class', 'paro-node-rect')+      .attr('x', cx - width / 2)+      .attr('y', cy - height / 2)+      .attr('width', width)+      .attr('height', height)+      .attr('stroke', borderColor)+      .attr('fill', backgroundColor)+      .attr('stroke-width', '2')+      .attr('rx', borderRadius)+      .attr('ry', borderRadius)+    // render text+    const t = g+      .append('text')+      .attr('textId', boxId)+      .attr('class', 'paro-node-text' + boxId)+      .attr('text-anchor', 'middle')+      .attr('font-size', fontSize)+      .attr('fill', fontColor)+    let textPosYOffset = 0+    const textLines = this.text.length+    if (textLines === 1) {+      textPosYOffset = 0+    } else if (textLines % 2 !== 0) {+      textPosYOffset = ((1 - textLines) / 2) * lineHeight+    } else {+      textPosYOffset = (0.5 - textLines / 2) * lineHeight+    }+    const STATIC_OFFSET = 5 // I don't know why+    this.text.forEach((str: string, i: number) => {+      const y =+        this.center[1] ++        textPosYOffset ++        i * lineHeight ++        STATIC_OFFSET+      t.append('tspan')+        .attr('class', 'paro-node-tspan' + boxId)+        .attr('x', this.center[0])+        .attr('y', y)+        .text(str)+    })+  }++  public drawLinks() {+    this.links.forEach((link: Link) => {+      link.drawLinkLine(this.nodeId, this.svgEl)+    })+  }++  public drawTargetLinks() {+    this.targetLinks.forEach((link: Link) => {+      link.drawLinkLine()+    })+  }++  public changeXY(resetXY: Coordinate) {+    const [x1, y1] = resetXY+    this.center = [x1 + (this.width / 2), y1 + (this.height / 2)]++    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)++    this.links.forEach((link: Link) => {+      link.changeLink();+    })+    this.targetLinks.forEach((link: Link) => {+      link.changeLink();+    })+  } } interface Dictionary<T = any> {   [index: string]: T }+class DirectionPoint {+  posTrunXY: string+  negTrunXY: string+  point: Coordinate = [0, 0]+  otherPoint: Coordinate = [0, 0]+  direction?: PointDirection+  constructor(option: any) {+    this.posTrunXY = option.posTrunXY+    this.negTrunXY = option.negTrunXY+    this.point = option.point+    this.otherPoint = option.otherPoint+    this.direction = option.direction+  }+}+class Link {+  p: any+  pathEl: any+  sourceNode: Node+  targetNode: Node+  sourceXY: [number, number] = [0, 0]+  sourceOriginXY: [number, number] = [0, 0]+  targetXY: [number, number] = [0, 0]+  targetOriginXY: [number, number] = [0, 0]+  centerPoint: [number, number] = [0, 0]+  //InflectionPoint must in rect+  InflectionPoint?: Coordinate+  outDir: EdgeDirection = 'right'+  inDir: EdgeDirection = 'left'+  svgEl: any+  lineId?: number+  style: Dictionary = {}++  private static nodeMap: Dictionary<Node>++  constructor(linkArg: any) {+    this.sourceNode = linkArg.sourceNode+    this.targetNode = linkArg.targetNode+    this.sourceXY = linkArg.sourceXY+    this.sourceOriginXY = linkArg.sourceOriginXY+    this.targetXY = linkArg.targetXY+    this.targetOriginXY = linkArg.targetOriginXY+    this.centerPoint = this.getCentrePoint(this.sourceXY, this.targetXY)+    this.InflectionPoint = linkArg.InflectionPoint+    this.outDir = linkArg.outDir+    this.inDir = linkArg.inDir+    this.style = linkArg.style+  }++  static setNodeMap(nodeMap: Dictionary<Node>) {+    this.nodeMap = nodeMap+  }++  // Is the line formed by two points parallel to the coordinate axis+  private isParallelAxis(a: Coordinate, b: Coordinate) {+    const [x1, y1] = a+    const [x2, y2] = b+    if (x1 == x2 || y1 == y2) {+      return true+    } else {+      return false+    }+  }++  private isSamePoint(p1: Coordinate, p2: Coordinate): boolean {+    return p1.toString() == p2.toString()+  }++  private getCentrePoint(a: Coordinate, b: Coordinate): Coordinate {+    const [x1, y1] = a+    const [x2, y2] = b+    return [(x1 + x2) / 2, (y1 + y2) / 2]+  }++  private getDirectionPoint(mainPoint: Coordinate, point: Coordinate, edgeDirection: EdgeDirection): DirectionPoint {+    const [x1, y1] = mainPoint+    const [x2, y2] = point++    let pointDirection: PointDirection = 'positive'+    let pointXY: Coordinate = [0, 0]+    let otherPointXY: Coordinate = [0, 0]++    let posTrunXY = ''+    let negTrunXY = ''++    switch (edgeDirection) {+      case 'top':+        if (y1 - y2 > 0) {+          pointDirection = 'positive'+          posTrunXY = 'y'+        } else {+          pointDirection = 'negative'+          negTrunXY = 'x'+        }+        pointXY = [x1, y2]+        otherPointXY = [x2, y1]+        break+      case 'bottom':+        if (y1 - y2 > 0) {+          pointDirection = 'negative'+          negTrunXY = 'x'+        } else {+          pointDirection = 'positive'+          posTrunXY = 'y'+        }+        pointXY = [x1, y2]+        otherPointXY = [x2, y1]+        break+      case 'left':+        if (x1 - x2 > 0) {+          pointDirection = 'positive'+          posTrunXY = 'x'+        } else {+          pointDirection = 'negative'+          negTrunXY = 'y'+        }+        pointXY = [x2, y1]+        otherPointXY = [x1, y2]+        break+      case 'right':+        if (x1 - x2 > 0) {+          pointDirection = 'negative'+          negTrunXY = 'y'+        } else {+          pointDirection = 'positive'+          posTrunXY = 'x'+        }+        pointXY = [x2, y1]+        otherPointXY = [x1, y2]+        break+    }+    return new DirectionPoint({+      posTrunXY,+      negTrunXY,+      point: pointXY,+      otherPoint: otherPointXY,+      direction: pointDirection+    })+  }++  private drawNeatLine(sourceDirPoint: DirectionPoint, targetDirPoint: DirectionPoint) {+    const [x1, y1] = this.sourceXY+    const [x2, y2] = this.targetXY+    let neatPoint = []+    if (sourceDirPoint.direction == 'positive') {+      neatPoint = sourceDirPoint.point+    } else if (targetDirPoint.direction == 'positive') {+      neatPoint = targetDirPoint.point+    } else {+      neatPoint = sourceDirPoint.otherPoint+    }++    const [xn, yn] = neatPoint++    this.p.moveTo(x1, y1)+    this.p.lineTo(xn, yn)+    this.p.lineTo(x2, y2)+  }++  private drawTurnLine(sourceDirPoint: DirectionPoint, targetDirPoint: DirectionPoint, turnPoint: Coordinate) {+    const [xt, yt] = turnPoint+    const [x1, y1] = this.sourceXY+    const [x2, y2] = this.targetXY+    let startMoveXY = ''++    if (sourceDirPoint.direction == 'negative' && sourceDirPoint.direction == targetDirPoint.direction) {+      startMoveXY = sourceDirPoint.negTrunXY+    } else {+      if (sourceDirPoint.direction == 'positive') {+        startMoveXY = sourceDirPoint.posTrunXY+      } else if (targetDirPoint.direction == 'positive') {+        startMoveXY = targetDirPoint.posTrunXY+      }+    }+    if (!startMoveXY) {+      throw new Error("not startMoveXY")+    }+    this.p.moveTo(x1, y1)+    switch (startMoveXY) {+      case 'x':+        this.p.lineTo(xt, y1)+        this.p.lineTo(xt, y2)+        break+      case 'y':+        this.p.lineTo(x1, yt)+        this.p.lineTo(x2, yt)+        break+    }++    this.p.lineTo(x2, y2)+  }++  public drawLinkLine(nodeId: any = undefined, _svg: any = undefined) {+    this.p = path()+    if (!this.svgEl) {+      this.svgEl = _svg+    }+    if (!this.lineId) {+      this.lineId = nodeId+    }+    if (this.pathEl) {+      this.pathEl.remove();+    }+    this.pathEl = this.svgEl.append('path').attr('lineId', this.lineId)++    const { color, width } = this.style+    this.pathEl+      .attr('class', 'paro-edge' + nodeId)+      .attr('stroke', color)+      .attr('fill', 'transparent')+      .attr('stroke-width', width)++    if (this.isParallelAxis(this.sourceXY, this.targetXY)) {+      this.p.moveTo(...this.sourceXY)+      this.p.lineTo(...this.targetXY)+    } else {+      const sourceDirPoint = this.getDirectionPoint(this.sourceXY, this.targetXY, this.outDir)+      const targetDirPoint = this.getDirectionPoint(this.targetXY, this.sourceXY, this.inDir)+      // 一正点一反点----------------------------+      if (sourceDirPoint.direction != targetDirPoint.direction) {

使用严格不等判断 !== 代替普通的不等判断 != 以避免隐式类型转换引起运行时错误

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 interface FlowChartNodeOptions {   minWidth?: number   minHeight?: number   extendLength?: number+  borderRadius?: number } interface FlowChartEdgeOptions {   direction?: string   color?: string   width?: number   pattern?: LinkPattern }-interface Node {++class Node {   name: string-  center: [number, number]+  nodeId: number+  center: [number, number] = [0, 0]   width: number   height: number-  text: string[]+  text: string[] = ['']   extendLength: number-  style: Dictionary-  links: Link[]-}-interface EdgeOption {-  name: string-  direction: EdgeDirection-}-interface Edge {-  source: EdgeOption-  target: EdgeOption-  style: Dictionary-  pattern?: LinkPattern+  coordinateXY: Dictionary<Coordinate> = {}+  style: Dictionary = {}+  links: Link[] = []+  targetLinks: Link[] = []+  svgEl: any+  constructor(nodeArg: any) {+    this.name = nodeArg.name+    this.nodeId = nodeArg.nodeId+    this.center = nodeArg.center+    this.width = nodeArg.width || 0+    this.height = nodeArg.height || 0+    this.text = nodeArg.text+    this.extendLength = nodeArg.extendLength || 0+    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)+    this.style = nodeArg.style+    this.svgEl = nodeArg.svgEl+  }++  private getBoundPoint(node: Node, dir: EdgeDirection, extend: boolean) {+    const {+      center: [x, y],+      width,+      height,+      extendLength+    } = node+    let dx = 0,+      dy = 0+    const finalExtendLength = extend+      ? extendLength || this.extendLength+      : 0+    if (dir === 'top') {+      dy = -0.5 * height - finalExtendLength+    } else if (dir === 'right') {+      dx = 0.5 * width + finalExtendLength+    } else if (dir === 'bottom') {+      dy = 0.5 * height + finalExtendLength+    } else {+      dx = -0.5 * width - finalExtendLength+    }+    return [x + dx, y + dy] as Coordinate+  }++  public drawNode(_svg: any, boxId: number) {+    this.nodeId = boxId+    this.svgEl = _svg+    const g = _svg.append('g').attr('class', 'paro-node' + boxId).attr('nodeId', boxId)+    const { width, height } = this+    const [cx, cy] = this.center+    const { borderColor, backgroundColor, fontColor, borderRadius, lineHeight, fontSize } = this.style+    // render rect+    g.append('rect')+      .attr('rectId', boxId)+      .attr('class', 'paro-node-rect')+      .attr('x', cx - width / 2)+      .attr('y', cy - height / 2)+      .attr('width', width)+      .attr('height', height)+      .attr('stroke', borderColor)+      .attr('fill', backgroundColor)+      .attr('stroke-width', '2')+      .attr('rx', borderRadius)+      .attr('ry', borderRadius)+    // render text+    const t = g+      .append('text')+      .attr('textId', boxId)+      .attr('class', 'paro-node-text' + boxId)+      .attr('text-anchor', 'middle')+      .attr('font-size', fontSize)+      .attr('fill', fontColor)+    let textPosYOffset = 0+    const textLines = this.text.length+    if (textLines === 1) {+      textPosYOffset = 0+    } else if (textLines % 2 !== 0) {+      textPosYOffset = ((1 - textLines) / 2) * lineHeight+    } else {+      textPosYOffset = (0.5 - textLines / 2) * lineHeight+    }+    const STATIC_OFFSET = 5 // I don't know why+    this.text.forEach((str: string, i: number) => {+      const y =+        this.center[1] ++        textPosYOffset ++        i * lineHeight ++        STATIC_OFFSET+      t.append('tspan')+        .attr('class', 'paro-node-tspan' + boxId)+        .attr('x', this.center[0])+        .attr('y', y)+        .text(str)+    })+  }++  public drawLinks() {+    this.links.forEach((link: Link) => {+      link.drawLinkLine(this.nodeId, this.svgEl)+    })+  }++  public drawTargetLinks() {+    this.targetLinks.forEach((link: Link) => {+      link.drawLinkLine()+    })+  }++  public changeXY(resetXY: Coordinate) {+    const [x1, y1] = resetXY+    this.center = [x1 + (this.width / 2), y1 + (this.height / 2)]++    this.coordinateXY.top = this.getBoundPoint(this, 'top', false)+    this.coordinateXY.left = this.getBoundPoint(this, 'left', false)+    this.coordinateXY.bottom = this.getBoundPoint(this, 'bottom', false)+    this.coordinateXY.right = this.getBoundPoint(this, 'right', false)+    this.coordinateXY.extop = this.getBoundPoint(this, 'top', true)+    this.coordinateXY.exleft = this.getBoundPoint(this, 'left', true)+    this.coordinateXY.exbottom = this.getBoundPoint(this, 'bottom', true)+    this.coordinateXY.exright = this.getBoundPoint(this, 'right', true)++    this.links.forEach((link: Link) => {+      link.changeLink();+    })+    this.targetLinks.forEach((link: Link) => {+      link.changeLink();+    })+  } } interface Dictionary<T = any> {   [index: string]: T }+class DirectionPoint {+  posTrunXY: string+  negTrunXY: string+  point: Coordinate = [0, 0]+  otherPoint: Coordinate = [0, 0]+  direction?: PointDirection+  constructor(option: any) {+    this.posTrunXY = option.posTrunXY+    this.negTrunXY = option.negTrunXY+    this.point = option.point+    this.otherPoint = option.otherPoint+    this.direction = option.direction+  }+}+class Link {+  p: any+  pathEl: any+  sourceNode: Node+  targetNode: Node+  sourceXY: [number, number] = [0, 0]+  sourceOriginXY: [number, number] = [0, 0]+  targetXY: [number, number] = [0, 0]+  targetOriginXY: [number, number] = [0, 0]+  centerPoint: [number, number] = [0, 0]+  //InflectionPoint must in rect+  InflectionPoint?: Coordinate+  outDir: EdgeDirection = 'right'+  inDir: EdgeDirection = 'left'+  svgEl: any+  lineId?: number+  style: Dictionary = {}++  private static nodeMap: Dictionary<Node>++  constructor(linkArg: any) {+    this.sourceNode = linkArg.sourceNode+    this.targetNode = linkArg.targetNode+    this.sourceXY = linkArg.sourceXY+    this.sourceOriginXY = linkArg.sourceOriginXY+    this.targetXY = linkArg.targetXY+    this.targetOriginXY = linkArg.targetOriginXY+    this.centerPoint = this.getCentrePoint(this.sourceXY, this.targetXY)+    this.InflectionPoint = linkArg.InflectionPoint+    this.outDir = linkArg.outDir+    this.inDir = linkArg.inDir+    this.style = linkArg.style+  }++  static setNodeMap(nodeMap: Dictionary<Node>) {+    this.nodeMap = nodeMap+  }++  // Is the line formed by two points parallel to the coordinate axis+  private isParallelAxis(a: Coordinate, b: Coordinate) {+    const [x1, y1] = a+    const [x2, y2] = b+    if (x1 == x2 || y1 == y2) {+      return true+    } else {+      return false+    }+  }++  private isSamePoint(p1: Coordinate, p2: Coordinate): boolean {+    return p1.toString() == p2.toString()+  }++  private getCentrePoint(a: Coordinate, b: Coordinate): Coordinate {+    const [x1, y1] = a+    const [x2, y2] = b+    return [(x1 + x2) / 2, (y1 + y2) / 2]+  }++  private getDirectionPoint(mainPoint: Coordinate, point: Coordinate, edgeDirection: EdgeDirection): DirectionPoint {+    const [x1, y1] = mainPoint+    const [x2, y2] = point++    let pointDirection: PointDirection = 'positive'+    let pointXY: Coordinate = [0, 0]+    let otherPointXY: Coordinate = [0, 0]++    let posTrunXY = ''+    let negTrunXY = ''++    switch (edgeDirection) {+      case 'top':+        if (y1 - y2 > 0) {+          pointDirection = 'positive'+          posTrunXY = 'y'+        } else {+          pointDirection = 'negative'+          negTrunXY = 'x'+        }+        pointXY = [x1, y2]+        otherPointXY = [x2, y1]+        break+      case 'bottom':+        if (y1 - y2 > 0) {+          pointDirection = 'negative'+          negTrunXY = 'x'+        } else {+          pointDirection = 'positive'+          posTrunXY = 'y'+        }+        pointXY = [x1, y2]+        otherPointXY = [x2, y1]+        break+      case 'left':+        if (x1 - x2 > 0) {+          pointDirection = 'positive'+          posTrunXY = 'x'+        } else {+          pointDirection = 'negative'+          negTrunXY = 'y'+        }+        pointXY = [x2, y1]+        otherPointXY = [x1, y2]+        break+      case 'right':+        if (x1 - x2 > 0) {+          pointDirection = 'negative'+          negTrunXY = 'y'+        } else {+          pointDirection = 'positive'+          posTrunXY = 'x'+        }+        pointXY = [x2, y1]+        otherPointXY = [x1, y2]+        break+    }+    return new DirectionPoint({+      posTrunXY,+      negTrunXY,+      point: pointXY,+      otherPoint: otherPointXY,+      direction: pointDirection+    })+  }++  private drawNeatLine(sourceDirPoint: DirectionPoint, targetDirPoint: DirectionPoint) {+    const [x1, y1] = this.sourceXY+    const [x2, y2] = this.targetXY+    let neatPoint = []+    if (sourceDirPoint.direction == 'positive') {+      neatPoint = sourceDirPoint.point+    } else if (targetDirPoint.direction == 'positive') {+      neatPoint = targetDirPoint.point+    } else {+      neatPoint = sourceDirPoint.otherPoint+    }++    const [xn, yn] = neatPoint++    this.p.moveTo(x1, y1)+    this.p.lineTo(xn, yn)+    this.p.lineTo(x2, y2)+  }++  private drawTurnLine(sourceDirPoint: DirectionPoint, targetDirPoint: DirectionPoint, turnPoint: Coordinate) {+    const [xt, yt] = turnPoint+    const [x1, y1] = this.sourceXY+    const [x2, y2] = this.targetXY+    let startMoveXY = ''++    if (sourceDirPoint.direction == 'negative' && sourceDirPoint.direction == targetDirPoint.direction) {+      startMoveXY = sourceDirPoint.negTrunXY+    } else {+      if (sourceDirPoint.direction == 'positive') {+        startMoveXY = sourceDirPoint.posTrunXY+      } else if (targetDirPoint.direction == 'positive') {+        startMoveXY = targetDirPoint.posTrunXY+      }+    }+    if (!startMoveXY) {+      throw new Error("not startMoveXY")+    }+    this.p.moveTo(x1, y1)+    switch (startMoveXY) {+      case 'x':+        this.p.lineTo(xt, y1)+        this.p.lineTo(xt, y2)+        break+      case 'y':+        this.p.lineTo(x1, yt)+        this.p.lineTo(x2, yt)+        break+    }++    this.p.lineTo(x2, y2)+  }++  public drawLinkLine(nodeId: any = undefined, _svg: any = undefined) {

当参数可以不传时使用可选操作符 ?:, 不要使用 undefined 作为参数的默认值. 例如 public drawLinkLine(nodeId?: SomeType) { ... }

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 interface FlowChartNodeOptions {   minWidth?: number   minHeight?: number   extendLength?: number+  borderRadius?: number } interface FlowChartEdgeOptions {   direction?: string   color?: string   width?: number   pattern?: LinkPattern }-interface Node {++class Node {   name: string-  center: [number, number]+  nodeId: number+  center: [number, number] = [0, 0]   width: number   height: number-  text: string[]+  text: string[] = ['']   extendLength: number-  style: Dictionary-  links: Link[]-}-interface EdgeOption {-  name: string-  direction: EdgeDirection-}-interface Edge {-  source: EdgeOption-  target: EdgeOption-  style: Dictionary-  pattern?: LinkPattern+  coordinateXY: Dictionary<Coordinate> = {}+  style: Dictionary = {}+  links: Link[] = []+  targetLinks: Link[] = []+  svgEl: any+  constructor(nodeArg: any) {

尽可能不要使用 any 类型, 尤其在类的构造函数中.

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

 class FlowChart {       console.error(         `[P-Flow warn]: Can't find source node: ${source}.\n\nPlease check if add node correctly before or add it before call render().`       )+      return this     }     if (!targetExist) {       console.error(         `[P-Flow warn]: Can't find target node: ${target}.\n\nPlease check if add node correctly before or add it before call render().`       )+      return this     }     const [outDir, inDir] = direction       ? direction.split('-')       : defaultDir.split('-')-    const from: EdgeOption = {-      name: source,-      direction: outDir as EdgeDirection-    }-    const to = {-      name: target,-      direction: inDir as EdgeDirection-    }-    this.edges.push({-      source: from,-      target: to,-      style: {-        color,-        width-      },-      pattern-    })++    const link = new Link(+      {+        sourceNode: sourceExist,+        targetNode: targetExist,+        outDir: outDir,+        inDir: inDir,+        sourceXY: sourceExist.coordinateXY['ex' + outDir],+        sourceOriginXY: sourceExist.coordinateXY[outDir],+        targetXY: targetExist.coordinateXY['ex' + inDir],+        targetOriginXY: targetExist.coordinateXY[inDir],+        style: {+          color,+          width+        }+      }+    )+    this.links.push(link)+    sourceExist.links.push(link)+    targetExist.targetLinks.push(link)     return this   }+  private init() {+    this.selectAll = selectAll++  }

selectAll挂载到类里似乎没有意义, 并且别处没有调用到 this.selectAll

Mrliuchanghao

comment created time in 5 days

Pull request review commentparrotdance/paroflow

封装节点、连线对象,增加拖拽功能,更改连线规则

-import { path } from 'd3-path'-import { select } from 'd3-selection'+import { event, drag, path, select, selectAll } from 'd3'

d3 内部已经将 API 分离到了不同的包中, 并且有详尽的声明文件. 尽可能从对应的包中引入以减小依赖体积. 如 selectselectAll 都可以从 d3-selection 引入.

Mrliuchanghao

comment created time in 5 days

push eventparrotdance/parrot-blog

ParroT

commit sha da7701d1969390e0c273950b43f223bee81a2814

add export script

view details

push time in 10 days

push eventparrotdance/parrot-blog

ParroT

commit sha 7eb91c3c343c96ce6a1debb2f93752233085f6ee

update

view details

push time in 18 days

push eventparrotdance/parrot-blog

ParroT

commit sha a59dcac9ed8fc4b6f4b8dbf53a9208f3c1dc85bd

update

view details

push time in 18 days

push eventparrot-cend/thinking-parrot

dependabot[bot]

commit sha f457628f5dc559968c37d9c2e7e9212579c08590

Bump lodash from 4.17.15 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] <support@github.com>

view details

Zhe Lin / ParroT

commit sha c09581dddd726ab9deecb06687d2e8ab2c73a897

Merge pull request #1 from parrot-cend/dependabot/npm_and_yarn/lodash-4.17.19 Bump lodash from 4.17.15 to 4.17.19

view details

push time in 23 days

PR merged parrot-cend/thinking-parrot

Bump lodash from 4.17.15 to 4.17.19 dependencies

Bumps lodash from 4.17.15 to 4.17.19. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/lodash/lodash/releases">lodash's releases</a>.</em></p> <blockquote> <h2>4.17.16</h2> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/lodash/lodash/commit/d7fbc52ee0466a6d248f047b5d5c3e6d1e099056"><code>d7fbc52</code></a> Bump to v4.17.19</li> <li><a href="https://github.com/lodash/lodash/commit/2e1c0f22f425e9c013815b2cd7c2ebd51f49a8d6"><code>2e1c0f2</code></a> Add npm-package</li> <li><a href="https://github.com/lodash/lodash/commit/1b6c282299f4e0271f932b466c67f0f822aa308e"><code>1b6c282</code></a> Bump to v4.17.18</li> <li><a href="https://github.com/lodash/lodash/commit/a370ac81408de2da77a82b3c4b61a01a3b9c2fac"><code>a370ac8</code></a> Bump to v4.17.17</li> <li><a href="https://github.com/lodash/lodash/commit/1144918f3578a84fcc4986da9b806e63a6175cbb"><code>1144918</code></a> Rebuild lodash and docs</li> <li><a href="https://github.com/lodash/lodash/commit/3a3b0fd339c2109563f7e8167dc95265ed82ef3e"><code>3a3b0fd</code></a> Bump to v4.17.16</li> <li><a href="https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12"><code>c84fe82</code></a> fix(zipObjectDeep): prototype pollution (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4759">#4759</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/e7b28ea6cb17b4ca021e7c9d66218c8c89782f32"><code>e7b28ea</code></a> Sanitize sourceURL so it cannot affect evaled code (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4518">#4518</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/0cec225778d4ac26c2bac95031ecc92a94f08bbb"><code>0cec225</code></a> Fix lodash.isEqual for circular references (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4320">#4320</a>) (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4515">#4515</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/94c3a8133cb4fcdb50db72b4fd14dd884b195cd5"><code>94c3a81</code></a> Document matches* shorthands for over* methods (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4510">#4510</a>) (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4514">#4514</a>)</li> <li>Additional commits viewable in <a href="https://github.com/lodash/lodash/compare/4.17.15...4.17.19">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~mathias">mathias</a>, a new releaser for lodash since your current version.</p> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+3 -3

0 comment

1 changed file

dependabot[bot]

pr closed time in 23 days

push eventparrot-cend/speaking-parrot

dependabot[bot]

commit sha 3582570c23f636b60303cc28bcb88c5675583efb

Bump lodash from 4.17.15 to 4.17.19 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] <support@github.com>

view details

Zhe Lin / ParroT

commit sha 605b3bd5ac95447c3b602d8f45525c2fa2dddef2

Merge pull request #2 from parrot-cend/dependabot/npm_and_yarn/lodash-4.17.19 Bump lodash from 4.17.15 to 4.17.19

view details

push time in 23 days

PR merged parrot-cend/speaking-parrot

Bump lodash from 4.17.15 to 4.17.19 dependencies

Bumps lodash from 4.17.15 to 4.17.19. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/lodash/lodash/releases">lodash's releases</a>.</em></p> <blockquote> <h2>4.17.16</h2> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/lodash/lodash/commit/d7fbc52ee0466a6d248f047b5d5c3e6d1e099056"><code>d7fbc52</code></a> Bump to v4.17.19</li> <li><a href="https://github.com/lodash/lodash/commit/2e1c0f22f425e9c013815b2cd7c2ebd51f49a8d6"><code>2e1c0f2</code></a> Add npm-package</li> <li><a href="https://github.com/lodash/lodash/commit/1b6c282299f4e0271f932b466c67f0f822aa308e"><code>1b6c282</code></a> Bump to v4.17.18</li> <li><a href="https://github.com/lodash/lodash/commit/a370ac81408de2da77a82b3c4b61a01a3b9c2fac"><code>a370ac8</code></a> Bump to v4.17.17</li> <li><a href="https://github.com/lodash/lodash/commit/1144918f3578a84fcc4986da9b806e63a6175cbb"><code>1144918</code></a> Rebuild lodash and docs</li> <li><a href="https://github.com/lodash/lodash/commit/3a3b0fd339c2109563f7e8167dc95265ed82ef3e"><code>3a3b0fd</code></a> Bump to v4.17.16</li> <li><a href="https://github.com/lodash/lodash/commit/c84fe82760fb2d3e03a63379b297a1cc1a2fce12"><code>c84fe82</code></a> fix(zipObjectDeep): prototype pollution (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4759">#4759</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/e7b28ea6cb17b4ca021e7c9d66218c8c89782f32"><code>e7b28ea</code></a> Sanitize sourceURL so it cannot affect evaled code (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4518">#4518</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/0cec225778d4ac26c2bac95031ecc92a94f08bbb"><code>0cec225</code></a> Fix lodash.isEqual for circular references (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4320">#4320</a>) (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4515">#4515</a>)</li> <li><a href="https://github.com/lodash/lodash/commit/94c3a8133cb4fcdb50db72b4fd14dd884b195cd5"><code>94c3a81</code></a> Document matches* shorthands for over* methods (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4510">#4510</a>) (<a href="https://github-redirect.dependabot.com/lodash/lodash/issues/4514">#4514</a>)</li> <li>Additional commits viewable in <a href="https://github.com/lodash/lodash/compare/4.17.15...4.17.19">compare view</a></li> </ul> </details> <details> <summary>Maintainer changes</summary> <p>This version was pushed to npm by <a href="https://www.npmjs.com/~mathias">mathias</a>, a new releaser for lodash since your current version.</p> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
  • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
  • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
  • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the Security Alerts page.

</details>

+3 -3

0 comment

1 changed file

dependabot[bot]

pr closed time in 23 days

pull request commentdocschina/rollupjs.org

docs(cn): translate guide/zh/06-faqs.md

哈,抱歉,确实是我误解了。 已根据修改意见更新了译文,还请抽空 review 一下。

parrotdance

comment created time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha 6e5dc7f59443e36f0d65194ed3b6e254577400f3

delete unnecessary line

view details

push time in a month

pull request commentdocschina/rollupjs.org

docs(cn): translate guide/zh/06-faqs.md

每一段落请注意中英文行数保持一致哈

我觉得在一些情况下实在是难以取舍,中文相比于英文通常都更加简洁,强行保持行数一致会让译文变得臃肿,对阅读过程并没有帮助。 例如对第 7 行的翻译:

  • ES modules are an official standard and the clear path forward for JavaScript code structure, whereas CommonJS modules are an idiosyncratic legacy format that served as a stopgap solution before ES modules had been proposed. ES modules allow static analysis that helps with optimizations like tree-shaking and scope-hoisting, and provide advanced features like circular references and live bindings.
  • ES 模块是一个官方标准,也是 JavaScript 代码结构的明确的发展方向,而 CommonJS 模块是一种特殊且老旧的格式,仅仅在提出 ES 模块标准之前作为暂时性的解决方案。ES 模块允许进行静态分析,从而有助于摇树(tree-shaking)和作用域提升(scope-hoisting)之类的优化工作,同时提供了一些高级特性,例如循环引用和实时绑定。

我觉得已经很难再往里面塞别的文字了...能否举个例子?

parrotdance

comment created time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha fd28a64b351f61f5664c26d810fd2c7b03cfbc92

docs(cn): translate guide/zh/06-faqs.md

view details

push time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha 31bbfd41ac516f2f71a5ad514792a7fcd74d5622

docs(cn): translate guide/zh/06-faqs.md

view details

push time in a month

pull request commentdocschina/rollupjs.org

docs(cn): translate guide/zh/06-faqs.md

@QC-L 翻译已基本完成,劳烦抽空review 🍻

parrotdance

comment created time in a month

issue commentdocschina/rollupjs.org

术语表

我先来一个: live binding

QC-L

comment created time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha 7c5fb90cabd063957932f5298d77f952c7b84c19

docs(cn): translate guide/zh/06-faqs.md

view details

push time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha a7aeab55f357183eddd5d499369b319bc2eda8d0

docs(cn): translate guide/zh/06-faqs.md

view details

push time in a month

PR opened docschina/rollupjs.org

docs(cn): translate guide/zh/06-faqs.md

翻译常见问题章节

+42 -38

0 comment

1 changed file

pr created time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha d52efce5bea4235a0e637b233a2472766373c79e

docs(cn): translate guide/zh/06-faqs.md

view details

push time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha 23a2497ec44caf95f0345316b2a0bd39ee7cc3a9

docs(cn): translate guide/zh/06-faqs.md

view details

push time in a month

create barnchparrotdance/rollupjs.org

branch : translate/faq

created branch time in a month

push eventparrotdance/rollupjs.org

ParroT

commit sha edf409a0a18f222257f08872939e0203d9114df6

translate faq

view details

push time in a month

issue commentdocschina/rollupjs.org

翻译任务认领

Section Title 译者 完成时间
Guide Frequently Asked Questions @parrotdance 2020.06.29 - 2020.06.30
lcxfs1991

comment created time in a month

push eventparrotdance/paroflow

ParroT

commit sha 39c19a01e69016f4bd0cc7a9ff6e3dbd74f173cf

update README

view details

ParroT

commit sha 631fb557d07001552f9fb41b3a078f0aafbf4d90

0.2.1

view details

push time in 2 months

push eventparrotdance/paroflow

ParroT

commit sha 5da8df2fec06718b7f6ee3fbb9e616f24064b568

put path element to a consistant g tag

view details

push time in 2 months

push eventparrotdance/parrot-blog

ParroT

commit sha efba2d9b6be8200911f8436401dbb598b920d5d3

update

view details

push time in 2 months

push eventparrotdance/parrot-blog

ParroT

commit sha 632f891ae6db267f535a09333c80a7c3407f8c22

update

view details

push time in 2 months

push eventparrotdance/parrot-blog

ParroT

commit sha 7ad633722823bc52adf963135edfa1cf2f83ebd7

update

view details

push time in 2 months

push eventparrotdance/parrot-blog

ParroT

commit sha b8c6ac013b61752f5c1c6a9cd25f3a557029d29a

update

view details

push time in 2 months

push eventparrotdance/parrot-blog

ParroT

commit sha 65714f6e671d2871e4498e5f081686623ceb4b42

update

view details

push time in 2 months

push eventparrotdance/paroflow

Zhe Lin / ParroT

commit sha 5c48f0ea6b7c4a1fa62d5ea046d07ce6f4a82514

Create LICENSE

view details

ParroT

commit sha ce2ee1d6e4b909373a391fc09a3b6399af1eb050

0.2.0

view details

push time in 2 months

push eventparrotdance/paroflow

Zhe Lin / ParroT

commit sha eea9c20f891771e2227baae4e1b4cafb3a915717

Create LICENSE

view details

push time in 2 months

startedparrotdance/paroflow

started time in 2 months

push eventparrotdance/paroflow

ParroT

commit sha e6775fb953e8484a3adc43767f34f52747cc9f40

update keywords and README

view details

ParroT

commit sha 8b6900c87f3bef86b3904244c7233c6fafe91486

0.1.4

view details

push time in 2 months

push eventparrotdance/paroflow

ParroT

commit sha 8bb77ace729bae1b0d00a7e10e6ca58c918adca9

0.1.2

view details

ParroT

commit sha d283caf56c22187d5ad5cb4649d8b076eb6005b7

update README

view details

ParroT

commit sha f5f80c09cf3b48f38adac68d1e9eafa22e275e00

0.1.3

view details

push time in 2 months

push eventparrotdance/paroflow

ParroT

commit sha 026c25acdbf0be5b7947fac1ebea5010dfc396fa

rename project by "paroflow"

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha dce8a849429c46804dc18f0acfafb2c6df8dd2ed

update package.json

view details

push time in 2 months

created tagparrotdance/p-flow

tagv0.1.1

P-flow is a simple flow-chart builder which works with D3.js

created time in 2 months

created tagparrotdance/p-flow

tagv0.1.0

P-flow is a simple flow-chart builder which works with D3.js

created time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 03bd31d1686d1fb047739d4e680a528d9fa703e0

update package.json

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 3aa6b8b7b0264de32be940025be34bcc7f9c040f

update package.json

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha a28eca5241c5edb74697b040accf2dd014bb0e5e

update README

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 23c87f20b04f040f8ad7168f9ef0587c736484f4

now when add a edge which link nodes not exist will throw an error.

view details

ParroT

commit sha e50ca3715a34ad747380740e613ac355b7a8babc

add many configuration options to adjust node and edge. the option in node or edge has a higher priority than global option.

view details

ParroT

commit sha 672eb907d3e696eb1066869a24b828aa2e8edc80

update README

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha b6b8c687347ca00c2025c93ac3789c2f9aad7079

rename core file

view details

ParroT

commit sha ed3b78aa1e08c6ebfb24635e07e28c913dd48fa5

add dist file

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 6f0192daa8f98181d73eb6690296a083735485b3

update

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 2ac2fd160e50566177fc7417c348c6aaa7c2602f

update README

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 704d8c28d471f8f78d0d7dde39fd927da06c40bc

update demo

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 60dfcef17b119e3991d36019118d47c92a34c8ac

fix build script to run correctly in windows(?)

view details

ParroT

commit sha 8f6eea0833c7025d4343a8a29821994202baff45

reorganize file structure and add demo in README

view details

push time in 2 months

push eventparrotdance/p-flow

ParroT

commit sha 87ebddb81892b8635b2a2d8006c22124141581c8

add vscode setting file

view details

push time in 2 months

PublicEvent

created repositoryparrotdance/puckee

Web framework for learn HTTP(S) protocol and Rust, then make it simple and fast.

created time in 2 months

startedyewstack/yew

started time in 2 months

push eventparrotdance/parrot-blog

ParroT

commit sha c12646c79da5382e0c0f258ecdf7e031d602e2b7

update readme

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha c87dc70d8238bb4fb44c6f65166dd3e1cf8b85f4

update manifest

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 64eb671aa27d25fb21930119e4265b490b926bd2

add #2

view details

push time in 3 months

startedyisar/joke

started time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 3669560029df40066164b3f6cdf9a72b5fed0af1

update article names

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 4b8f9e166ba473a698c809f02c98cdc062e4fe42

update article names

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 89213ec92e26e86bf883c1fe897a4eb821b14381

update article names

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 8ad8888b2033c76bc1ee8d63ca737f89e0f8288f

update

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha bc2a18e19987ab41c79c51e315a3e08bde8054f2

update

view details

push time in 3 months

startedzhmushan/abc

started time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha a86a9228aee65a2d9265b0e223add6d9302c724c

init commit

view details

ParroT

commit sha 0efd32762268fb0ee26ca80bd6e5abcaae79ad32

update

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 4a435ad9522492152563c681fafa6bc31284de15

init commit

view details

ParroT

commit sha bb1145b9b5fee7d401adb55941d23fa1990afc8e

update

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha 0efd32762268fb0ee26ca80bd6e5abcaae79ad32

update

view details

push time in 3 months

startedvitejs/vite-plugin-react

started time in 3 months

startedmessense/jieba-rs

started time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha a86a9228aee65a2d9265b0e223add6d9302c724c

init commit

view details

push time in 3 months

push eventparrotdance/parrot-blog

ParroT

commit sha d4f8ef59f467e9428a616ad37fe215654771e1bf

init commit

view details

push time in 3 months

create barnchparrotdance/parrot-blog

branch : master

created branch time in 3 months

created repositoryparrotdance/parrot-blog

The place where ParroT retell what it thought and what it said.

created time in 3 months

startedvuejs/vite

started time in 3 months

more