zk-draw
Version:
canvas绘制AI数据的一个工具类
214 lines (206 loc) • 7.41 kB
JavaScript
/*
* @Author: wangfpp
* @Date: 2020-05-03 18:16:35
* @Last Modified by: wangfpp
* @Last Modified time: 2020-07-06 18:01:50
*/
// import handleData from '../index.js'
import {
drawLine
} from '../../draw_line/draw_line.js';
import {
getNodeById
} from '../../../comm/comm.js';
// lineData, scolor, tcolor, lineWidth, canvasWidth {data: [], title: '', scolor: '', tcolor: '', lineWidth: 1}
/**
* @description 绘制ST走向图
* @param {Dom} node 绘制的canvas要插入的父节点
* @param {Number} canvasWidth canvas的大小
* @param { String } lineColor 绘制网格线的颜色
* @param { String } isLegend 是否显示图例
* @param { Object } axisStyle x轴颜色配置 {color: '#f00', font: '14px Arial'}
* @param { Object } yaxisStyle x轴颜色配置 {color: '#f00', font: '14px Arial'}
* @param {Arrray} lineArr 待绘制的数据以及配置文件
* @param { Object } legend 图例配置项 {direction: "horizontal", //"vertical"title: ["教师", "学生"],markColor: ["#20D2FE", "#F0E75A"],markStyle: "circle", //"round"}
*
*/
const drawStLine = (node, canvasWidth, lineColor, isLegend = false, axisStyle, yaxisStyle, lineArr, legend) => {
if (typeof window === 'undefined') {
return;
}
const legendBase = {
direction: "horizontal", //"vertical"
title: ["教师", "学生"],
markColor: ["#20D2FE", "#F0E75A"],
markStyle: "circle", //"round"
};
let legendData = Object.assign({}, legendBase, legend);
lineColor = lineColor || '#000';
canvasWidth = canvasWidth || 400;
drawMain(node, canvasWidth, lineColor, isLegend, axisStyle, yaxisStyle, lineArr, legendData)
}
const drawMain = (node, canvasWidth, lineColor, isLegend, axisStyle, yaxisStyle, lineArr, legendData) => {
let defaultColor = ['#5B8FF9', '#6DC8EC', '#CDDDFD', '#F8D0CB', '#D3EEF9', '#5AD8A6', '#CDF3E4', '#5D7092', '#CED4DE', '#F6BD16', '#FCEBB9', '#E86452', '#945FB9', '#DECFEA', '#FF9845', '#FFE0C7', '#1E9493', '#BBDEDE', '#FF99C3', '#FFE0ED'];
const lineConfig = {
lineWidth: 1,
title: "",
scolor: '#20D2FE',
tcolor: '#F0E75A'
}
// 创建canvas画布
let contentWrap = document.createElement('div'),
canvas = document.createElement('canvas'),
padding = 20;
let legendNode = document.createElement('div');
contentWrap.setAttribute('id', 'zk_st_line');
let canvasWidthRe = legendData.direction === "horizontal" ? canvasWidth : canvasWidth * 0.88;
canvas.width = canvas.height = canvasWidthRe;
contentWrap.setAttribute('style', `width:${canvasWidth}px;position:relative;height:${canvasWidth}px`)
canvas.setAttribute('style', `background: transparent;transform: scale(1);${legendData.direction === "horizontal" ? `margin-top:${padding/2}px;` : `position:absolute;bottom:0;left:0;`};`)
let ctx = canvas.getContext('2d');
canvasWrap(ctx, canvasWidthRe, lineColor, padding);
ctx.beginPath();
let {
color: tcolor,
font: tfont
} = axisStyle || {
color: '#000',
font: "14px Airal"
};
ctx.fillStyle = tcolor
ctx.font = tfont;
ctx.fillText('T', canvasWidthRe - 10, canvasWidthRe - 15)
ctx.closePath();
ctx.beginPath()
let {
color: scolor,
font: sfont
} = yaxisStyle || {
color: '#000',
font: "14px Airal"
};
ctx.fillStyle = scolor;
ctx.font = sfont;
ctx.fillText('S', 5, padding - 5)
ctx.closePath();
let pointx = padding,
pointy = (canvasWidthRe - padding);
let tempStyle = `display:flex;align-items: center;position:absolute;z-index:1;`,
style = legendData.direction === "horizontal" ?
`${tempStyle}
width: ${canvasWidthRe}px;
top:0;
flex-direction:row;
justify-content: space-around;
` :
`${tempStyle}
flex:0.2;
right:0;
bottom:0;
flex-direction:column;
height:${canvasWidthRe}px;
justify-content: center;`;
legendNode.setAttribute('style', style);
lineArr.forEach((item, index) => {
let {
data,
scolor,
tcolor,
lineWidth,
title
} = Object.assign({}, lineConfig, item),
len = data.length,
lineLen = (canvasWidthRe - padding * 2) / len,
// 生成默认颜色
s_line_color = (tcolor && tcolor != "") ? scolor : defaultColor[index * 2],
t_line_color = (tcolor && tcolor != "") ? tcolor : defaultColor[index * 2 + 1];
for (var i = 0; i < len; i++) {
let line_item = data[i];
if (line_item === 'T') {
drawLine(ctx, [pointx, pointy], [pointx, pointy - lineLen], {
lineWidth: lineWidth,
strokeStyle: s_line_color,
lineGap: 'round',
lineJoin: 'round'
})
pointy -= lineLen;
} else {
drawLine(ctx, [pointx, pointy], [pointx + lineLen, pointy], {
lineWidth: lineWidth,
strokeStyle: t_line_color
})
pointx += lineLen;
}
}
// 创建legend图例
let tempStyleChild = `display:flex;align-items: center;cursor:pointer;width: 100%;justify-content: center;`,
styleChild = legendData.direction === "horizontal" ?
`${tempStyleChild}
flex-direction:row;` :
`${tempStyleChild}
flex-direction:column;`;
let legend_child = document.createElement('div');
let divtitle = document.createElement('div');
divtitle.innerHTML = title;
legend_child.setAttribute('style', styleChild);
legend_child.appendChild(divtitle);
legendData.title.map((item, index) => {
legend_child.appendChild(createLegend(item, title, legendData, index));
});
legendNode.appendChild(legend_child);
// 每绘制完一条线重置坐标点
pointx = padding;
pointy = (canvasWidthRe - padding);
});
contentWrap.appendChild(canvas);
if (isLegend) {
contentWrap.appendChild(legendNode);
}
console.log(node);
let trueNode = getNodeById(node);
let stlineContent = trueNode.querySelector('#zk_st_line');
if (stlineContent) {
trueNode.removeChild(stlineContent);
}
trueNode.appendChild(contentWrap);
}
const createLegend = (catlog, title, legendData, index) => {
let warp = document.createElement('div'),
titlediv = document.createElement('div'),
div = document.createElement('div'),
colorDiv = document.createElement('div');
div.innerHTML = `${catlog}`;
titlediv.innerHTML = `${title}`
warp.setAttribute('style', `display: flex;align-items: center;justify-content: space-around;margin:4px;font-size:12px;`);
legendData.markStyle === "circle" ?
colorDiv.setAttribute('style', `background: ${legendData.markColor[index]};width: 8px;height:8px;border-radius: 50%;margin-right:4px;`) :
colorDiv.setAttribute('style', `background: ${legendData.markColor[index]};width: 14px;height:8px;border-radius: 4px;margin-right:4px;`);
warp.appendChild(colorDiv);
warp.appendChild(div);
return warp;
}
/**
* @description 绘制canvas网格图的主体
* @param {Object} ctx canvas 2d
* @param {Number} canvasWidth canvas的大小
* @param {Number} padding 预留出的宽度
*/
const canvasWrap = (ctx, canvasWidth, lineColor, padding) => {
let maxValue = canvasWidth - padding,
minvalue = padding;
drawLine(ctx, [minvalue, minvalue], [minvalue, maxValue], {
lineWidth: 1,
strokeStyle: lineColor
});
drawLine(ctx, [minvalue, maxValue], [maxValue, maxValue]);
drawLine(ctx, [maxValue, maxValue], [maxValue, minvalue]);
drawLine(ctx, [maxValue, minvalue], [minvalue, minvalue]);
let lineGap = (canvasWidth - padding * 2) / 10;
for (var i = 1; i < 10; i++) {
drawLine(ctx, [i * lineGap + padding, minvalue], [i * lineGap + padding, maxValue]);
drawLine(ctx, [minvalue, i * lineGap + minvalue], [maxValue, i * lineGap + minvalue]);
}
}
export {
drawStLine
};