diff --git a/.gitignore b/.gitignore
index 202330f..8d3aca1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ node_modules/
.vscode
yarn-error.log
dst/
-dist/
\ No newline at end of file
+dist/
+module/
\ No newline at end of file
diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js
new file mode 100644
index 0000000..d8e2052
--- /dev/null
+++ b/config/webpack.config.dev.js
@@ -0,0 +1,25 @@
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const path = require('path');
+
+module.exports = {
+ entry: path.resolve(__dirname, '../src/index.ts'),
+ devtool: 'inline-source-map',
+ module: {
+ rules: [
+ {
+ test: /\.tsx?$/,
+ use: 'ts-loader',
+ exclude: /node_modules/,
+ },
+ ],
+ },
+ resolve: {
+ extensions: [ '.ts', '.tsx', '.js' ],
+ },
+ output: {
+ filename: 'facetTree.js',
+ path: path.resolve(__dirname, '../module'),
+ libraryTarget: "umd",
+ library: 'facetTree',
+ }
+};
\ No newline at end of file
diff --git a/src/data.ts b/data.ts
similarity index 100%
rename from src/data.ts
rename to data.ts
diff --git a/index.ts b/index.ts
new file mode 100644
index 0000000..3099a89
--- /dev/null
+++ b/index.ts
@@ -0,0 +1,69 @@
+import axios from 'axios';
+
+import {drawTree} from './module/facetTree';
+import { data } from './data';
+
+const svg = document.getElementById('mysvg');
+
+async function clickFacet(facetId: number) {
+
+ try {
+ const res = await axios.get('http://yotta.xjtushilei.com:8083/facet/getFacetNameAndParentFacetNameByFacetId', {
+ params: {
+ facetId,
+ }
+ });
+ if ((res as any).data.code === 200) {
+ document.getElementById('facet').innerHTML = (res.data.data.parentFacetName ? res.data.data.parentFacetName + ' - ' : '') + res.data.data.facetName;
+ } else {
+ throw(res.data)
+ }
+ } catch (e) {
+ console.log(e);
+ document.getElementById('facet').innerHTML = '';
+ }
+
+ // empty list
+ const list = document.getElementById('list');
+ const children = list.childNodes;
+ for (let i = 0; i < children.length; i++) {
+ list.removeChild(children[i]);
+ }
+
+ const ul = document.createElement('ul');
+ let assembleNumber = 0;
+
+ try {
+ const res = await axios.get('http://yotta.xjtushilei.com:8083/assemble/getAssemblesByFacetId', {
+ params: {
+ facetId: facetId,
+ },
+ });
+
+ if ((res as any).data.code === 200) {
+ const assembleList = res.data.data;
+ (assembleList as any).forEach(element => {
+ const li = document.createElement('li');
+ li.className = 'assemble';
+ if (element.type === 'video') {
+ const regex = new RegExp('https://.*mp4');
+ li.innerHTML = ``
+ } else {
+ li.innerHTML = element.assembleContent;
+ }
+ ul.appendChild(li);
+ });
+ assembleNumber = assembleList.length;
+ list.appendChild(ul);
+ document.getElementById('assembleNumber').innerHTML = assembleNumber.toString();
+ } else {
+ throw ('api error');
+ }
+ } catch (e) {
+ console.log(e);
+ document.getElementById('assembleNumber').innerHTML = '';
+ }
+
+}
+
+drawTree(svg, data, clickFacet);
\ No newline at end of file
diff --git a/package.json b/package.json
index 1516404..05407f5 100755
--- a/package.json
+++ b/package.json
@@ -34,7 +34,8 @@
"test": "jest",
"build": "rm -rf ./dst && tsc",
"webpack": "webpack",
- "dev": "rm -rf dist && npm run webpack -- --mode development",
- "prod": "rm -rf dist && npm run webpack -- --mode production"
+ "dev": "rm -rf dist module && npm run webpack -- --mode development --config ./config/webpack.config.dev.js && npm run webpack -- --mode development",
+ "prod": "rm -rf dist module && npm run webpack -- --mode production --config ./config/webpack.config.dev.js && npm run webpack -- --mode production",
+ "pack": "rm -rf module && npm run webpack -- --mode production --config ./config/webpack.config.dev.js"
}
}
diff --git a/src/draw-tree.ts b/src/draw-tree.ts
index 5a8c58c..1995829 100644
--- a/src/draw-tree.ts
+++ b/src/draw-tree.ts
@@ -1,5 +1,5 @@
import * as d3 from 'd3';
-import { map, distinctUntilChanged, debounce, filter } from 'rxjs/operators';
+import { map, distinctUntilChanged, debounce, filter, skip } from 'rxjs/operators';
import { interval } from 'rxjs';
import { buildTree } from './facet-tree-ng';
@@ -7,12 +7,13 @@ import { drawFacetPieChart } from './facet-pie-chart';
import { drawFacetForceLayout } from './facet-force-layout';
import { globalState } from './state';
-function drawTree(svg, data, clickFacet): void {
+export function drawTree(svg, data, clickFacet): void {
const canvas = d3.select(svg);
const treeData = buildTree(data, svg);
globalState.pipe(
- debounce(() => interval(1000)),
+ debounce(() => interval(200)),
+ skip(1),
map(state => state.currentFacetId),
distinctUntilChanged()
).subscribe(currentFacetId => {
@@ -20,10 +21,12 @@ function drawTree(svg, data, clickFacet): void {
});
globalState.pipe(
- debounce(() => interval(1000)),
+ debounce(() => interval(200)),
+ skip(1),
map(state => state.expandedFacetId),
filter(expandedFacetId => {
const [prev, curr] = expandedFacetId.split(',');
+ console.log(expandedFacetId);
return prev !== curr;
}),
distinctUntilChanged()
@@ -36,7 +39,7 @@ function drawTree(svg, data, clickFacet): void {
expandedNodes[0].parentNode.removeChild(expandedNodes[0]);
}
// draw pie chart
- drawFacetPieChart(treeData.facetChart.filter(x => x.facetId.toString() === prev)[0], svg, treeData, clickFacet);
+ drawFacetPieChart(treeData.facetChart.filter(x => x.facetId.toString() === prev)[0], svg);
}
if (curr !== '-2') {
// delete pie chart
@@ -45,7 +48,7 @@ function drawTree(svg, data, clickFacet): void {
expandedNodes[0].parentNode.removeChild(expandedNodes[0]);
}
// draw force layout
- drawFacetForceLayout(treeData.facetChart.filter(x => x.facetId.toString() === curr)[0], svg, clickFacet);
+ drawFacetForceLayout(treeData.facetChart.filter(x => x.facetId.toString() === curr)[0], svg);
}
});
@@ -86,11 +89,19 @@ function drawTree(svg, data, clickFacet): void {
})
.attr('fill', d => d.color)
.style('cursor', 'pointer')
- .on('click', (d, i) => clickFacet(treeData.branches[i].facetId, treeData.branches[i].facetName));
+ .on('click', (d, i) => {
+ const [prev, curr] = globalState.getValue().expandedFacetId.split(',');
+ globalState.next(
+ {
+ currentFacetId: treeData.branches[i].facetId,
+ expandedFacetId: curr + ',-2',
+ }
+ )
+ });
// draw second layer facet
treeData.facetChart.forEach(element => {
// 饼图
- drawFacetPieChart(element, svg, treeData, clickFacet);
+ drawFacetPieChart(element, svg);
// 力导向图
// drawFacetForceLayout(element, svg);
});
diff --git a/src/facet-force-layout.ts b/src/facet-force-layout.ts
index 2de265a..168a5fc 100644
--- a/src/facet-force-layout.ts
+++ b/src/facet-force-layout.ts
@@ -1,6 +1,8 @@
-import { FacetChartData } from './facet-tree-ng';
import * as d3 from 'd3';
+import { FacetChartData } from './facet-tree-ng';
+import { globalState } from './state';
+
function calcFacetForceLayout(data: FacetChartData): {nodes: any[]; links: any[]} {
const nodes = [];
const links = [];
@@ -39,7 +41,7 @@ function fixna(x: number): number {
return 0;
}
-export function drawFacetForceLayout(data: FacetChartData, dom: HTMLElement, clickFacet: Function, fontSize = 12): void {
+export function drawFacetForceLayout(data: FacetChartData, dom: HTMLElement, fontSize = 12): void {
const container = d3.select(dom).append('g');
const { nodes, links } = calcFacetForceLayout(data);
@@ -59,7 +61,13 @@ export function drawFacetForceLayout(data: FacetChartData, dom: HTMLElement, cli
.attr('r', data.r / 2)
.attr('fill', data.color)
.style('cursor', 'pointer')
- .on('click', d => clickFacet(d.facetId, data.facetName + '-' + d.facetName, data.facetId));
+ .on('click', d => {
+ const [prev, next] = globalState.getValue().expandedFacetId.split(',');
+ globalState.next({
+ currentFacetId: d.facetId,
+ expandedFacetId: next + ',' + data.facetId.toString(),
+ });
+ });
const label = container.append('g')
.selectAll('text')
diff --git a/src/facet-pie-chart.ts b/src/facet-pie-chart.ts
index 4e0090b..066d8da 100644
--- a/src/facet-pie-chart.ts
+++ b/src/facet-pie-chart.ts
@@ -1,7 +1,9 @@
-import { FacetChartData, FacetData, Tree } from './facet-tree-ng';
import * as d3 from 'd3';
-export function drawFacetPieChart(data: FacetChartData, dom: HTMLElement, treeData: Tree, clickFacet: Function, fontSize = 12): void {
+import { FacetChartData, FacetData, Tree } from './facet-tree-ng';
+import { globalState } from './state';
+
+export function drawFacetPieChart(data: FacetChartData, dom: HTMLElement, fontSize = 12): void {
const canvas = d3.select(dom);
canvas.append('g')
.attr('class', data.facetId)
@@ -18,10 +20,11 @@ export function drawFacetPieChart(data: FacetChartData, dom: HTMLElement, treeDa
.attr("stroke-width", data.r / 10)
.style('cursor', 'pointer')
.on('click', d => {
- let facetName = ' - ' + (d.data as any).facetName;
- const firstFacetId = (d.data as any).parentFacetId;
- facetName = ' ' + treeData.branches.filter(branch => branch.facetId === firstFacetId)[0].facetName + facetName;
- clickFacet((d.data as any).facetId, facetName, data.facetId);
+ const [prev, curr] = globalState.getValue().expandedFacetId.split(',');
+ globalState.next({
+ currentFacetId: (d.data as any).facetId,
+ expandedFacetId: curr + ',' + data.facetId.toString(),
+ });
});
const num = data.childrenNumber;
const angle = Math.PI / num;
diff --git a/src/index.ts b/src/index.ts
index cef755c..32ac71e 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,64 +1,4 @@
-import * as d3 from 'd3';
-import axios from 'axios';
-
-
-import { buildTree, FacetData } from './facet-tree-ng';
-import { data } from './data';
-import { drawFacetPieChart } from './facet-pie-chart';
-import { drawFacetForceLayout } from './facet-force-layout';
-
-const svg = document.getElementById('mysvg');
-
-let currentFacetId = -1;
-
-async function clickFacet(facetId: number, facetName: string, parentFacetId = -2) {
- // return when facetId not change
- if (currentFacetId === facetId) return;
-
- // save facetId
- currentFacetId = facetId;
-
- // empty list
- const list = document.getElementById('list');
- const children = list.childNodes;
- for (let i = 0; i < children.length; i++) {
- list.removeChild(children[i]);
- }
-
- const ul = document.createElement('ul');
- let assembleNumber = 0;
-
- try {
- const res = await axios.get('http://yotta.xjtushilei.com:8083/assemble/getAssemblesByFacetId', {
- params: {
- facetId: facetId,
- },
- });
-
- if ((res as any).data.code === 200) {
- const assembleList = res.data.data;
- (assembleList as any).forEach(element => {
- const li = document.createElement('li');
- li.className = 'assemble';
- if (element.type === 'video') {
- const regex = new RegExp('https://.*mp4');
- li.innerHTML = ``
- } else {
- li.innerHTML = element.assembleContent;
- }
- ul.appendChild(li);
- });
- assembleNumber = assembleList.length;
- } else {
- throw ('api error');
- }
- } catch (e) {
- console.log(e);
- }
- // whether current facet has changed or not
- if (currentFacetId === facetId) {
- list.appendChild(ul);
- document.getElementById('facet').innerHTML = facetName;
- document.getElementById('assembleNumber').innerHTML = assembleNumber.toString();
- }
-}
\ No newline at end of file
+export * from './draw-tree';
+export * from './facet-tree-ng';
+export * from './facet-force-layout';
+export * from './facet-pie-chart';
diff --git a/tsconfig.json b/tsconfig.json
index 7cd71bd..0d2d557 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,7 +5,6 @@
"target": "es5",
"types": ["lodash", "d3", "jest"],
"sourceMap": true,
- "rootDir": "src",
"outDir": "dst",
"lib": [
"es5",
@@ -15,7 +14,7 @@
]
},
"include": [
- "src/*"
+ "src/*", "data.ts"
],
"exclude": [
"node_modules"
diff --git a/webpack.config.js b/webpack.config.js
index a64b9a1..bed6461 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,7 +2,7 @@
const path = require('path');
module.exports = {
- entry: path.resolve(__dirname, './src/index.ts'),
+ entry: path.resolve(__dirname, 'index.ts'),
devtool: 'inline-source-map',
module: {
rules: [