@@ -10,37 +10,45 @@ const labelFont = `${labelFontSize}px Arial`;
1010 * This plugin draws an x-axis on the chart.
1111 * @param formatLabel A function that converts an x-axis value to a human-readable format
1212 * @param xMarks The number of markers to show on the x-axis
13+ * @param side The side of the graph to render the axis on
1314 * @returns {TimeLinePlugin }
1415 */
1516export const xAxisPlugin = (
1617 formatLabel : ( x : number ) => string = ( x ) => x + "" ,
1718 xMarks = 5 ,
19+ side : "top" | "bottom" = "bottom" ,
1820) : TimeLinePlugin => ( {
1921 construct : ( chart ) => {
20- chart . padding . bottom += 30 ;
22+ chart . padding [ side ] += 30 ;
2123 } ,
2224 "draw:after" : ( chart ) => {
25+ const onBottom = side === "bottom" ;
2326 // Set font properties
2427 chart . ctx . font = labelFont ;
2528 chart . ctx . fillStyle = chart . foregroundColour ;
2629 chart . ctx . textAlign = "start" ;
27- chart . ctx . textBaseline = "top" ;
30+ chart . ctx . textBaseline = onBottom ? "top" : "bottom ";
2831
2932 const xPointGap = Math . floor ( chart . maxPoints / xMarks ) ;
3033
3134 for ( let i = 0 ; i < xMarks ; i ++ ) {
3235 const point = chart . computedData [ i * xPointGap ] ;
3336 if ( ! point ) continue ;
34- const renderY = chart . height - chart . padding . bottom ;
37+ const renderY = onBottom
38+ ? chart . heightInsidePadding + chart . padding . top
39+ : chart . padding . top ;
3540
3641 const label = formatLabel ( point . x ) ;
3742 const textX = point . renderX + 5 ;
38- const textY = renderY + axisGap ;
43+ const textY = renderY + ( onBottom ? axisGap : - axisGap ) ;
3944
4045 // Marker
4146 chart . ctx . beginPath ( ) ;
4247 chart . ctx . moveTo ( point . renderX , renderY ) ;
43- chart . ctx . lineTo ( point . renderX , renderY + tickLength ) ;
48+ chart . ctx . lineTo (
49+ point . renderX ,
50+ renderY + ( onBottom ? tickLength : - tickLength ) ,
51+ ) ;
4452 chart . ctx . stroke ( ) ;
4553
4654 // Label
@@ -53,39 +61,50 @@ export const xAxisPlugin = (
5361 * This plugin draws a y-axis on the chart.
5462 * @param formatLabel A function that converts an y-axis value to a human-readable format
5563 * @param yMarks The number of markers to show on the y-axis
64+ * @param side The side of the graph to render the axis on
5665 * @returns {TimeLinePlugin }
5766 */
5867export const yAxisPlugin = (
5968 formatLabel : ( y : number ) => string = ( y ) => y + "" ,
6069 yMarks = 5 ,
70+ side : "left" | "right" = "left" ,
6171) : TimeLinePlugin => ( {
6272 construct : ( chart ) => {
63- chart . padding . left += 40 ;
73+ chart . padding [ side ] += 40 ;
6474 } ,
6575 "draw:after" : ( chart ) => {
76+ const onLeft = side === "left" ;
6677 const { yOffset, yMultiplier } = chart . getRenderOffsetsAndMultipliers ( ) ;
6778
6879 // Set font properties
6980 chart . ctx . font = labelFont ;
7081 chart . ctx . fillStyle = chart . foregroundColour ;
71- chart . ctx . textAlign = "right" ;
82+ chart . ctx . textAlign = onLeft ? "right" : "left ";
7283 chart . ctx . textBaseline = "top" ;
7384 chart . ctx . fillStyle = chart . foregroundColour ;
7485
86+ const relevantChartContentEdgeX = onLeft
87+ ? chart . padding . left
88+ : chart . padding . left + chart . widthInsidePadding ;
89+
7590 for ( let i = 0 ; i < yMarks ; i ++ ) {
7691 const yValue = ( i * chart . heightInsidePadding ) / ( yMarks - 1 ) ;
77- const yRenderPosition = yValue + chart . padding . top ;
92+ const yRenderPosition = yValue + chart . padding . top + 1 ;
7893 const yDataValue =
7994 ( chart . heightInsidePadding - yValue ) / yMultiplier - yOffset ;
8095
81- const textX = chart . padding . left - axisGap ;
96+ const textX =
97+ relevantChartContentEdgeX + ( onLeft ? - axisGap : axisGap ) ;
8298 const textY = yRenderPosition + axisGap ; // Move down so it doesn't overlap the line
8399 const label = formatLabel ( yDataValue ) ;
84100
85101 //Marker
86102 chart . ctx . beginPath ( ) ;
87- chart . ctx . moveTo ( chart . padding . left - tickLength , yRenderPosition ) ;
88- chart . ctx . lineTo ( chart . padding . left , yRenderPosition ) ;
103+ chart . ctx . moveTo (
104+ relevantChartContentEdgeX + ( onLeft ? - tickLength : tickLength ) ,
105+ yRenderPosition ,
106+ ) ;
107+ chart . ctx . lineTo ( relevantChartContentEdgeX , yRenderPosition ) ;
89108 chart . ctx . stroke ( ) ;
90109
91110 // Label
0 commit comments