use of com.github.mikephil.charting.data.Entry in project MPAndroidChart by PhilJay.
the class LineChartRenderer method drawValues.
@Override
public void drawValues(Canvas c) {
if (isDrawingValuesAllowed(mChart)) {
List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();
for (int i = 0; i < dataSets.size(); i++) {
ILineDataSet dataSet = dataSets.get(i);
if (!shouldDrawValues(dataSet))
continue;
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
// make sure the values do not interfear with the circles
int valOffset = (int) (dataSet.getCircleRadius() * 1.75f);
if (!dataSet.isDrawCirclesEnabled())
valOffset = valOffset / 2;
mXBounds.set(mChart, dataSet);
float[] positions = trans.generateTransformedValuesLine(dataSet, mAnimator.getPhaseX(), mAnimator.getPhaseY(), mXBounds.min, mXBounds.max);
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
for (int j = 0; j < positions.length; j += 2) {
float x = positions[j];
float y = positions[j + 1];
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsLeft(x) || !mViewPortHandler.isInBoundsY(y))
continue;
Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
if (dataSet.isDrawValuesEnabled()) {
drawValue(c, dataSet.getValueFormatter(), entry.getY(), entry, i, x, y - valOffset, dataSet.getValueTextColor(j / 2));
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
Utils.drawImage(c, icon, (int) (x + iconsOffset.x), (int) (y + iconsOffset.y), icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
}
}
MPPointF.recycleInstance(iconsOffset);
}
}
}
use of com.github.mikephil.charting.data.Entry in project MPAndroidChart by PhilJay.
the class LineChartRenderer method generateFilledPath.
/**
* Generates a path that is used for filled drawing.
*
* @param dataSet The dataset from which to read the entries.
* @param startIndex The index from which to start reading the dataset
* @param endIndex The index from which to stop reading the dataset
* @param outputPath The path object that will be assigned the chart data.
* @return
*/
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float fillMin = dataSet.getFillFormatter().getFillLinePosition(dataSet, mChart);
final float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), fillMin);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = null;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
if (isDrawSteppedEnabled && previousEntry != null) {
filled.lineTo(currentEntry.getX(), previousEntry.getY() * phaseY);
}
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
previousEntry = currentEntry;
}
// close up
if (currentEntry != null) {
filled.lineTo(currentEntry.getX(), fillMin);
}
filled.close();
}
use of com.github.mikephil.charting.data.Entry in project MPAndroidChart by PhilJay.
the class LineChartRenderer method drawLinear.
/**
* Draws a normal line.
*
* @param c
* @param dataSet
*/
protected void drawLinear(Canvas c, ILineDataSet dataSet) {
int entryCount = dataSet.getEntryCount();
final boolean isDrawSteppedEnabled = dataSet.isDrawSteppedEnabled();
final int pointsPerEntryPair = isDrawSteppedEnabled ? 4 : 2;
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
float phaseY = mAnimator.getPhaseY();
mRenderPaint.setStyle(Paint.Style.STROKE);
Canvas canvas = null;
// if the data-set is dashed, draw on bitmap-canvas
if (dataSet.isDashedLineEnabled()) {
canvas = mBitmapCanvas;
} else {
canvas = c;
}
mXBounds.set(mChart, dataSet);
// if drawing filled is enabled
if (dataSet.isDrawFilledEnabled() && entryCount > 0) {
drawLinearFill(c, dataSet, trans, mXBounds);
}
// more than 1 color
if (dataSet.getColors().size() > 1) {
if (mLineBuffer.length <= pointsPerEntryPair * 2)
mLineBuffer = new float[pointsPerEntryPair * 4];
for (int j = mXBounds.min; j <= mXBounds.range + mXBounds.min; j++) {
Entry e = dataSet.getEntryForIndex(j);
if (e == null)
continue;
mLineBuffer[0] = e.getX();
mLineBuffer[1] = e.getY() * phaseY;
if (j < mXBounds.max) {
e = dataSet.getEntryForIndex(j + 1);
if (e == null)
break;
if (isDrawSteppedEnabled) {
mLineBuffer[2] = e.getX();
mLineBuffer[3] = mLineBuffer[1];
mLineBuffer[4] = mLineBuffer[2];
mLineBuffer[5] = mLineBuffer[3];
mLineBuffer[6] = e.getX();
mLineBuffer[7] = e.getY() * phaseY;
} else {
mLineBuffer[2] = e.getX();
mLineBuffer[3] = e.getY() * phaseY;
}
} else {
mLineBuffer[2] = mLineBuffer[0];
mLineBuffer[3] = mLineBuffer[1];
}
trans.pointValuesToPixel(mLineBuffer);
if (!mViewPortHandler.isInBoundsRight(mLineBuffer[0]))
break;
// bounds
if (!mViewPortHandler.isInBoundsLeft(mLineBuffer[2]) || (!mViewPortHandler.isInBoundsTop(mLineBuffer[1]) && !mViewPortHandler.isInBoundsBottom(mLineBuffer[3])))
continue;
// get the color that is set for this line-segment
mRenderPaint.setColor(dataSet.getColor(j));
canvas.drawLines(mLineBuffer, 0, pointsPerEntryPair * 2, mRenderPaint);
}
} else {
if (mLineBuffer.length < Math.max((entryCount) * pointsPerEntryPair, pointsPerEntryPair) * 2)
mLineBuffer = new float[Math.max((entryCount) * pointsPerEntryPair, pointsPerEntryPair) * 4];
Entry e1, e2;
e1 = dataSet.getEntryForIndex(mXBounds.min);
if (e1 != null) {
int j = 0;
for (int x = mXBounds.min; x <= mXBounds.range + mXBounds.min; x++) {
e1 = dataSet.getEntryForIndex(x == 0 ? 0 : (x - 1));
e2 = dataSet.getEntryForIndex(x);
if (e1 == null || e2 == null)
continue;
mLineBuffer[j++] = e1.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
if (isDrawSteppedEnabled) {
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
}
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e2.getY() * phaseY;
}
if (j > 0) {
trans.pointValuesToPixel(mLineBuffer);
final int size = Math.max((mXBounds.range + 1) * pointsPerEntryPair, pointsPerEntryPair) * 2;
mRenderPaint.setColor(dataSet.getColor());
canvas.drawLines(mLineBuffer, 0, size, mRenderPaint);
}
}
}
mRenderPaint.setPathEffect(null);
}
use of com.github.mikephil.charting.data.Entry in project MPAndroidChart by PhilJay.
the class LineChartRenderer method drawCubicBezier.
protected void drawCubicBezier(ILineDataSet dataSet) {
float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
float phaseY = mAnimator.getPhaseY();
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mXBounds.set(mChart, dataSet);
float intensity = dataSet.getCubicIntensity();
cubicPath.reset();
if (mXBounds.range >= 1) {
float prevDx = 0f;
float prevDy = 0f;
float curDx = 0f;
float curDy = 0f;
// Take an extra point from the left, and an extra from the right.
// That's because we need 4 points for a cubic bezier (cubic=4), otherwise we get lines moving and doing weird stuff on the edges of the chart.
// So in the starting `prev` and `cur`, go -2, -1
// And in the `lastIndex`, add +1
final int firstIndex = mXBounds.min + 1;
final int lastIndex = mXBounds.min + mXBounds.range;
Entry prevPrev;
Entry prev = dataSet.getEntryForIndex(Math.max(firstIndex - 2, 0));
Entry cur = dataSet.getEntryForIndex(Math.max(firstIndex - 1, 0));
Entry next = cur;
int nextIndex = -1;
if (cur == null)
return;
// let the spline start
cubicPath.moveTo(cur.getX(), cur.getY() * phaseY);
for (int j = mXBounds.min + 1; j <= mXBounds.range + mXBounds.min; j++) {
prevPrev = prev;
prev = cur;
cur = nextIndex == j ? next : dataSet.getEntryForIndex(j);
nextIndex = j + 1 < dataSet.getEntryCount() ? j + 1 : j;
next = dataSet.getEntryForIndex(nextIndex);
prevDx = (cur.getX() - prevPrev.getX()) * intensity;
prevDy = (cur.getY() - prevPrev.getY()) * intensity;
curDx = (next.getX() - prev.getX()) * intensity;
curDy = (next.getY() - prev.getY()) * intensity;
cubicPath.cubicTo(prev.getX() + prevDx, (prev.getY() + prevDy) * phaseY, cur.getX() - curDx, (cur.getY() - curDy) * phaseY, cur.getX(), cur.getY() * phaseY);
}
}
// if filled is enabled, close the path
if (dataSet.isDrawFilledEnabled()) {
cubicFillPath.reset();
cubicFillPath.addPath(cubicPath);
drawCubicFill(mBitmapCanvas, dataSet, cubicFillPath, trans, mXBounds);
}
mRenderPaint.setColor(dataSet.getColor());
mRenderPaint.setStyle(Paint.Style.STROKE);
trans.pathValueToPixel(cubicPath);
mBitmapCanvas.drawPath(cubicPath, mRenderPaint);
mRenderPaint.setPathEffect(null);
}
use of com.github.mikephil.charting.data.Entry in project MPAndroidChart by PhilJay.
the class RadarHighlighter method getHighlightsAtIndex.
/**
* Returns an array of Highlight objects for the given index. The Highlight
* objects give information about the value at the selected index and the
* DataSet it belongs to. INFORMATION: This method does calculations at
* runtime. Do not over-use in performance critical situations.
*
* @param index
* @return
*/
protected List<Highlight> getHighlightsAtIndex(int index) {
mHighlightBuffer.clear();
float phaseX = mChart.getAnimator().getPhaseX();
float phaseY = mChart.getAnimator().getPhaseY();
float sliceangle = mChart.getSliceAngle();
float factor = mChart.getFactor();
MPPointF pOut = MPPointF.getInstance(0, 0);
for (int i = 0; i < mChart.getData().getDataSetCount(); i++) {
IDataSet<?> dataSet = mChart.getData().getDataSetByIndex(i);
final Entry entry = dataSet.getEntryForIndex(index);
float y = (entry.getY() - mChart.getYChartMin());
Utils.getPosition(mChart.getCenterOffsets(), y * factor * phaseY, sliceangle * index * phaseX + mChart.getRotationAngle(), pOut);
mHighlightBuffer.add(new Highlight(index, entry.getY(), pOut.x, pOut.y, i, dataSet.getAxisDependency()));
}
return mHighlightBuffer;
}
Aggregations