android 如何在水平条形图中显示可用和不可用的插槽

How to display available and unavailable slots in a horizontal bar graph in android

我试图在水平条形图上显示可用和不可用的插槽,但找不到解决方案。来自服务器的值是这样的:

start_time - 9.30am
end_time - 11.30am
status - available

start_time - 11.30am
end_time - 12.00pm
status - available

start_time - 12.00pm
end_time - 15.00pm
status - not available

[and so on... till 21.00pm]

所以我必须在单个水平条上用绿色表示可用插槽,用灰色表示不可用插槽。目前,我正在使用 MP Chart Android 的水平条形图,但它没有给我想要的结果。

这是我想要实现的形象:

这是我使用的代码:

int StockColors[] = new int[]{Color.parseColor("#24E224"), Color.parseColor("#A9A9A9")};

                    ArrayList<BarEntry> entries = new ArrayList<>();
                    entries.add(new BarEntry(0f, arr));
                    BarDataSet bardataset = new BarDataSet(entries, "");
                    bardataset.setColors(StockColors);
                    bardataset.setDrawValues(false);
                    stockChart.getAxisRight().setCenterAxisLabels(true);
                    BarData data = new BarData(bardataset);
                    data.setBarWidth(5f);

                    Legend legend = stockChart.getLegend();

                    LegendEntry legendentry1 = new LegendEntry();
                    legendentry1.label = "Available Slot";
                    legendentry1.formColor = Color.GREEN;

                    LegendEntry legendentry2 = new LegendEntry();
                    legendentry2.label = "UnAvailable Slot";
                    legendentry2.formColor = Color.GRAY;

                    legend.setCustom(Arrays.asList(legendentry1, legendentry2));

                    stockChart.setExtraBottomOffset(20f);
                    stockChart.getLegend().setXEntrySpace(30f);
                    stockChart.getLegend().setYEntrySpace(20f);
                    stockChart.getAxisRight().setDrawGridLines(false);
                    stockChart.getAxisRight().setDrawAxisLine(false);
                    stockChart.getAxisRight().setGranularity(1f);

                    stockChart.setViewPortOffsets(0f, 0f, 0f, 0f);
                    stockChart.setExtraOffsets(0f, 0f, 0f, 0f);

                    stockChart.getAxisLeft().setEnabled(false); //show y-axis at left
                    stockChart.getAxisRight().setEnabled(true); //hide y-axis at right

                    stockChart.setScaleEnabled(false);
                    stockChart.getAxisRight().setEnabled(true);
                    stockChart.getXAxis().setEnabled(false);
                    stockChart.getXAxis().setDrawAxisLine(false);

                    stockChart.setData(data);
                    stockChart.getAxisRight().setTextColor(Color.WHITE);
                    stockChart.getXAxis().setTextColor(Color.WHITE);
                    stockChart.getLegend().setTextColor(Color.WHITE);

                    stockChart.getDescription().setEnabled(false);
                    stockChart.setFitBars(false);
                    stockChart.setTouchEnabled(true);

                    stockChart.setDrawGridBackground(false);
                    stockChart.setDrawBarShadow(false);
                    stockChart.setDrawValueAboveBar(false);
                    stockChart.invalidate();

                    xvalues = new ArrayList<>();
                    xvalues.add("9.00");
                    xvalues.add("10.00");
                    xvalues.add("11.00");
                    xvalues.add("12.00");
                    xvalues.add("13.00");
                    xvalues.add("14.00");
                    xvalues.add("15.00");
                    xvalues.add("16.00");
                    xvalues.add("17.00");
                    xvalues.add("18.00");
                    xvalues.add("19.00");
                    xvalues.add("20.00");
                    xvalues.add("21.00");

                    stockChart.getAxisRight().setLabelCount(xvalues.size()+3, true); // also if i use entries.size() here, then only few labels are visible
                    stockChart.getAxisRight().setDrawLabels(true);

stockChart.getAxisRight().setValueFormatter(new newBarChartXaxisFormatter());


public class newBarChartXaxisFormatter implements IAxisValueFormatter
    {
        @SuppressLint("StringFormatInvalid")
        @Override
        public String getFormattedValue(float value, AxisBase axis) {
            int a = (int) (10f + value); // if i use 9f then it starts with 7
            return String.valueOf(a);
        }
    }

这是上面代码的当前结果:

获得上图的正确方法是使用 MpAndroidChartStacked Bar graphHorizo​​ntalBarChart 组件

Note: I will be linking the project with the sample output shown in the above diagram. Check the comments section for the link. Run HorizontalStackedBarGraph.kt activity to try the solution. The code written below is commented to give you an idea as to how you can implement it in your project.

将以上代码粘贴到您的 activity XML

<com.github.mikephil.charting.charts.HorizontalBarChart
    android:id="@+id/timetable_barchart"
    android:layout_marginBottom="40dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

class HorizontalStackedBarGraph : AppCompatActivity() {

val startTime = 9f
val EXTRA_GRAPH_SIZE = 3
// In Horizontal graph Bar width will set your graph height.
val BAR_WIDTH = 0.3F
// Calculate the time interval and create an array
val entries = floatArrayOf(2f, 1f, 3f, 3f, 1f, 2f) 

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_horizontal_stacked_bar_graph)

    val barChart = findViewById<BarChart>(R.id.timetable_barchart);
    
    // Add the list of values to a single BarEntry
    val timeTableEntries = BarEntry(0f, entries)
    val set1 = BarDataSet(listOf(timeTableEntries), "TimeTable")
    set1.setColors(intArrayOf(R.color.colorAvailableSlot, R.color.colorUnAvailableSlot), this)
    set1.setDrawValues(false)
    val barData = BarData(set1)
    barData.barWidth = BAR_WIDTH
    barChart.data = barData
    barChart.description.isEnabled = false
    
    val legend1= LegendEntry().apply {
        formColor = ContextCompat.getColor(this@HorizontalStackedBarGraph, R.color.colorAvailableSlot)
        label = "Unavailable Slot"
    }
    
    val legend2= LegendEntry().apply {
        formColor = ContextCompat.getColor(this@HorizontalStackedBarGraph, R.color.colorUnAvailableSlot)
        label = "Available Slot"
    }

    val valueFormatterForTime = object : ValueFormatter() {
        override fun getFormattedValue(value: Float): String {
            return getString(R.string.time, (startTime + value).toInt())
        }
    }

    //Bar graph customization
    barChart.extraBottomOffset = 20f
    barChart.legend.xEntrySpace = 10f
    barChart.legend.setCustom(arrayListOf(legend1, legend2))
    barChart.axisRight.apply {
        setDrawGridLines(false)
        granularity = 1f
        valueFormatter = valueFormatterForTime
        labelCount = entries.size + EXTRA_GRAPH_SIZE
    }
    barChart.axisLeft.isEnabled = false
    barChart.xAxis.isEnabled = false
    barChart.xAxis.axisMinimum = 0f
    barChart.setDrawGridBackground(false)
    barChart.setDrawBarShadow(false)
    barChart.setDrawValueAboveBar(false)
    barChart.invalidate()
    }
}