UNPKG

zk-draw

Version:

canvas绘制AI数据的一个工具类

214 lines (206 loc) 7.41 kB
/* * @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 };