UNPKG

@nativescript-community/ui-chart

Version:

A powerful chart / graph plugin, supporting line, bar, pie, radar, bubble, and candlestick charts as well as scaling, panning and animations.

258 lines 10.9 kB
import { Align } from '@nativescript-community/ui-canvas'; import { LimitLabelPosition } from '../components/LimitLine'; import { AxisDependency, YAxisLabelPosition } from '../components/YAxis'; import { Utils } from '../utils/Utils'; import { YAxisRenderer } from './YAxisRenderer'; export class YAxisRendererHorizontalBarChart extends YAxisRenderer { /** * Computes the axis values. * * @param yMin - the minimum y-value in the data object for this axis * @param yMax - the maximum y-value in the data object for this axis */ computeAxis(yMin, yMax, inverted) { const axis = this.mYAxis; // calculate the starting and entry polet of the y-labels (depending on // zoom / contentrect bounds) const rect = axis.ignoreOffsets ? this.mViewPortHandler.chartRect : this.mViewPortHandler.contentRect; if (rect.height() > 10 && !this.mViewPortHandler.isFullyZoomedOutX()) { const p1 = this.transformer.getValuesByTouchPoint(rect.left, rect.top); const p2 = this.transformer.getValuesByTouchPoint(rect.right, rect.top); if (!inverted) { yMin = p1.x; yMax = p2.x; } else { yMin = p2.x; yMax = p1.x; } } this.computeAxisValues(yMin, yMax); } /** * draws the y-axis labels to the screen */ renderAxisLabels(c) { const axis = this.mYAxis; if (!axis.enabled || !axis.drawLabels) { return; } const positions = this.getTransformedPositions(); const paint = this.axisLabelsPaint; paint.setFont(axis.typeface); paint.setColor(axis.textColor); paint.setTextAlign(Align.CENTER); const baseYOffset = 2.5; const textHeight = Utils.calcTextHeight(paint, 'Q'); const dependency = axis.axisDependency; const labelPosition = axis.position; let yPos = 0; const rect = this.mAxis.ignoreOffsets ? this.mViewPortHandler.chartRect : this.mViewPortHandler.contentRect; if (dependency === AxisDependency.LEFT) { if (labelPosition === YAxisLabelPosition.OUTSIDE_CHART) { yPos = rect.top - baseYOffset; } else { yPos = rect.top - baseYOffset; } } else { if (labelPosition === YAxisLabelPosition.OUTSIDE_CHART) { yPos = rect.bottom + textHeight + baseYOffset; } else { yPos = rect.bottom + textHeight + baseYOffset; } } this.drawYLabels(c, yPos, positions, axis.yOffset); } renderAxisLine(c) { const axis = this.mYAxis; if (!axis.enabled || !axis.drawAxisLine) { return; } const paint = this.axisLinePaint; paint.setColor(axis.axisLineColor); paint.setStrokeWidth(axis.axisLineWidth); const rect = this.mAxis.ignoreOffsets ? this.mViewPortHandler.chartRect : this.mViewPortHandler.contentRect; if (axis.axisDependency === AxisDependency.LEFT) { c.drawLine(rect.left, rect.top, rect.right, rect.top, paint); } else { c.drawLine(rect.left, rect.bottom, rect.right, rect.bottom, paint); } } /** * draws the y-labels on the specified x-position * * @param fixedPosition * @param positions */ drawYLabels(c, fixedPosition, positions, offset) { const axis = this.mYAxis; const paint = this.axisLabelsPaint; paint.setFont(axis.typeface); paint.setColor(axis.textColor); const from = axis.drawBottomYLabelEntry ? 0 : 1; const to = axis.drawTopYLabelEntry ? axis.mEntryCount : axis.mEntryCount - 1; for (let i = from; i < to; i++) { const text = axis.getFormattedLabel(i); if (text) { c.drawText(text + '', positions[i * 2], fixedPosition - offset, paint); } } } getTransformedPositions() { const axis = this.mYAxis; const length = axis.mEntryCount * 2; if (!this.mGetTransformedPositionsBuffer || this.mGetTransformedPositionsBuffer.length !== length) { this.mGetTransformedPositionsBuffer = Utils.createArrayBuffer(length); } const positions = this.mGetTransformedPositionsBuffer; for (let i = 0; i < length; i += 2) { // only fill x values, y values are not needed for x-labels positions[i] = axis.mEntries[i / 2]; } const result = Utils.pointsFromBuffer(positions); this.transformer.pointValuesToPixel(result); return Utils.nativeArrayToArray(result); } getGridClippingRect() { const rect = this.mAxis.ignoreOffsets ? this.mViewPortHandler.chartRect : this.mViewPortHandler.contentRect; const temRect = Utils.getTempRectF(); temRect.set(rect); temRect.inset(-this.mAxis.gridLineWidth, 0); return temRect; } drawZeroLine(c) { const axis = this.mYAxis; const customRender = axis.customRenderer; const customRendererFunc = customRender && customRender.drawZeroLine; const clipRestoreCount = c.save(); const rect = this.mAxis.ignoreOffsets ? this.mViewPortHandler.chartRect : this.mViewPortHandler.contentRect; const zeroLineClippingRect = Utils.getTempRectF(); zeroLineClippingRect.set(rect); zeroLineClippingRect.inset(-axis.zeroLineWidth, 0); c.clipRect(zeroLineClippingRect); // draw zero line const pos = this.transformer.getPixelForValues(0, 0); const paint = this.zeroLinePaint; paint.setColor(axis.zeroLineColor); paint.setStrokeWidth(axis.zeroLineWidth); const zeroLinePath = Utils.getTempPath(); zeroLinePath.reset(); zeroLinePath.moveTo(pos.x - 1, rect.top); zeroLinePath.lineTo(pos.x - 1, rect.bottom); // draw a path because lines don't support dashing on lower android versions if (customRendererFunc) { customRendererFunc(c, axis, pos, zeroLinePath, paint); } else { // draw a path because lines don't support dashing on lower android versions c.drawPath(zeroLinePath, paint); } c.restoreToCount(clipRestoreCount); } /** * Draws the LimitLines associated with this axis to the screen. * This is the standard XAxis renderer using the YAxis limit lines. * * @param c */ renderLimitLines(c) { const axis = this.mYAxis; const limitLines = axis.limitLines; if (!limitLines || limitLines.length <= 0) { return; } const pts = Utils.getTempArray(2); pts[0] = 0; pts[1] = 0; // const limitLinePath = this.renderLimitLinesPath; // limitLinePath.reset(); const customRender = axis.customRenderer; const customRendererFunc = customRender && customRender.drawLimitLine; const rect = axis.ignoreOffsets ? this.mViewPortHandler.chartRect : this.mViewPortHandler.contentRect; const clipToContent = axis.clipLimitLinesToContent; for (let i = 0; i < limitLines.length; i++) { const l = limitLines[i]; if (!l.enabled) { continue; } const lineWidth = l.lineWidth; if (clipToContent) { c.save(); const clipRect = Utils.getTempRectF(); clipRect.set(rect); clipRect.inset(0, -lineWidth); c.clipRect(clipRect); } pts[0] = l.limit; this.transformer.pointValuesToPixel(pts); const paint = this.limitLinePaint; paint.setColor(l.lineColor); paint.setPathEffect(l.dashPathEffect); paint.setStrokeWidth(l.lineWidth); if (lineWidth > 0) { if (customRendererFunc) { customRendererFunc(c, axis, l, rect, pts[0], paint); } else { c.drawLine(pts[0], rect.bottom, pts[0], rect.top, paint); } } const label = l.label; // if drawing the limit-value label is enabled if (label?.length) { paint.setStyle(l.textStyle); paint.setPathEffect(null); paint.setColor(l.textColor); paint.setFont(l.typeface); paint.setStrokeWidth(0.5); paint.setFont(l.typeface); const xOffset = l.lineWidth + l.xOffset; const yOffset = 2 + l.yOffset; const position = l.labelPosition; switch (position) { case LimitLabelPosition.RIGHT_TOP: { const labelLineHeight = Utils.calcTextHeight(paint, label); paint.setTextAlign(Align.LEFT); c.drawText(label, pts[0] + xOffset, rect.top + yOffset + labelLineHeight, paint); break; } case LimitLabelPosition.RIGHT_BOTTOM: { paint.setTextAlign(Align.LEFT); c.drawText(label, pts[0] + xOffset, rect.bottom - yOffset, paint); break; } case LimitLabelPosition.CENTER_TOP: { const labelLineHeight = Utils.calcTextHeight(paint, label); paint.setTextAlign(Align.CENTER); c.drawText(label, pts[0], rect.top + yOffset + labelLineHeight, paint); break; } case LimitLabelPosition.CENTER_BOTTOM: { paint.setTextAlign(Align.CENTER); c.drawText(label, pts[0], rect.bottom - yOffset, paint); break; } case LimitLabelPosition.LEFT_TOP: { paint.setTextAlign(Align.RIGHT); const labelLineHeight = Utils.calcTextHeight(paint, label); c.drawText(label, pts[0] - xOffset, rect.top + yOffset + labelLineHeight, paint); break; } default: { paint.setTextAlign(Align.RIGHT); c.drawText(label, pts[0] - xOffset, rect.bottom - yOffset, paint); break; } } } if (clipToContent) { c.restore(); } } } } //# sourceMappingURL=YAxisRendererHorizontalBarChart.js.map