Skip to content

Commit

Permalink
feat: add more charts
Browse files Browse the repository at this point in the history
1. 岗位分类分布 饼图
2. 公司分布 TreeMap
3. 经验要求分析 半饼图
4. 薪资分析 金字塔图
  • Loading branch information
Selflocking committed Jan 22, 2024
1 parent fa51963 commit 018f04f
Show file tree
Hide file tree
Showing 11 changed files with 543 additions and 80 deletions.
37 changes: 28 additions & 9 deletions src/backend/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ def get_count_by_list(session: Session, pattern: list[str]) -> dict[str, int]:

def get_city_analysis(session: Session) -> dict[str, int]:
data = dao.group_count(session, "city")
data = sorted(data.items(), lambda x: x[1], reverse=True)
return dict(data[:20])
data = sorted(data.items(), key=lambda x: x[1], reverse=True)
return dict(data[:10])


def get_education_analysis(session: Session) -> dict[str, int]:
data = dao.group_count(session, "education")
data = sorted(data.items(), lambda x: x[1], reverse=True)
return data
data = sorted(data.items(), key=lambda x: x[1], reverse=True)
return dict(data)


def get_position_analysis(session: Session) -> dict[str, int]:
Expand Down Expand Up @@ -121,28 +121,47 @@ def get_language_analysis(session: Session) -> dict[str, int]:
return get_count_by_list(session, language)


def get_salary_analysis(session: Session):
def get_salary_analysis(session: Session) -> dict[str, int]:
salary_data = dao.group_count(session, "salary")
histogram = dict()
histogram: dict[int, int] = dict()
for k, v in salary_data.items():
index = int(k.replace("k", "").split("-")[0])
if index not in histogram.keys():
histogram[index] = v
else:
histogram[index] += v
return {str(k) + "k": v for k, v in histogram.items()}

result: dict[str, int] = dict()
for k, v in histogram.items():
if k < 2:
result["0-2k"] = result.get("0-2k", 0) + v
elif k < 5:
result["2-5k"] = result.get("2-5k", 0) + v
elif k < 10:
result["5-10k"] = result.get("5-10k", 0) + v
elif k < 15:
result["10-15k"] = result.get("10-15k", 0) + v
elif k < 20:
result["15-20k"] = result.get("15-20k", 0) + v
elif k < 30:
result["20-30k"] = result.get("20-30k", 0) + v
elif k < 50:
result["30-50k"] = result.get("30-50k", 0) + v
else:
result["50k以上"] = result.get("50k以上", 0) + v
return result


def get_company_analysis(session: Session):
data = dao.group_count(session, "company_name")
data = sorted(data.items(), key=lambda it: it[1], reverse=True)
return dict(data[:10])
return dict(data[:30])


def get_category_analysis(session: Session):
data = dao.group_count(session, "category")
data = sorted(data.items(), key=lambda it: it[1], reverse=True)
return dict(data[:10])
return dict(data)


def get_experience_analysis(session: Session):
Expand Down
28 changes: 28 additions & 0 deletions web/src/backend/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,39 @@ const getLanguagesAnalyze = () => {
});
};

const getSalaryAnalyze = () => {
return axios.get(serverUrl + "/api/analyze/salary").then((response) => {
return response.data;
});
};

const getExperienceAnalyze = () => {
return axios.get(serverUrl + "/api/analyze/experience").then((response) => {
return response.data;
});
};

const getCompanyAnalyze = () => {
return axios.get(serverUrl + "/api/analyze/company_name").then((response) => {
return response.data;
});
};

const getCategoryAnalyze = () => {
return axios.get(serverUrl + "/api/analyze/category").then((response) => {
return response.data;
});
};

export {
getJobs,
getCitiesAnalyze,
getEducationAnalyze,
getPositionbAnalyze,
getLanguagesAnalyze,
searchJobs,
getSalaryAnalyze,
getExperienceAnalyze,
getCompanyAnalyze,
getCategoryAnalyze,
};
57 changes: 57 additions & 0 deletions web/src/components/Charts/BasicPieChart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as echarts from "echarts/core";
import { PieChart } from "echarts/charts";
import { LabelLayout } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";
import EChartsReactCore from "echarts-for-react/lib/core";
import PropTypes from "prop-types";

echarts.use([PieChart, CanvasRenderer, LabelLayout]);

const optionSample = {
series: [
{
type: "pie",
radius: "25%",
center: ["50%", "50%"],
data: [],
label: {
position: "outer",
alignTo: "edge",
// edgeDistance: "25%",
},
left: 0,
right: 0,
top: 0,
bottom: 0,
},
],
};

export default function BasicPieChart({ items, data, onChartReady, ...props }) {
if (data.length === 0) {
return <div className="h-64"></div>;
}

console.log(items);
let option = optionSample;
const chartdata = [];
for (let i = 0; i < items.length; i++) {
chartdata.push({ value: data[i], name: items[i] });
}
option.series[0].data = chartdata;

return (
<EChartsReactCore
echarts={echarts}
option={option}
onChartReady={onChartReady}
{...props}
/>
);
}

BasicPieChart.propTypes = {
items: PropTypes.array.isRequired,
data: PropTypes.array.isRequired,
onChartReady: PropTypes.func.isRequired,
};
2 changes: 1 addition & 1 deletion web/src/components/Charts/DoughnutChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function DoughnutChart({ items, data, onChartReady, ...props }) {
chartdata.push({ value: data[i], name: items[i] });
}
option.series[0].data = chartdata;
console.log(chartdata);
// console.log(chartdata);
return (
<EChartsReactCore
echarts={echarts}
Expand Down
100 changes: 100 additions & 0 deletions web/src/components/Charts/HalfPieChart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import * as echarts from "echarts/core";
import { LegendComponent } from "echarts/components";
import { PieChart } from "echarts/charts";
import { LabelLayout } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";
import EChartsReactCore from "echarts-for-react/lib/core";
import PropTypes from "prop-types";

echarts.use([LegendComponent, PieChart, CanvasRenderer, LabelLayout]);

const optionSample = {
legend: {
top: "5%",
left: "center",
// doesn't perfectly work with our tricks, disable it
selectedMode: false,
},
series: [
{
name: "Access From",
type: "pie",
radius: ["40%", "70%"],
center: ["50%", "70%"],
// adjust the start angle
startAngle: 180,
label: {
show: true,
formatter(param) {
// correct the percentage
return param.name + " (" + param.percent * 2 + "%)";
},
},
data: [
{ value: 1048, name: "Search Engine" },
{ value: 735, name: "Direct" },
{ value: 580, name: "Email" },
{ value: 484, name: "Union Ads" },
{ value: 300, name: "Video Ads" },
{
// make an record to fill the bottom 50%
value: 1048 + 735 + 580 + 484 + 300,
itemStyle: {
// stop the chart from rendering this piece
color: "none",
decal: {
symbol: "none",
},
},
label: {
show: false,
},
},
],
},
],
};

export default function HalfPieChart({ items, data, onChartReady, ...props }) {
if (data.length === 0) {
return <div className="h-64"></div>;
}

let option = optionSample;
const chartdata = [];
let sum = 0;
for (let i = 0; i < items.length; i++) {
chartdata.push({ value: data[i], name: items[i] });
sum += data[i];
}
chartdata.push({
// make an record to fill the bottom 50%
value: sum,
itemStyle: {
// stop the chart from rendering this piece
color: "none",
decal: {
symbol: "none",
},
},
label: {
show: false,
},
});
option.series[0].data = chartdata;

return (
<EChartsReactCore
echarts={echarts}
option={option}
onChartReady={onChartReady}
{...props}
/>
);
}

HalfPieChart.propTypes = {
items: PropTypes.array.isRequired,
data: PropTypes.array.isRequired,
onChartReady: PropTypes.func.isRequired,
};
19 changes: 13 additions & 6 deletions web/src/components/Charts/NightingaleChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,20 @@ let optionSample = {
// subtext: "Fake Data",
// left: "center",
// },
toolbox: {
// toolbox: {
// show: true,
// feature: {
// mark: { show: true },
// // dataView: { show: true, readOnly: false },
// // restore: { show: true },
// // saveAsImage: { show: true },
// },
// },
label: {
show: true,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true },
formatter(param) {
// correct the percentage
return param.name + " (" + param.percent * 2 + "%)";
},
},
series: [
Expand Down
Loading

0 comments on commit 018f04f

Please sign in to comment.