finish charts
This commit is contained in:
parent
c632837767
commit
7d54a42da9
|
@ -6,15 +6,22 @@ import (
|
|||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/474420502/focus/tree/heap"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var tagCounter = make(map[string]*tagcounter)
|
||||
|
||||
type taginfo struct {
|
||||
Name string
|
||||
Value int
|
||||
}
|
||||
|
||||
type tagcounter struct {
|
||||
Name string
|
||||
LastTime time.Time
|
||||
CountWord map[string]int
|
||||
CountWord map[string]*taginfo
|
||||
PQueue []interface{}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -26,7 +33,7 @@ func CountTag(cxt *gin.Context) {
|
|||
var cw *tagcounter
|
||||
if cw, ok := tagCounter[platform]; ok {
|
||||
if time.Now().Sub(cw.LastTime).Minutes() <= 10 {
|
||||
cxt.JSON(200, cw.CountWord)
|
||||
cxt.JSON(200, cw.PQueue)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +46,7 @@ func CountTag(cxt *gin.Context) {
|
|||
}
|
||||
|
||||
cw = &tagcounter{}
|
||||
cw.CountWord = make(map[string]int)
|
||||
cw.CountWord = make(map[string]*taginfo)
|
||||
cw.Name = platform
|
||||
cw.LastTime = time.Now()
|
||||
tagCounter[platform] = cw
|
||||
|
@ -54,12 +61,40 @@ func CountTag(cxt *gin.Context) {
|
|||
json.Unmarshal([]byte(stag), &tag)
|
||||
for _, t := range tag {
|
||||
if _, ok := cw.CountWord[t]; ok {
|
||||
cw.CountWord[t]++
|
||||
cw.CountWord[t].Value++
|
||||
} else {
|
||||
cw.CountWord[t] = 1
|
||||
cw.CountWord[t] = &taginfo{Name: t, Value: 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
cxt.JSON(200, cw.CountWord)
|
||||
|
||||
heap := heap.New(func(a, b interface{}) int {
|
||||
if a.(*taginfo).Value >= b.(*taginfo).Value {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
|
||||
})
|
||||
|
||||
var other = &taginfo{Name: "Other...", Value: 0}
|
||||
var i = 0
|
||||
for _, v := range cw.CountWord {
|
||||
if i <= 99 {
|
||||
heap.Put(v)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
// heap.Put(other)
|
||||
cw.PQueue = heap.Values()
|
||||
other.Value = cw.PQueue[len(cw.PQueue)-1].(*taginfo).Value - 1
|
||||
if other.Value == 0 {
|
||||
other.Value = 1
|
||||
}
|
||||
|
||||
cw.PQueue = append(cw.PQueue, other)
|
||||
cxt.JSON(200, cw.PQueue)
|
||||
cw.LastTime = time.Now()
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ module initmate_server
|
|||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/474420502/focus v0.12.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/jinzhu/gorm v1.9.16 // indirect
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
github.com/474420502/focus v0.12.0 h1:+icbmj7IEOefvTegHt5EpcHt6WFbe2miIrceUJx2Evo=
|
||||
github.com/474420502/focus v0.12.0/go.mod h1:d0PMjtMxFz1a9HIhwyFPkWa+JF+0LgOrEUfd8iZka6s=
|
||||
github.com/Pallinder/go-randomdata v1.1.0/go.mod h1:yHmJgulpD2Nfrm0cR9tI/+oAgRqCQQixsA8HyRZfV9Y=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
72
src/App.js
72
src/App.js
|
@ -2,22 +2,25 @@ import Icon, {
|
|||
MenuFoldOutlined, MenuUnfoldOutlined,
|
||||
DatabaseOutlined, DatabaseFilled
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Layout, Menu } from 'antd';
|
||||
import { Row, Col, Divider } from 'antd';
|
||||
import { Button, Layout, Menu, Tabs } from 'antd';
|
||||
import 'antd/dist/antd.css';
|
||||
import React from 'react';
|
||||
import ReactDom from 'react-dom';
|
||||
import './App.less';
|
||||
import DataTable from './Table';
|
||||
import ContentTable from './ContentTable';
|
||||
import DataTableTest from './TableTest';
|
||||
import CountCharts from './Graph';
|
||||
|
||||
import ChartsCount from './ChartsCount';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
const bstyle = { width: "100px" };
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
platform: "openrec",
|
||||
collapsed: false,
|
||||
tkey: "content_table",
|
||||
};
|
||||
|
||||
toggleCollapsed = () => {
|
||||
|
@ -26,6 +29,14 @@ class App extends React.Component {
|
|||
});
|
||||
};
|
||||
|
||||
changePlatform = (p) => {
|
||||
this.setState({platform: p});
|
||||
if (this.refs.tcharts && this.refs.tcharts.state.platform !== p) {
|
||||
this.refs.tcharts.changePlatform(p)
|
||||
}
|
||||
this.refs.ctable.changePlatform(p);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Layout>
|
||||
|
@ -36,33 +47,64 @@ class App extends React.Component {
|
|||
inlineCollapsed={this.state.collapsed}
|
||||
>
|
||||
<Button type="primary" onClick={this.toggleCollapsed} style={{ background: '#6739b6', width: "100%", colorRendering: "optimizeSpeed" }}>
|
||||
|
||||
{React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined)}
|
||||
</Button>
|
||||
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}
|
||||
defaultOpenKeys={['sub1']}
|
||||
>
|
||||
<Menu.Item key="openrec" icon={<DatabaseFilled/>} onClick={(e)=>{ this.refs.ctable.changePlatform( e.key) ; }} >
|
||||
<Menu.Item key="openrec" icon={<DatabaseFilled/>} onClick={(e)=>{ this.changePlatform(e.key); }} >
|
||||
openrec
|
||||
</Menu.Item>
|
||||
<Menu.Item key="twitcasting" icon={<DatabaseFilled/>} onClick={(e)=>{ this.refs.ctable.changePlatform( e.key) ; }} >
|
||||
<Menu.Item key="twitcasting" icon={<DatabaseFilled/>} onClick={(e)=>{ this.changePlatform(e.key); ; }} >
|
||||
twitcasting
|
||||
</Menu.Item>
|
||||
<Menu.Item key="twitch" icon={<DatabaseFilled/>} onClick={(e)=>{ this.refs.ctable.changePlatform( e.key) ; }} >
|
||||
<Menu.Item key="twitch" icon={<DatabaseFilled/>} onClick={(e)=>{ this.changePlatform(e.key); }} >
|
||||
twitch
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Header style={{ background: '#000', padding:"0" }}>
|
||||
|
||||
<span style={{color:'#fff', paddingLeft: "40%", fontSize:'1.2em'}}>
|
||||
标题
|
||||
</span>
|
||||
|
||||
<Divider orientation="left" style={{height: "100%"}} >
|
||||
<Row justify="center" gutter={{lg: 128 }}>
|
||||
{/* <Col span={4}><Button type="primary" style={bstyle} onClick={(e)=>{}}> tag统计 </Button> </Col> */}
|
||||
</Row>
|
||||
</Divider>
|
||||
|
||||
</Header>
|
||||
<Content style={{ margin: '0 8px' }}>
|
||||
{/* <ContentTable ref="ctable" platform={"openrec"}></ContentTable> */}
|
||||
<CountCharts></CountCharts>
|
||||
<Content ref="content" style={{ margin: '0 8px' }}>
|
||||
<Tabs
|
||||
onChange={(e)=>{
|
||||
const { platform } = this.state;
|
||||
this.setState({key: e})
|
||||
|
||||
switch (e) {
|
||||
case "content_table":
|
||||
if (this.refs.ctable) {
|
||||
this.refs.ctable.changePlatform(platform);
|
||||
}
|
||||
break;
|
||||
case "tag_count":
|
||||
if( this.refs.tcharts ) {
|
||||
this.refs.tcharts.changePlatform(platform);
|
||||
}
|
||||
break
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}} >
|
||||
|
||||
<TabPane tab="数据表格" key="content_table">
|
||||
<ContentTable ref="ctable" platform={this.state.platform}></ContentTable>
|
||||
</TabPane>
|
||||
<TabPane tab="tag统计" key="tag_count">
|
||||
<ChartsCount platform={this.state.platform} ref="tcharts"> </ChartsCount>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
|
||||
|
||||
</Content>
|
||||
<Footer style={{ textAlign: 'center' }}>
|
||||
Intimate ©2020 Created by eson
|
||||
|
|
143
src/ChartsCount.js
Normal file
143
src/ChartsCount.js
Normal file
|
@ -0,0 +1,143 @@
|
|||
|
||||
|
||||
import React from 'react';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
|
||||
function parseData(cw={}) {
|
||||
var legendData = [];
|
||||
var seriesData = [];
|
||||
var selected = {};
|
||||
|
||||
for(var i =0; i < cw.length ; i++){
|
||||
// legendData.push(name);
|
||||
var taginfo = cw[i];
|
||||
seriesData.push({
|
||||
name: taginfo.Name,
|
||||
value: taginfo.Value
|
||||
})
|
||||
selected[taginfo.Name] = false;
|
||||
}
|
||||
|
||||
|
||||
seriesData.sort((a, b) => {
|
||||
return b.value - a.value
|
||||
})
|
||||
|
||||
for(var i = 0; i < seriesData.length ; i ++) {
|
||||
var o = seriesData[i];
|
||||
legendData.push(o.name);
|
||||
selected[o.name] = i <= 20;
|
||||
}
|
||||
|
||||
return { legendData: legendData, seriesData: seriesData, selected:selected }
|
||||
}
|
||||
|
||||
function getOption(state={}) {
|
||||
const { platform, data } = state;
|
||||
const option = {
|
||||
title: {
|
||||
text: `${platform}同名数量统计`,
|
||||
subtext: '数据最新仅供参考',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
data: data.legendData,
|
||||
selected: data.selected
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '标签',
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['40%', '50%'],
|
||||
data: data.seriesData,
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
};
|
||||
return option;
|
||||
}
|
||||
|
||||
class ChartsCount extends React.Component {
|
||||
|
||||
state = {
|
||||
option: {},
|
||||
platform: this.props.platform,
|
||||
data: {}
|
||||
}
|
||||
|
||||
changePlatform = (p) => {
|
||||
this.setState({platform: p}, ()=>{
|
||||
this.updateData();
|
||||
} );
|
||||
};
|
||||
|
||||
|
||||
|
||||
updateData = () => {
|
||||
|
||||
const { platform } = this.state;
|
||||
fetch(`http://192.168.16.130:5500/tag/count?platform=${platform}`, {
|
||||
"mode": "cors"
|
||||
}).then(
|
||||
response => {
|
||||
response.json().then( value => {
|
||||
|
||||
this.setState({
|
||||
data: parseData(value)
|
||||
}, ()=> {
|
||||
|
||||
var ins = this.echarts_react.getEchartsInstance();
|
||||
ins.setOption( getOption(this.state) );
|
||||
|
||||
});
|
||||
|
||||
} );
|
||||
}
|
||||
)
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.updateData();
|
||||
}
|
||||
|
||||
render() {
|
||||
return ( <div style={{ padding: 24, background: '#fff', minHeight: 780 }} >
|
||||
<ReactEcharts
|
||||
notMerge={true}
|
||||
ref={(e) => { this.echarts_react = e; }}
|
||||
option={ getOption(this.state)}
|
||||
style={{height: '600px', width: '100%'}}
|
||||
className='react_for_echarts' />
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ChartsCount;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import DataTable from './Table.js';
|
||||
|
||||
class ContentTable extends React.Component {
|
||||
changePlatform(p) {
|
||||
|
||||
changePlatform = (p) => {
|
||||
// this.refs.table.firstPage();
|
||||
// this.setState({platform: p});
|
||||
// this.refs.table.setState({platform: p})
|
||||
|
|
151
src/Graph.js
151
src/Graph.js
|
@ -1,151 +0,0 @@
|
|||
|
||||
|
||||
import React from 'react';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import reqwest from 'reqwest';
|
||||
|
||||
// function genData(count) {
|
||||
// var nameList = [
|
||||
// '赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁', '杜', '阮', '蓝', '闵', '席', '季', '麻', '强', '贾', '路', '娄', '危'
|
||||
// ];
|
||||
// var legendData = [];
|
||||
// var seriesData = [];
|
||||
// var selected = {};
|
||||
// for (var i = 0; i < count; i++) {
|
||||
// var name = Math.random() > 0.65
|
||||
// ? makeWord(4, 1) + '·' + makeWord(3, 0)
|
||||
// : makeWord(2, 1);
|
||||
// legendData.push(name);
|
||||
// seriesData.push({
|
||||
// name: name,
|
||||
// value: Math.round(Math.random() * 100000)
|
||||
// });
|
||||
// selected[name] = i < 6;
|
||||
// }
|
||||
|
||||
// return {
|
||||
// legendData: legendData,
|
||||
// seriesData: seriesData,
|
||||
// selected: selected
|
||||
// };
|
||||
|
||||
// function makeWord(max, min) {
|
||||
// var nameLen = Math.ceil(Math.random() * max + min);
|
||||
// var name = [];
|
||||
// for (var i = 0; i < nameLen; i++) {
|
||||
// name.push(nameList[Math.round(Math.random() * nameList.length - 1)]);
|
||||
// }
|
||||
// return name.join('');
|
||||
// }
|
||||
// }
|
||||
|
||||
function parseData(cw={}) {
|
||||
var legendData = [];
|
||||
var seriesData = [];
|
||||
var selected = {};
|
||||
|
||||
for(var name in cw){
|
||||
legendData.push(name);
|
||||
seriesData.push({
|
||||
name: name,
|
||||
value: cw[name]
|
||||
})
|
||||
selected[name] = false
|
||||
}
|
||||
return { legendData: legendData, seriesData: seriesData, selected:selected }
|
||||
}
|
||||
|
||||
const getRandomuserParams = params => {
|
||||
return {
|
||||
platform: params.platform,
|
||||
// ...params,
|
||||
};
|
||||
};
|
||||
|
||||
class CountCharts extends React.Component {
|
||||
|
||||
state = {
|
||||
platform: "twitch",
|
||||
data: {}
|
||||
}
|
||||
|
||||
fetch = (params = {}) => {
|
||||
|
||||
// console.log(platform);
|
||||
reqwest({
|
||||
url: 'http://localhost:5500/tag/count',
|
||||
method: 'get',
|
||||
type: 'json',
|
||||
data: getRandomuserParams(params),
|
||||
}).then(data => {
|
||||
var result = JSON.parse(data);
|
||||
console.log("result", result);
|
||||
this.setState({
|
||||
data: parseData(result),
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.fetch(this.state);
|
||||
}
|
||||
|
||||
render() {
|
||||
// this.fetch(this.state);
|
||||
const {data} = this.state;
|
||||
const option = {
|
||||
title: {
|
||||
text: '同名数量统计',
|
||||
subtext: '纯属虚构',
|
||||
left: 'center'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
},
|
||||
legend: {
|
||||
type: 'scroll',
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
data: data.legendData,
|
||||
selected: data.selected
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '标签',
|
||||
type: 'pie',
|
||||
radius: '55%',
|
||||
center: ['40%', '50%'],
|
||||
data: data.seriesData,
|
||||
emphasis: {
|
||||
itemStyle: {
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 0,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
};
|
||||
return ( <div style={{ padding: 24, background: '#fff', minHeight: 780 }} >
|
||||
<ReactEcharts
|
||||
option={option}
|
||||
style={{height: '350px', width: '1000px'}}
|
||||
className='react_for_echarts' />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default CountCharts;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -167,9 +167,9 @@ class DataTable extends React.Component {
|
|||
fetch = (params = {}) => {
|
||||
this.setState({ loading: true });
|
||||
const {platform} = this.state;
|
||||
console.log(platform);
|
||||
|
||||
reqwest({
|
||||
url: 'http://localhost:5500/' + platform + '/query',
|
||||
url: 'http://192.168.16.130:5500/' + platform + '/query',
|
||||
method: 'get',
|
||||
type: 'json',
|
||||
data: getRandomuserParams(params),
|
||||
|
|
Loading…
Reference in New Issue
Block a user