/** * draws the x-labels on the specified y-position * * @param pos */ protected void drawLabels(Canvas c, float pos) { // pre allocate to save performance (dont allocate in loop) float[] position = new float[] {0f, 0f}; for (int i = mMinX; i <= mMaxX; i += mXAxis.mAxisLabelModulus) { position[0] = i; mTrans.pointValuesToPixel(position); if (mViewPortHandler.isInBoundsX(position[0])) { String label = mXAxis.getValues().get(i); if (mXAxis.isAvoidFirstLastClippingEnabled()) { // avoid clipping of the last if (i == mXAxis.getValues().size() - 1 && mXAxis.getValues().size() > 1) { float width = Utils.calcTextWidth(mAxisLabelPaint, label); if (width > mViewPortHandler.offsetRight() * 2 && position[0] + width > mViewPortHandler.getChartWidth()) position[0] -= width / 2; // avoid clipping of the first } else if (i == 0) { float width = Utils.calcTextWidth(mAxisLabelPaint, label); position[0] += width / 2; } } c.drawText(label, position[0], pos, mAxisLabelPaint); } } }
/** setup the x-axis labels */ private void prepareXLabels() { StringBuffer a = new StringBuffer(); int max = (int) Math.round(mCurrentData.getXValAverageLength()); for (int i = 0; i < max; i++) { a.append("h"); } mXLabels.mLabelWidth = Utils.calcTextWidth(mXLabelPaint, a.toString()); mXLabels.mLabelHeight = Utils.calcTextWidth(mXLabelPaint, "Q"); }
/** * draws the x-labels on the specified y-position * * @param pos */ @Override protected void drawLabels(Canvas c, float pos) { // pre allocate to save performance (dont allocate in loop) float[] position = new float[] {0f, 0f}; BarData bd = mChart.getData(); int step = bd.getDataSetCount(); for (int i = mMinX; i <= mMaxX; i += mXAxis.mAxisLabelModulus) { position[0] = i * step + i * bd.getGroupSpace() + bd.getGroupSpace() / 2f; // consider groups (center label for each group) if (step > 1) { position[0] += ((float) step - 1f) / 2f; } mTrans.pointValuesToPixel(position); if (mViewPortHandler.isInBoundsX(position[0]) && i >= 0 && i < mXAxis.getValues().size()) { String label = mXAxis.getValues().get(i); int color = mXAxis.getTextColor(i); mAxisLabelPaint.setColor(color); if (mXAxis.isAvoidFirstLastClippingEnabled()) { // avoid clipping of the last if (i == mXAxis.getValues().size() - 1) { float width = Utils.calcTextWidth(mAxisLabelPaint, label); if (width > mViewPortHandler.offsetRight() * 2 && position[0] + width > mViewPortHandler.getChartWidth()) position[0] -= width / 2; // avoid clipping of the first } else if (i == 0) { float width = Utils.calcTextWidth(mAxisLabelPaint, label); position[0] += width / 2; } } c.drawText(label, position[0], pos, mAxisLabelPaint); } } }
/** * returns the maximum length in pixels across all legend labels + formsize + formtotextspace * * @param p the paint object used for rendering the text * @return */ public float getMaximumEntryWidth(Paint p) { float max = 0f; for (int i = 0; i < mLabels.length; i++) { if (mLabels[i] != null) { float length = (float) Utils.calcTextWidth(p, mLabels[i]); if (length > max) max = length; } } return max + mFormSize + mFormToTextSpace; }
public void computeAxis(float xValAverageLength, List<String> xValues) { mAxisLabelPaint.setTypeface(mXAxis.getTypeface()); mAxisLabelPaint.setTextSize(mXAxis.getTextSize()); StringBuffer a = new StringBuffer(); int max = (int) Math.round(xValAverageLength + mXAxis.getSpaceBetweenLabels()); for (int i = 0; i < max; i++) { a.append("h"); } mXAxis.mLabelWidth = Utils.calcTextWidth(mAxisLabelPaint, a.toString()); mXAxis.mLabelHeight = Utils.calcTextHeight(mAxisLabelPaint, "Q"); mXAxis.setValues(xValues); }
/** * Calculates the dimensions of the Legend. This includes the maximum width and height of a single * entry, as well as the total width and height of the Legend. * * @param labelpaint */ public void calculateDimensions(Paint labelpaint, ViewPortHandler viewPortHandler) { mTextWidthMax = getMaximumEntryWidth(labelpaint); mTextHeightMax = getMaximumEntryHeight(labelpaint); switch (mOrientation) { case VERTICAL: { float maxWidth = 0f, maxHeight = 0f, width = 0f; float labelLineHeight = Utils.getLineHeight(labelpaint); final int count = mLabels.length; boolean wasStacked = false; for (int i = 0; i < count; i++) { boolean drawingForm = mColors[i] != ColorTemplate.COLOR_SKIP; if (!wasStacked) width = 0.f; if (drawingForm) { if (wasStacked) width += mStackSpace; width += mFormSize; } // grouped forms have null labels if (mLabels[i] != null) { // make a step to the left if (drawingForm && !wasStacked) width += mFormToTextSpace; else if (wasStacked) { maxWidth = Math.max(maxWidth, width); maxHeight += labelLineHeight + mYEntrySpace; width = 0.f; wasStacked = false; } width += Utils.calcTextWidth(labelpaint, mLabels[i]); if (i < count - 1) maxHeight += labelLineHeight + mYEntrySpace; } else { wasStacked = true; width += mFormSize; if (i < count - 1) width += mStackSpace; } maxWidth = Math.max(maxWidth, width); } mNeededWidth = maxWidth; mNeededHeight = maxHeight; break; } case HORIZONTAL: { int labelCount = mLabels.length; float labelLineHeight = Utils.getLineHeight(labelpaint); float labelLineSpacing = Utils.getLineSpacing(labelpaint) + mYEntrySpace; float contentWidth = viewPortHandler.contentWidth() * mMaxSizePercent; // Start calculating layout float maxLineWidth = 0.f; float currentLineWidth = 0.f; float requiredWidth = 0.f; int stackedStartIndex = -1; mCalculatedLabelBreakPoints.clear(); mCalculatedLabelSizes.clear(); mCalculatedLineSizes.clear(); for (int i = 0; i < labelCount; i++) { boolean drawingForm = mColors[i] != ColorTemplate.COLOR_SKIP; mCalculatedLabelBreakPoints.add(false); if (stackedStartIndex == -1) { // we are not stacking, so required width is for this label // only requiredWidth = 0.f; } else { // add the spacing appropriate for stacked labels/forms requiredWidth += mStackSpace; } // grouped forms have null labels if (mLabels[i] != null) { mCalculatedLabelSizes.add(Utils.calcTextSize(labelpaint, mLabels[i])); requiredWidth += drawingForm ? mFormToTextSpace + mFormSize : 0.f; requiredWidth += mCalculatedLabelSizes.get(i).width; } else { mCalculatedLabelSizes.add(FSize.getInstance(0.f, 0.f)); requiredWidth += drawingForm ? mFormSize : 0.f; if (stackedStartIndex == -1) { // mark this index as we might want to break here later stackedStartIndex = i; } } if (mLabels[i] != null || i == labelCount - 1) { float requiredSpacing = currentLineWidth == 0.f ? 0.f : mXEntrySpace; if (!mWordWrapEnabled // No word wrapping, it must fit. // The line is empty, it must fit || currentLineWidth == 0.f // It simply fits || (contentWidth - currentLineWidth >= requiredSpacing + requiredWidth)) { // Expand current line currentLineWidth += requiredSpacing + requiredWidth; } else { // It doesn't fit, we need to wrap a line // Add current line size to array mCalculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight)); maxLineWidth = Math.max(maxLineWidth, currentLineWidth); // Start a new line mCalculatedLabelBreakPoints.set( stackedStartIndex > -1 ? stackedStartIndex : i, true); currentLineWidth = requiredWidth; } if (i == labelCount - 1) { // Add last line size to array mCalculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight)); maxLineWidth = Math.max(maxLineWidth, currentLineWidth); } } stackedStartIndex = mLabels[i] != null ? -1 : stackedStartIndex; } mNeededWidth = maxLineWidth; mNeededHeight = labelLineHeight * (float) (mCalculatedLineSizes.size()) + labelLineSpacing * (float) (mCalculatedLineSizes.size() == 0 ? 0 : (mCalculatedLineSizes.size() - 1)); break; } } mNeededHeight += mYOffset; mNeededWidth += mXOffset; }