1 package com.github.mikephil.charting.components; 2 3 import android.content.Context; 4 import android.graphics.Bitmap; 5 import android.graphics.Canvas; 6 import android.graphics.Rect; 7 import android.graphics.drawable.Drawable; 8 import android.os.Build; 9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.widget.RelativeLayout; 12 13 import com.github.mikephil.charting.charts.Chart; 14 import com.github.mikephil.charting.data.Entry; 15 import com.github.mikephil.charting.highlight.Highlight; 16 import com.github.mikephil.charting.utils.FSize; 17 import com.github.mikephil.charting.utils.MPPointF; 18 19 import java.lang.ref.WeakReference; 20 21 /** 22 * View that can be displayed when selecting values in the chart. Extend this class to provide custom layouts for your 23 * markers. 24 * 25 * @author Philipp Jahoda 26 */ 27 public class MarkerImage implements IMarker { 28 29 private Context mContext; 30 private Drawable mDrawable; 31 32 private MPPointF mOffset = new MPPointF(); 33 private MPPointF mOffset2 = new MPPointF(); 34 private WeakReference<Chart> mWeakChart; 35 36 private FSize mSize = new FSize(); 37 private Rect mDrawableBoundsCache = new Rect(); 38 39 /** 40 * Constructor. Sets up the MarkerView with a custom layout resource. 41 * 42 * @param context 43 * @param drawableResourceId the drawable resource to render 44 */ MarkerImage(Context context, int drawableResourceId)45 public MarkerImage(Context context, int drawableResourceId) { 46 mContext = context; 47 48 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 49 { 50 mDrawable = mContext.getResources().getDrawable(drawableResourceId, null); 51 } 52 else 53 { 54 mDrawable = mContext.getResources().getDrawable(drawableResourceId); 55 } 56 } 57 setOffset(MPPointF offset)58 public void setOffset(MPPointF offset) { 59 mOffset = offset; 60 61 if (mOffset == null) { 62 mOffset = new MPPointF(); 63 } 64 } 65 setOffset(float offsetX, float offsetY)66 public void setOffset(float offsetX, float offsetY) { 67 mOffset.x = offsetX; 68 mOffset.y = offsetY; 69 } 70 71 @Override getOffset()72 public MPPointF getOffset() { 73 return mOffset; 74 } 75 setSize(FSize size)76 public void setSize(FSize size) { 77 mSize = size; 78 79 if (mSize == null) { 80 mSize = new FSize(); 81 } 82 } 83 getSize()84 public FSize getSize() { 85 return mSize; 86 } 87 setChartView(Chart chart)88 public void setChartView(Chart chart) { 89 mWeakChart = new WeakReference<>(chart); 90 } 91 getChartView()92 public Chart getChartView() { 93 return mWeakChart == null ? null : mWeakChart.get(); 94 } 95 96 @Override getOffsetForDrawingAtPoint(float posX, float posY)97 public MPPointF getOffsetForDrawingAtPoint(float posX, float posY) { 98 99 MPPointF offset = getOffset(); 100 mOffset2.x = offset.x; 101 mOffset2.y = offset.y; 102 103 Chart chart = getChartView(); 104 105 float width = mSize.width; 106 float height = mSize.height; 107 108 if (width == 0.f && mDrawable != null) { 109 width = mDrawable.getIntrinsicWidth(); 110 } 111 if (height == 0.f && mDrawable != null) { 112 height = mDrawable.getIntrinsicHeight(); 113 } 114 115 if (posX + mOffset2.x < 0) { 116 mOffset2.x = - posX; 117 } else if (chart != null && posX + width + mOffset2.x > chart.getWidth()) { 118 mOffset2.x = chart.getWidth() - posX - width; 119 } 120 121 if (posY + mOffset2.y < 0) { 122 mOffset2.y = - posY; 123 } else if (chart != null && posY + height + mOffset2.y > chart.getHeight()) { 124 mOffset2.y = chart.getHeight() - posY - height; 125 } 126 127 return mOffset2; 128 } 129 130 @Override refreshContent(Entry e, Highlight highlight)131 public void refreshContent(Entry e, Highlight highlight) { 132 133 } 134 135 @Override draw(Canvas canvas, float posX, float posY)136 public void draw(Canvas canvas, float posX, float posY) { 137 138 if (mDrawable == null) return; 139 140 MPPointF offset = getOffsetForDrawingAtPoint(posX, posY); 141 142 float width = mSize.width; 143 float height = mSize.height; 144 145 if (width == 0.f) { 146 width = mDrawable.getIntrinsicWidth(); 147 } 148 if (height == 0.f) { 149 height = mDrawable.getIntrinsicHeight(); 150 } 151 152 mDrawable.copyBounds(mDrawableBoundsCache); 153 mDrawable.setBounds( 154 mDrawableBoundsCache.left, 155 mDrawableBoundsCache.top, 156 mDrawableBoundsCache.left + (int)width, 157 mDrawableBoundsCache.top + (int)height); 158 159 int saveId = canvas.save(); 160 // translate to the correct position and draw 161 canvas.translate(posX + offset.x, posY + offset.y); 162 mDrawable.draw(canvas); 163 canvas.restoreToCount(saveId); 164 165 mDrawable.setBounds(mDrawableBoundsCache); 166 } 167 } 168