Due to the business needs of the company, the style of highcharts and Echarts chart library does not meet the design requirements, so canvas is selected to package a bar chart that supports personalized configuration without considering ie8 and other browsers. Hopefully there are front-end partners that need similar diagrams that can be useful. Since personalization requires a variety of parameters with custom sizes and colors, I have divided the parameters into four categories -- basic parameters, axis, column data, and enhanced attributes.Copy the code
-
Let’s take a look at the renderings
-
access
- Place a canvas in HTML
<canvas id="canvas"></canvas> Copy the code
-
Introduce the function drawHistogram below
-
Execution method
drawHistogram(chartsConfigObj); Copy the code
-
Parameter interpretation
- Layer 1 Parameter description
@param {basicData} is mandatory. @param {axisData} is mandatory. @param {columnData} is mandatory. Column data * @param {enhancementAttr} non-mandatory, some enhanced attributes */Copy the code
- Layer 2 parameter
let { basicData: { wrapEleId, width, height }, axisData: { basic: { axislineWidth, axisColor, axisTextColor, axisTextFont, }, axisX: { axisXStart, axisXWidth, axisXTextDistance }, axisY: { axisYStart, axisYWidth, axisYIntervalNum, axisYTextDistance, axisYMaxNum } }, columnData: { eachColumnWidth, spaceDistance, columnMaxHeight, columnColor, firstColumnStartX, firstColumnStartY }, graphs } = chartsConfigObj; const {enhancementAttr} = chartsConfigObj; let { isColumnNeedRadius, columnGradientData, isRemoveAxisArrow, horizontalLineObj } = enhancementAttr || {}; let { gradientStartColor, gradientEndColor } = columnGradientData || {}; let{ horizontalLineColor, horizontalLineDistance } = horizontalLineObj || {}; @param {wrapEleId} canvas canvas ID * @param {width} canvas width * @param {height} canvas height * @param {eachColumnWidth} Width of a column * @param {spaceDistance} Spacing between columns * @param {firstColumnStartX} X-axis coordinates in the lower left corner of the first column * @param {firstColumnStartY} * @param {columnMaxHeight} maximum column height * @param {axislineWidth} axislineWidth * @param {axisXStart} axisX starting point * @param {axisYStart} coordinate axisY starting point * @param {axisXWidth} coordinate axisX length * @param {axisYWidth} coordinate axisY length * @param {axisXTextDistance} * @param {axisYTextDistance} The horizontal offset of the Y-axis * @param {axisYIntervalNum} the left Y-axis spacing * @param {axisYMaxNum} left axis y scale Max * @param {axisColor} coordinate axisColor * @param {axisTextColor} coordinate axisTextColor * @param {axisTextFont} ColumnColor * @Param {Graphs} Graph data - Array, [{x:, Y :},...] * @param {columnGradientData} Column gradient information, @param {gradientStartColor} gradientStartColor (near the X-axis) @param {gradientEndColor} gradientEndColor (near the X-axis) Do columns need rounded corners * @param {gradientEndColor} gradient end * @Param {gradientEndColor} gradient end * @param {horizontalLineObj} horizontal dashed background parameters, do not pass {color,space} */ if not neededCopy the code
-
Function implementation code
export default function drawHistogram(chartsConfigObj) {
let {
basicData: {
wrapEleId,
width,
height
},
axisData: {
basic: {
axislineWidth,
axisColor,
axisTextColor,
axisTextFont,
},
axisX: {
axisXStart,
axisXWidth,
axisXTextDistance
},
axisY: {
axisYStart,
axisYWidth,
axisYIntervalNum,
axisYTextDistance,
axisYMaxNum
}
},
columnData: {
eachColumnWidth,
spaceDistance,
columnMaxHeight,
columnColor,
firstColumnStartX,
firstColumnStartY
},
graphs
} = chartsConfigObj;
const {enhancementAttr} = chartsConfigObj;
let {
isColumnNeedRadius,
columnGradientData,
isRemoveAxisArrow,
horizontalLineObj
} = enhancementAttr || {};
let {
gradientStartColor,
gradientEndColor
} = columnGradientData || {};
let {
horizontalLineColor,
horizontalLineDistance
} = horizontalLineObj || {};
horizontalLineColor = horizontalLineColor ? horizontalLineColor : '#eee';
horizontalLineDistance = horizontalLineDistance ? horizontalLineDistance: 5;
isRemoveAxisArrow = isRemoveAxisArrow ? isRemoveAxisArrow : false;
var canvas = document.getElementById(wrapEleId);
var context = canvas.getContext("2d"); canvas.width = width; canvas.height = height; context.beginPath(); // draw the X-axis context.beginPath(); context.moveTo(axisXStart, axisYStart); context.lineTo(axisXStart + axisXWidth, axisYStart); context.strokeStyle = axisColor; context.lineWidth = axislineWidth; context.stroke(); context.beginPath();if(! isRemoveAxisArrow) { context.moveTo(axisXStart + axisXWidth - 6, axisYStart-6); context.lineTo(axisXStart + axisXWidth, axisYStart); context.lineTo(axisXStart + axisXWidth - 6, axisYStart+6); context.strokeStyle = axisColor; context.lineWidth = axislineWidth; context.stroke(); } // draw the Y-axis context.beginPath(); var axisYEnd = height - (height - axisYStart + axisYWidth); context.moveTo(axisXStart, axisYStart); context.lineTo(axisXStart, axisYEnd); context.strokeStyle = axisColor; context.lineWidth = axislineWidth; context.stroke(); context.beginPath();if(! isRemoveAxisArrow) { context.moveTo(axisXStart - 6, axisYEnd + 6); context.lineTo(axisXStart, axisYEnd); context.lineTo(axisXStart + 6, axisYEnd + 6); context.strokeStyle = axisColor; context.lineWidth = axislineWidth; context.stroke(); } var axisYNum = axisYMaxNum/axisYIntervalNum; var axisYLength = columnMaxHeight / axisYNum;for (var j = 0; j <= axisYNum; j++) {
context.beginPath();
context.moveTo(axisXStart, axisYStart);
context.font = axisTextFont;
context.textAlign = "center";
context.fillStyle = axisTextColor;
context.fillText(j*axisYIntervalNum,axisXStart - 15, axisYStart - j * axisYLength + axisYTextDistance);
context.beginPath();
context.moveTo(axisXStart, axisYStart - j * axisYLength);
context.lineTo(axisXStart+5, axisYStart - j * axisYLength);
context.strokeStyle = axisColor;
context.lineWidth = axislineWidth;
context.stroke();
if(horizontalLineObj && j ! == 0) { context.beginPath(); context.moveTo(axisXStart, axisYStart - j * axisYLength); context.lineTo(axisXStart+axisXWidth, axisYStart - j * axisYLength); context.setLineDash([horizontalLineObj.space || 10]); context.strokeStyle = horizontalLineObj.color ||'#eee'; context.stroke(); } } context.beginPath(); Var columnLength = graph.length;for (var i = 0; i < columnLength; i++) {
var colData = graphs[i];
var colStratX = firstColumnStartX+(i*spaceDistance)+(i*eachColumnWidth);
var colStratY = height - (height - firstColumnStartY + (colData.y/100) * columnMaxHeight);
if(isColumnNeedRadius) {
const r = eachColumnWidth / 2;
const w = eachColumnWidth;
const h = -((colData.y/100) * columnMaxHeight);
const x = colStratX;
const y = firstColumnStartY;
context.beginPath();
context.moveTo(x + r, y);
context.arcTo(x + w, y, x + w, y + h, r);
context.arcTo(x + w, y + h, x, y + h, r);
context.arcTo(x, y + h, x, y, r);
context.arcTo(x, y, x + w, y, r);
context.closePath();
} else{ context.beginPath(); context.moveTo(colStratX, firstColumnStartY); context.lineTo(colStratX, colStratY); context.lineTo(colStratX+eachColumnWidth, colStratY); context.lineTo(colStratX+eachColumnWidth, firstColumnStartY); context.closePath(); } // Gradient is requiredif(columnGradientData) { var grad = context.createLinearGradient(0, firstColumnStartY, 0,colStratY); grad.addColorStop(0, gradientStartColor); / / green grad. AddColorStop (1, gradientEndColor); // purple context.fillStyle = grad; }else {
context.fillStyle = columnColor;
}
context.fill();
context.font = axisTextFont;
context.textAlign="center"; context.fillStyle = axisTextColor; context.fillText(colData.x, colStratX+eachColumnWidth/2, firstColumnStartY + axisXTextDistance); }}Copy the code
- Example data
const chartsConfigObj = {
basicData: {
wrapEleId: 'canvas',
width: 860,
height: 400
},
axisData: {
basic: {
axislineWidth: 1,
axisColor: '# 999',
axisTextColor: '# 666',
axisTextFont: '12px PingFangSC-Regular',
},
axisX: {
axisXStart: 26,
axisXWidth: 850,
},
axisY: {
axisYStart: 365,
axisYWidth: 190,
axisYIntervalNum: 20,
axisYTextDistance: 2,
axisYMaxNum: 100
}
},
columnData: {
eachColumnWidth: 14,
spaceDistance: 30,
columnMaxHeight: 156,
columnColor: '#f00',
firstColumnStartX: 50,
firstColumnStartY: 365
},
enhancementAttr: {
isColumnNeedRadius: true,
columnGradientData: {
gradientStartColor: '#35E1A0',
gradientEndColor: '#29CDC0'
},
horizontalLineObj: {
horizontalLineColor: '# 999',
horizontalLineDistance: 5
},
isRemoveAxisArrow: true
},
graphs: [
{
'x': '2011'.'y': '100'
}, {
'x': '2012'.'y': '90'
}, {
'x': '2013'.'y': '60'
}, {
'x': '2014'.'y': '90'
}, {
'x': '2015'.'y': '70'
}, {
'x': '2016'.'y': '10'
}, {
'x': '2011'.'y': '100'
}, {
'x': '2012'.'y': '90'
}, {
'x': '2013'.'y': '60'
}, {
'x': '2014'.'y': '90'
}, {
'x': '2015'.'y': '70'
}, {
'x': '2016'.'y': '10'
}, {
'x': '2011'.'y': '100'
}, {
'x': '2012'.'y': '90'
}, {
'x': '2013'.'y': '60'
}, {
'x': '2014'.'y': '30'
}, {
'x': '2015'.'y': '10'
}, {
'x': '2016'.'y': '95'}};Copy the code