Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีใช้ Bubble Chart ใน Android

สร้าง Bubble Chart (กราฟฟองสบู่) ด้วย MPAndroidChart

Bubble Chart แสดงข้อมูล 3 มิติ: X, Y, และ Size (ขนาดฟองสบู่) เหมาะสำหรับการวิเคราะห์ข้อมูลที่มี 3 ตัวแปร เช่น (ราคา, ยอดขาย, กำไร) หรือ (GDP, ประชากร, CO2)

ขั้นตอนที่ 1: สร้างโปรเจกต์และเพิ่ม Dependency

Module build.gradle:

dependencies {
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}

Project build.gradle: เพิ่ม maven { url 'https://jitpack.io' }

ขั้นตอนที่ 2: Layout - activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.BubbleChart
        android:id="@+id/bubbleChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="16dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

ขั้นตอนที่ 3: MainActivity.java - Bubble Chart พื้นฐาน

package com.example.bubblechartdemo;

import android.graphics.Color;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.github.mikephil.charting.charts.BubbleChart;
import com.github.mikephil.charting.data.BubbleData;
import com.github.mikephil.charting.data.BubbleDataSet;
import com.github.mikephil.charting.data.BubbleEntry;
import com.github.mikephil.charting.utils.ColorTemplate;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private BubbleChart bubbleChart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bubbleChart = findViewById(R.id.bubbleChart);
        setupBubbleChart();
    }

    private void setupBubbleChart() {
        // BubbleEntry(x, y, size)
        List<BubbleEntry> entries = new ArrayList<>();
        entries.add(new BubbleEntry(10f, 50f, 30f));  // x=10, y=50, size=30
        entries.add(new BubbleEntry(20f, 80f, 50f));
        entries.add(new BubbleEntry(30f, 40f, 20f));
        entries.add(new BubbleEntry(40f, 90f, 60f));
        entries.add(new BubbleEntry(50f, 30f, 15f));
        entries.add(new BubbleEntry(60f, 70f, 40f));
        entries.add(new BubbleEntry(70f, 60f, 35f));
        entries.add(new BubbleEntry(80f, 85f, 55f));

        BubbleDataSet dataSet = new BubbleDataSet(entries, "ผลิตภัณฑ์");
        dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
        dataSet.setValueTextColor(Color.WHITE);
        dataSet.setValueTextSize(10f);
        dataSet.setDrawValues(true);
        dataSet.setValueFormatter((value, entry, dataSetIndex, viewPortHandler) -> {
            BubbleEntry be = (BubbleEntry) entry;
            return String.format("Size: %.0f", be.getSize());
        });

        // Highlight Circle
        dataSet.setHighlightCircleWidth(2f);
        dataSet.setHighlightColor(Color.WHITE);

        BubbleData bubbleData = new BubbleData(dataSet);
        bubbleChart.setData(bubbleData);

        customizeBubbleChart();
    }

    private void customizeBubbleChart() {
        bubbleChart.getDescription().setEnabled(false);

        // Touch
        bubbleChart.setTouchEnabled(true);
        bubbleChart.setDragEnabled(true);
        bubbleChart.setScaleEnabled(true);
        bubbleChart.setPinchZoom(true);

        // Axes
        bubbleChart.getXAxis().setPosition(com.github.mikephil.charting.components.XAxis.XAxisPosition.BOTTOM);
        bubbleChart.getXAxis().setGranularity(10f);
        bubbleChart.getXAxis().setAxisMinimum(0f);
        bubbleChart.getXAxis().setAxisMaximum(100f);

        bubbleChart.getAxisLeft().setAxisMinimum(0f);
        bubbleChart.getAxisLeft().setAxisMaximum(100f);
        bubbleChart.getAxisRight().setEnabled(false);

        // Legend
        bubbleChart.getLegend().setEnabled(true);

        // Animation
        bubbleChart.animateXY(1500, 1500);

        bubbleChart.invalidate();
    }
}

BubbleEntry Parameters

new BubbleEntry(float x, float y, float size)

// x: ตำแหน่งแกน X
// y: ตำแหน่งแกน Y  
// size: ขนาดฟองสบู่ (สัมพันธ์กับพื้นที่ π*r²)
// หมายเหตุ: size ไม่ใช่ radius โดยตรง แต่ MPAndroidChart คำนวณ radius = sqrt(size/π)

หลาย Series (Multiple DataSets)

// Series 1: บริษัท A
List<BubbleEntry> entriesA = new ArrayList<>();
entriesA.add(new BubbleEntry(10, 50, 30));
entriesA.add(new BubbleEntry(20, 80, 50));

// Series 2: บริษัท B
List<BubbleEntry> entriesB = new ArrayList<>();
entriesB.add(new BubbleEntry(15, 60, 25));
entriesB.add(new BubbleEntry(25, 70, 45));

BubbleDataSet setA = new BubbleDataSet(entriesA, "บริษัท A");
setA.setColor(Color.RED);
setA.setHighlightCircleWidth(2f);

BubbleDataSet setB = new BubbleDataSet(entriesB, "บริษัท B");
setB.setColor(Color.BLUE);
setB.setHighlightCircleWidth(2f);

BubbleData data = new BubbleData(setA, setB);
bubbleChart.setData(data);

การปรับแต่งขนาดฟองสบู่ (Size Scaling)

// ควบคุมขนาด Max/Min ของฟองสบู่
bubbleChart.setMaxVisibleCount(100); // จุดสูงสุดที่แสดงค่า

// ปรับ Scale ของ Size (default 1.0f)
bubbleChart.getTransformer(YAxis.AxisDependency.LEFT).setScaleX(1f);
bubbleChart.getTransformer(YAxis.AxisDependency.LEFT).setScaleY(1f);

// หรือใช้ setMaxSize() ใน DataSet (API ใหม่)
dataSet.setMaxSize(100f); // ขนาดสูงสุด

ตัวอย่างข้อมูลจริง: ประเทศ (GDP, Population, Area)

// ข้อมูลตัวอย่าง: x=GDP per capita, y=Life Expectancy, size=Population
List<BubbleEntry> countries = new ArrayList<>();
countries.add(new BubbleEntry(65000, 82, 330000000)); // USA
countries.add(new BubbleEntry(45000, 84, 126000000)); // Japan
countries.add(new BubbleEntry(10000, 76, 1400000000)); // China
countries.add(new BubbleEntry(50000, 83, 67000000));  // UK
countries.add(new BubbleEntry(2000, 70, 270000000));  // Indonesia

// ปรับ Size ให้เหมาะสม (Population มากเกินไป)
for (BubbleEntry e : countries) {
    // Scale down population for visualization
    float scaledSize = (float) Math.sqrt(e.getSize() / 1_000_000) * 5; 
    // ต้องสร้าง Entry ใหม่เพราะ BubbleEntry immutable
}

Bubble Chart vs Scatter Chart

คุณสมบัติScatter ChartBubble Chart
มิติข้อมูล2 มิติ (X, Y)3 มิติ (X, Y, Size)
Entry ClassEntryBubbleEntry
การแสดงขนาดคงที่ตามค่า Size
ใช้เมื่อไหร่ความสัมพันธ์ 2 ตัวแปรความสัมพันธ์ 3 ตัวแปร

สรุป

Bubble Chart ใน MPAndroidChart ใช้ BubbleEntry(x, y, size) และ BubbleDataSet แสดงข้อมูล 3 มิติได้ชัดเจน จุดสำคัญคือการ Scale Size ให้เหมาะสมกับพื้นที่ Chart และใช้สีแยก Series ชัดเจน