绘制组合图是一种常见的需求。日常所见的组合图,比如股价走势图,上面有股价图(蜡烛图),还有趋势线(MA5,MA10,MA60等等)。
本文给定三个系列的数据,前两个系列绘制成Bar图,后一个系列绘制成Line图,其中两个Bar用的是同一个Y轴的刻度范围(Y轴1),Line图用的是另一个Y轴的刻度范围。*
一、要画的图(示例)
-
X轴:月份,从1月到12月
-
Y轴1【左】:温度,
-
Y轴2【右】:温差比值,百分比0% - 100%
-
数据1:林内温度,刻度用的是Y轴1(左)
-
数据2:林外温度,刻度用的是Y轴1(左)
-
数据3:温差比值,刻度用的是Y轴2(右)
二、作图的大概流程(关键步骤)
文章来源:https://www.toymoban.com/news/detail-650653.html
文章来源地址https://www.toymoban.com/news/detail-650653.html
三、代码清单
using Cysharp.Threading.Tasks;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using XCharts.Runtime;
/// <summary>
/// line和bar的合并图表
/// </summary>
public class ExampleComboChart : MonoBehaviour
{
/// <summary>
/// 测试按钮——画线
/// </summary>
public Button StartBtn;
void Start()
{
StartBtn.onClick.AddListener(() =>
{
DrawComboChartFlow();
});
}
/// <summary>
/// 绘制复合图的流程
/// </summary>
/// <returns></returns>
private async UniTask DrawComboChartFlow()
{
//【1】添加一个LineChart的组件
Debug.Log("添加一个组合图表");
var chart = gameObject.GetComponent<LineChart>();
if (chart == null)
{
chart = gameObject.AddComponent<LineChart>();
chart.Init();
}
//【2】设置图表的大小:SetSize(x,y)
Debug.Log("设置图表的大小(580, 300) ");
chart.SetSize(580, 300);//代码动态设置尺寸
Debug.Log("2秒后重新设置大小(1102, 519) ");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
chart.SetSize(1102, 519);
//【3】设置标题:chart.Title.text|subText = ""
Debug.Log("2秒后:设置标题 ");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
var title = chart.GetOrAddChartComponent<Title>();
title.text = "各月份林内林外温度"; //主标题
title.subText = "分析对比图"; //副标题
//【4】设置提示框【Tooltip】和图例【Legend】是否显示
//Tooltip - 鼠标悬停在曲线节点上的时候,显示数据信息
//Legend - 图上数据系列的类别信息【例如[red-白天温度]、[black-晚上温度]】
Debug.Log("2秒后:设置提示框和图例是否显示");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
var tooltip = chart.GetOrAddChartComponent<Tooltip>();
tooltip.show = true; //在数据节点上,鼠标悬停时显示的信息框
var legend = chart.GetOrAddChartComponent<Legend>();
legend.show = true;
//【5】设置坐标轴的数据刻度信息
Debug.Log("2秒后:设置坐标轴");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
//——x轴设置
var xAxis = chart.GetOrAddChartComponent<XAxis>();
xAxis.splitNumber = 24; //数据的个数-参数硬编码
xAxis.boundaryGap = true;
xAxis.type = Axis.AxisType.Category;
//X轴的坐标轴名称设置
xAxis.axisName.name = "月份";
xAxis.axisName.show = true;
xAxis.axisName.labelStyle.position = LabelStyle.Position.Middle;
xAxis.axisName.labelStyle.rotate = 0;
xAxis.axisName.labelStyle.textPadding.top = 100;
//——y轴设置
//第一个Y轴设置
var yAxis1 = chart.GetOrAddChartComponent<YAxis>();
yAxis1.type = Axis.AxisType.Value;
yAxis1.axisLabel.formatter = "{value}℃";
//Y轴1的坐标轴名称设置
yAxis1.axisName.name = "温度";
yAxis1.axisName.show = true;
yAxis1.axisName.labelStyle.position = LabelStyle.Position.End;
yAxis1.axisName.labelStyle.rotate = 90;
yAxis1.axisName.labelStyle.textPadding.bottom = 150;
//第二个Y轴设置
var yAxis2 = chart.AddChartComponent<YAxis>();
yAxis2.minMaxType = Axis.AxisMinMaxType.Custom;
yAxis2.min = 0;
yAxis2.max = 100;
yAxis2.position = Axis.AxisPosition.Right;
yAxis2.axisLabel.formatter = "{value}%";
//Y轴2的坐标轴名称设置
yAxis2.axisName.name = "温差比值";
yAxis2.axisName.show = true;
yAxis2.axisName.labelStyle.position = LabelStyle.Position.End;
yAxis2.axisName.labelStyle.rotate = 90;
yAxis2.axisName.labelStyle.textPadding.top = 140;
//【6】清空默认数据,添加Scatter类型的Serie用于接收数据
Debug.Log("2秒后:清空默认数据,添加Scatter类型的Serie用于接收数据");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
chart.RemoveData();
//【7】添加数据:X轴的刻度数据,Y轴的数据
var serie1 = chart.AddSerie<Bar>("林内温度"); //增加一个Bar系列
serie1.yAxisIndex = 0;//它的Y轴设定为第一个Y轴
var serie2 = chart.AddSerie<Bar>("林外温度"); //增加一个Bar系列
serie2.yAxisIndex = 0;//它的Y轴设定为第一个Y轴
var serie3 = chart.AddSerie<Line>("温差比值"); //增加一个Line系列
serie3.yAxisIndex = 1;//它的Y轴设定为第二个Y轴
Debug.Log("2秒后:添加数据");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
var seriesNums = Enumerable.Range(0, 12).ToList(); //12个数据
var xTickLabels = new List<string> { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
var y1Values = new List<float> { 1,2,3,4,5,6,7,8,9,10,11,12};
y1Values = seriesNums.Select(x => (float)(UnityEngine.Random.Range(10, 20))).ToList(); //[min,max) 前开后闭
var y2Values = new List<float> { 2,3,4,5,6,7,8,9,10,11,12,13 };
y2Values = y1Values.Select(x => (float)(x + UnityEngine.Random.Range(10, 20) / 10.0) ).ToList(); //Y2 = f(Y1)
var y3Values = new List<float> {3,4,5,6,7,8,9,10,11,12,13,14 };
y3Values = y1Values.Zip(y2Values, (y1, y2) => Math.Abs(y1 - y2)/y1 * 100).ToList(); //Y3 = f(Y1,Y2)
//数据添加到图表上
seriesNums.ForEach(idx =>
{
chart.AddXAxisData(xTickLabels[idx]); //X轴的刻度标签
chart.AddData(0, y1Values[idx]); //Y1,第一组数据
chart.AddData(1, y2Values[idx]); //Y2,第二组数据
chart.AddData(2, y3Values[idx]); //Y3,第二组数据
});
//【8】x轴刻度标签旋转(倾斜)设置
Debug.Log("2秒后:x轴刻度标签旋转设置");
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
xAxis.axisLabel.rotate = 45;
//【9】设置线条的颜色
Debug.Log("0.4秒后:线条的颜色设置");
await UniTask.Delay(TimeSpan.FromSeconds(0.4f));
chart.series[0].itemStyle.color = Color.red; //第一组线条的颜色
chart.series[1].itemStyle.color = Color.green; //第二组线条的颜色
chart.series[2].itemStyle.color = Color.blue; //第三组线条的颜色
//【10】线条样式设置:
await UniTask.Delay(TimeSpan.FromSeconds(2.0f));
Debug.Log("2秒后:设置Bar的width");
chart.series[0].barWidth = 20;
chart.series[0].barType = BarType.Zebra; //斑马线样式
chart.series[1].barWidth = 20;
chart.series[1].barType = BarType.Normal; //默认样式
chart.series[2].lineStyle.width = 1;
chart.series[2].lineType = LineType.Smooth; //线条设置为平滑
//刷新所有的组件【不刷新的话,发现不能画直线】
chart.RefreshAllComponent();
}
#if UNITY_EDITOR
[ContextMenu("测试")]
#endif
void Test()
{
DrawComboChartFlow();
}
}
到了这里,关于Unity中画2D图表(3)——用XChart包绘制复合图表【柱状图 + 折线图】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!