Auto Commit

上级 f01f2064
{
"name": "vuejs-with-vite",
"author": "yma16",
"version": "0.0.0",
"scripts": {
"dev": "vite",
......
<template>
<div id="barChartId" style="width:100vw;height:900px;margin: 0 auto"></div>
</template>
<script setup>
import * as echarts from 'echarts';
import { defineProps, reactive, watch, nextTick, onUnmounted } from 'vue';
const props = defineProps({
tableData: []
})
const state = reactive({
exportLoading: false,
dataSource: [],
echartInstance: undefined
})
watch(() => props.tableData,
(val) => {
state.dataSource = val
nextTick(() => {
renderEchartBar()
})
}, {
deep: true,
immediate: true
})
function renderEchartBar() {
// 基于准备好的dom,初始化echarts实例
const domInstance=document.getElementById('barChartId')
if(domInstance){
domInstance.removeAttribute('_echarts_instance_')
}
else{
return
}
const myChart = echarts.init(domInstance);
const option = {
title: {
text: 'csdn 质量分柱状图 点击跳转到对应的文章'
},
toolbox: {
show: true,
feature: {
saveAsImage: {}
}
},
dataZoom: [
{
id: 'dataZoomX',
type: 'slider',
xAxisIndex: [0],
filterMode: 'filter'
}
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {},
xAxis: {
type: 'category',
data: state.dataSource.map(item => item.postTime)
},
yAxis: {
type: 'value'
},
grid: {
x: 60,
x2: 100
},
tooltip: {
formatter: function (params) {
let findItem = state.dataSource.find(item => {
return item.postTime == params.name
})
if (!findItem) {
return ''
}
return `<span style='color:blue'>-<span> 博客标题:${findItem.title} <br>
<span style='color:green'>-<span> 博客质量:${params.value} <br>
<span style='color:red'>-<span> 博客建议:${findItem.message}<br>
<span style='color:blue'>-<span> 博客地址:${findItem.url}<br>
<span style='color:blue'>-<span> 发文时间:${params.name}<br>
`
},
},
series: [
{
data: state.dataSource.map(item => item.score),
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(180, 180, 180, 0.2)'
},
label: { //柱体上显示数值
show: true,//开启显示
position: 'center',//在上方显示
textStyle: {//数值样式
fontSize: '2px',
color: 'blue'
}
},
markPoint: {
data: [
{ type: 'max', name: '最高分' },
{ type: 'min', name: '最低分' }
]
},
markLine: {
itemStyle: {
normal: {
lineStyle:
{
type: 'dotted',
},
label:
{
show: true,
position: 'middle',
color: 'red',
lineHeight: 35,
backgroundColor: 'rgba(255,255,255.7)',
formatter: (params) => {
return params.name + ":" + params.value
}
}
}
},
data: [
{
type: 'average',
name: '平均分'
}]
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option, true);
// 监听
state.echartInstance = myChart;
myChart.on('click', function (params) {
const findItem = state.dataSource.find(item => {
return item.postTime == params.name
})
if (params.name) {
window.open(findItem.url, '_blank')
}
});
window.onresize = myChart.resize;
}
onUnmounted(() => {
window.onresize = null
})
</script>
\ No newline at end of file
<template>
<div>
<a-button type="primary" style="margin: 10px 0;" :loading="state.exportLoading" @click="onExport">
导出 </a-button>
</div>
</template>
<script setup>
import { defineProps, reactive, watch } from 'vue';
import { exportExcelFunc } from './exportExcel';
const props = defineProps({
tableData: []
})
const state = reactive({
exportLoading: false,
dataSource: []
})
const onExport = () => {
console.log('export')
if (!state.dataSource || state.dataSource.length === 0) {
window.alert('表格数据为空')
return
}
state.exportLoading = true
exportExcelFunc(state.dataSource, '用户质量分').then(res => {
state.exportLoading = false
console.log('res', res)
}).catch(r => {
state.exportLoading = false
console.log('r', r)
})
}
watch(() => props.tableData,
(val) => {
state.dataSource = val
}, {
deep: true,
immediate: true
})
</script>
\ No newline at end of file
<script setup>
import * as echarts from 'echarts';
import Author from './Author.vue'
import { tableColumns } from './const'
import { getRemoteCsdnGrade } from '../service/csdnApi'
import Author from './Author.vue';
import ExportBtn from './ExportBtn.vue';
import EchartBar from './EchartBar.vue';
import { tableColumns } from './const';
import { getRemoteCsdnGrade } from '../service/csdnApi';
import { onMounted, reactive, onUnmounted } from 'vue';
import { exportExcel } from './exportExcel'
const state = reactive({
title: 'csdn用户根据id快速查分数改文章',
loading: false,
......@@ -45,8 +46,8 @@ const getCsdnData = (uId) => {
state.dataSource = res.data.data
state.pagination.total = state.dataSource.length
state.loading = false
initFirstData()
window.localStorage.setItem('csdnUidData', JSON.stringify(state.dataSource))
saveStorege(state.dataSource)
}).catch((r) => {
state.pagination.total = 0
console.log(r)
......@@ -56,6 +57,13 @@ const getCsdnData = (uId) => {
})
}
async function saveStorege(val){
return new Promise(resolve=>{
window.localStorage.setItem('csdnUidData', JSON.stringify(val))
resolve(true)
})
}
const onSearch = () => {
if (!state.searchValue) {
return window.alert('请输入csdn用户id 如 qq_38870145')
......@@ -64,173 +72,34 @@ const onSearch = () => {
getCsdnData(state.searchValue)
}
function initFirstData() {
// 基于准备好的dom,初始化echarts实例
const myChart = echarts.init(document.getElementById('first'));
const option = {
title: {
text: 'csdn 质量分柱状图 点击跳转到对应的文章'
},
toolbox: {
show: true,
feature: {
saveAsImage: {}
}
},
dataZoom: [
{
id: 'dataZoomX',
type: 'slider',
xAxisIndex: [0],
filterMode: 'filter'
}
],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {},
xAxis: {
type: 'category',
data: state.dataSource.map(item => item.postTime)
},
yAxis: {
type: 'value'
},
grid: {
x: 60,
x2: 100
},
tooltip: {
formatter: function (params) {
let findItem = state.dataSource.find(item => {
return item.postTime == params.name
})
if (!findItem) {
return ''
}
return `<span style='color:blue'>-<span> 博客标题:${findItem.title} <br>
<span style='color:green'>-<span> 博客质量:${params.value} <br>
<span style='color:red'>-<span> 博客建议:${findItem.message}<br>
<span style='color:blue'>-<span> 博客地址:${findItem.url}<br>
<span style='color:blue'>-<span> 发文时间:${params.name}<br>
`
},
},
series: [
{
data: state.dataSource.map(item => item.score),
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(180, 180, 180, 0.2)'
},
label: { //柱体上显示数值
show: true,//开启显示
position: 'center',//在上方显示
textStyle: {//数值样式
fontSize: '2px',
color: 'blue'
}
},
markPoint: {
data: [
{ type: 'max', name: '最高分' },
{ type: 'min', name: '最低分' }
]
},
markLine: {
itemStyle: {
normal: {
lineStyle:
{
type: 'dotted',
},
label:
{
show: true,
position: 'middle',
color: 'red',
lineHeight: 35,
backgroundColor: 'rgba(255,255,255.7)',
formatter: (params) => {
console.log('params markline', params)
return params.name + ":" + params.value
}
}
}
},
data: [
{
type: 'average',
name: '平均分'
}]
}
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
// 监听
state.firstChart = myChart;
window.onresize = myChart.resize
myChart.on('click', function (params) {
const findItem = state.dataSource.find(item => {
return item.postTime == params.name
})
if (params.name) {
window.open(findItem.url, '_blank')
}
});
const exportTableDataFunc = () => {
if (!state.dataSource || state.dataSource.length === 0) {
return window.alert('表格数据为空')
}
state.exportLoading = true
exportExcel(state.dataSource, '用户质量分').then(res => {
state.exportLoading = false
console.log('res', res)
})
}
onMounted(() => {
const storageUid = localStorage.getItem('csdnUid')
console.log('window.localStorage', localStorage)
console.log('storageUid', storageUid)
if (storageUid) {
state.searchValue = storageUid
onMounted(() => {
const storageUid = localStorage.getItem('csdnUid')
console.log('window.localStorage', localStorage)
console.log('storageUid', storageUid)
if (storageUid) {
state.searchValue = storageUid
onSearch()
}
document.addEventListener('keydown', (e) => {
console.log(e, 'e')
if (e.ctrlKey && e.keyCode === 79) {
console.log('Ctrl+y');
onSearch()
}
document.addEventListener('keydown', (e) => {
console.log(e, 'e')
if (e.ctrlKey && e.keyCode === 79) {
console.log('Ctrl+y');
onSearch()
}
})
// storage
// if (state.dataSource) {
// initFirstData();
// }
})
onUnmounted(() => {
window.onresize = null
if (state.searchValue) {
window.localStorage.setItem('csdnUid', state.searchValue)
}
if (state.dataSource) {
window.localStorage.setItem('csdnUidData', JSON.stringify(state.dataSource))
}
})
}
})
onUnmounted(() => {
if (state.searchValue) {
window.localStorage.setItem('csdnUid', state.searchValue)
}
if (state.dataSource) {
window.localStorage.setItem('csdnUidData', JSON.stringify(state.dataSource))
}
})
</script>
<template>
......@@ -246,9 +115,9 @@ function initFirstData() {
<div style="width:100px;line-height: 32px;">csdn用户id:</div><a-input-search v-model:value="state.searchValue"
:disabled="state.loading" placeholder="输入用户id(如 qq_38870145)" enter-button @search="onSearch" />
</div>
<a-button type="primary" @click="exportTableDataFunc" style="margin: 10px 0;" :loading="state.exportLoading">
导出 </a-button>
<div>
<ExportBtn :table-data="state.dataSource" />
<a-table :scroll="{ x: 800, y: 600 }" :columns="state.columns" :data-source="state.dataSource"
:loading="state.loading" :pagination="state.pagination" bordered style="border-bottom:1px solid #f0f0f0;">
<template #bodyCell="{ column, record }">
......@@ -276,7 +145,7 @@ function initFirstData() {
</div>
<div>
<a-spin :spinning="state.loading">
<div id="first" style="width:100vw;height:900px;margin: 0 auto"></div>
<EchartBar :table-data="state.dataSource" />
</a-spin>
</div>
</div>
......
......@@ -6,7 +6,7 @@ const tableToExcel = async (jsonData) => {
console.log('start', jsonData)
let str = '<tr>'
Object.keys(jsonData[0]).forEach(name => {
const tdStr = `<tr>${name}</td>`
const tdStr = `<td>${name}</td>`
str += tdStr
})
str += '</tr>'
......@@ -44,7 +44,7 @@ const tableToExcel = async (jsonData) => {
};
export async function exportExcel(tableData) {
export const exportExcelFunc = async (tableData) => {
return new Promise(async (resolve) => {
try {
await tableToExcel(tableData)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册