123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- <template>
- <div>
- <div
- v-loading="loading"
- :id="`plotDiv-${inds}`"
- style="width: 100%; height: 450px"
- >
- <el-empty v-if="isError" description="请求失败"></el-empty>
- </div>
- </div>
- </template>
- <script>
- import Plotly from "plotly.js-dist";
- import axios from "axios";
- import { myMixin } from "@/mixins/chartRequestMixin";
- import { colorSchemes } from "@/views/overview/js/colors";
- import { mapState } from "vuex";
- export default {
- props: {
- fileAddr: {
- default: "",
- type: String,
- },
- inds: {
- type: [Number, String],
- default: 1,
- },
- },
- mixins: [myMixin],
- data() {
- return {
- // 数据结构
- chartData: {},
- color1: colorSchemes[0].colors, // 默认颜色
- // 配色方案列表(每个方案是一个颜色数组)
- colorSchemes: [...colorSchemes],
- };
- },
- computed: {
- ...mapState("themes", {
- themeColor: "themeColor",
- }),
- },
- watch: {
- chartData: {
- deep: true,
- handler(v) {
- if (v) {
- this.renderChart();
- }
- },
- },
- themeColor: {
- handler() {
- this.color1 = this.themeColor;
- this.renderChart();
- },
- deep: true,
- },
- },
- mounted() {
- this.$nextTick(() => {
- this.getData();
- // if (this.themeColor.length === 0) {
- this.color1 = this.colorSchemes[0].colors;
- // } else {
- // this.color1 = this.themeColor;
- // }
- });
- },
- methods: {
- async getData() {
- if (this.fileAddr !== "") {
- try {
- this.loading = true;
- this.cancelToken = axios.CancelToken.source();
- const resultChartsData = await axios.get(this.fileAddr, {
- cancelToken: this.cancelToken.token,
- });
- this.chartData = resultChartsData.data;
- this.renderChart();
- this.isError = false;
- this.loading = false;
- } catch (error) {
- this.isError = true;
- this.loading = false;
- }
- }
- },
- renderChart() {
- const { axes, data, analysisTypeCode } = this.chartData;
- // 从数据中提取 windSpeedRange 和动态生成 speedLabels 和 colorscale
- const windSpeedRanges = new Set();
- data.forEach((engine) => {
- engine.windRoseData.forEach((item) => {
- windSpeedRanges.add(item.windSpeedRange);
- });
- });
- const speedLabels = Array.from(windSpeedRanges).sort(); // 动态范围值
- const colors = [...this.color1]; // 可扩展颜色列表
- const colorscale = {};
- speedLabels.forEach((label, index) => {
- colorscale[label] = colors[(index % colors.length) + 4];
- });
- // 定义风向的 16 等分
- const windDirections = Array.from({ length: 16 }, (_, i) => i * 22.5);
- // 数据聚合
- const counts = {};
- speedLabels.forEach((speedLabel) => {
- counts[speedLabel] = Array(windDirections.length).fill(0);
- });
- data.forEach((engine) => {
- engine.windRoseData.forEach((item) => {
- const { windDirection, windSpeedRange } = item;
- const index = windDirections.findIndex(
- (dir, i) =>
- windDirection >= dir && windDirection < windDirections[i + 1]
- );
- if (index !== -1 && counts[windSpeedRange]) {
- counts[windSpeedRange][index] += item.frequency;
- }
- });
- });
- // 构建 traces
- const traces = speedLabels.map((speedLabel) => {
- const percentage = counts[speedLabel];
- return {
- r: percentage,
- theta: windDirections,
- name: speedLabel,
- type: "barpolar",
- marker: {
- color: colorscale[speedLabel],
- line: {
- color: "white",
- width: 1,
- },
- },
- hovertemplate:
- `${axes.radial}:` +
- ` %{r} <br> ` +
- `${axes.angular}:` +
- "%{theta} <br> <extra></extra>",
- };
- });
- // 图表布局
- const layout = {
- title: {
- // text: `${analysisTypeCode} - ${data[0]?.enginName} `,
- text: `风向玫瑰图 - ${data[0]?.enginName} `,
- font: {
- size: 16, // 设置标题字体大小(默认 16)
- weight: "bold",
- },
- },
- plot_bgcolor: "#e5ecf6",
- polar: {
- bgcolor: "#e5ecf6",
- radialaxis: {
- title: { text: axes.radial },
- gridcolor: "rgb(255,255,255)",
- showgrid: true,
- linecolor: "rgb(255,255,255)",
- },
- angularaxis: {
- title: { text: axes.angular },
- tickvals: windDirections,
- gridcolor: "rgb(255,255,255)",
- tickcolor: "rgb(255,255,255)",
- linecolor: "rgb(255,255,255)",
- showticklabels: false, // 隐藏角度标签
- },
- },
- showlegend: true,
- legend: { title: { text: axes.levelname } },
- };
- Plotly.newPlot(`plotDiv-${this.inds}`, traces, layout, {
- modeBarButtonsToRemove: [
- // 移除不需要的工具按钮
- "select2d", // 对应 "Box Select"
- "lasso2d", // 对应 "Lasso Select"
- "zoom2d", // 缩放按钮
- ],
- displaylogo: false,
- responsive: true,
- }).then(function (gd) {
- // 获取工具栏按钮
- const toolbar = gd.querySelector(".modebar");
- const buttons = toolbar.querySelectorAll(".modebar-btn");
- // 定义一个映射对象,方便修改按钮提示
- const titleMap = {
- "Download plot as a png": "保存图片",
- Autoscale: "缩放",
- Pan: "平移",
- "Zoom out": "缩小",
- "Zoom in": "放大",
- "Box Select": "选择框操作",
- "Lasso Select": "套索选择操作",
- "Reset axes": "重置操作",
- "Reset camera to default": "重置相机视角",
- "Turntable rotation": "转台式旋转",
- "Orbital rotation": "轨道式旋转",
- };
- // 遍历所有按钮,修改它们的 title
- buttons.forEach(function (button) {
- const dataTitle = button.getAttribute("data-title");
- // 如果标题匹配,修改属性值
- if (titleMap[dataTitle]) {
- button.setAttribute("data-title", titleMap[dataTitle]);
- }
- });
- });
- },
- },
- };
- </script>
- <style scoped></style>
|