finish charts

This commit is contained in:
eson 2020-08-21 19:36:05 +08:00
parent c632837767
commit 7d54a42da9
8 changed files with 249 additions and 175 deletions

View File

@ -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()
}

View File

@ -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

View File

@ -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=

View File

@ -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
View 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;

View File

@ -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})

View File

@ -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;

View File

@ -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),