首页 > 解决方案 > 如何在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);
        }
    }

这是上面代码的当前结果: 我使用上面的代码得到的图像

标签: androidandroid-studiographbar-chartmpandroidchart

解决方案


实现上图的正确方法是使用MpAndroidChart 的Stacked Bar 图Horizo ​​ntalBarChart 组件

样本输出图像

注意:我会将项目与上图中显示的示例输出链接。检查链接的评论部分。运行HorizontalStackedBarGraph.kt活动以尝试解决方案。下面编写的代码经过注释,可以让您了解如何在项目中实现它。

将上述代码粘贴到您的活动 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()
    }
}

推荐阅读