Compare commits

...

15 Commits

Author SHA1 Message Date
智能大石头 e2f76c5cf2 time 类型的坐标轴是“连续型”坐标轴(基于时间戳),它不依赖 xAxis.data,而是从 series 数据中自动提取时间信息 来决定坐标轴的刻度和范围。 2025-07-28 15:11:48 +08:00
智能大石头 4fe3c4fc3c 新增Legend,改进箱线图和K线图 2025-07-28 13:51:30 +08:00
智能大石头 2f598ea2f1 新增K线图示例 2025-07-28 11:18:27 +08:00
智能大石头 bb960cc5cb 优化箱线图展示,可以自定义5个名字 2025-07-28 10:49:07 +08:00
智能大石头 55cd18109c [feat] 新增自定义系列 2025-07-28 10:06:45 +08:00
智能大石头 b421e77c0c [feat] 新增日历坐标系 Calendar 2025-07-28 10:01:55 +08:00
智能大石头 8329425fe3 [feat] 新增主题河流,SeriesThemeRiver 2025-07-28 09:56:42 +08:00
智能大石头 fab1c49130 [feat] 新增SeriesPictorialBar,象形柱图 2025-07-28 09:54:01 +08:00
智能大石头 bc7133c675 [feat] 新增平行坐标系 SeriesParallel 2025-07-28 09:51:01 +08:00
智能大石头 075be44173 [feat] 新增地图SeriesMap 2025-07-28 09:45:21 +08:00
智能大石头 d961be2bc4 [feat] 增加K线图 SeriesCandlestick 2025-07-28 09:36:35 +08:00
智能大石头 bde8400a48 增加SeriesScatter气泡散点图 2025-07-28 09:32:55 +08:00
大石头 d2da01d56e [feat] 增加箱线图 2025-07-27 18:27:28 +08:00
大石头 d77cb4e522 本地地址不允许跳转 2025-07-27 17:29:51 +08:00
大石头 2f96210a70 完善ECharts系列图类型,优化系列图的创建 2025-07-27 17:15:41 +08:00
33 changed files with 4285 additions and 49 deletions

View File

@ -1,4 +1,5 @@
using NewLife.Cube.Charts;
using NewLife.Cube.Charts.Models;
using NewLife.Cube.Entity;
using NewLife.Web;
using XCode.Membership;
@ -58,6 +59,19 @@ public class UserStatController : ReadOnlyEntityController<UserStat>
""");
chart.SetToolbox();
var chart2 = new ECharts();
chart2.SetX(list2, "Date", e => e.Date.ToString("MM-dd"));
chart2.AddBoxplot("用户箱线(仅用于演示)",
list2.Select(e => new BoxplotItem(e.News, e.Actives, e.NewsT7, e.ActivesT7, e.NewsT30)),
["新用户", "今日活跃", "7天注册", "7天活跃", "30天注册"]);
var chart3 = new ECharts();
chart3.SetX(list2, "Date", e => e.Date.ToString("MM-dd"));
chart3.AddCandlestick("用户K线仅用于演示",
list2.Select(e => new CandlestickItem(e.Actives, e.NewsT7, e.News, e.ActivesT7)));
ViewBag.Charts2 = new[] { chart2, chart3 };
}
return list;

View File

@ -0,0 +1,138 @@
namespace NewLife.Cube.Charts;
/// <summary>日历坐标系组件</summary>
/// <remark>
/// 在ECharts中我们非常有创意地实现了日历图是通过使用日历坐标系组件来达到日历图效果的如下方的几个示例图所示我们可以在热力图、散点图、关系图中使用日历坐标系。
/// 在日历坐标系中使用热力图的示例:
/// 在日历坐标系中使用散点图的示例:
/// 在日历坐标系中使用关系图(以及混合图表)的示例:
/// 灵活利用 echarts 图表和坐标系的组合,以及 API可以实现更丰富的效果。
/// 在日历中使用文字、
/// 在日历中放置饼图
/// 水平和垂直放置日历
/// 在日历坐标系可以水平放置,也可以垂直放置。如上面的例子,使用热力图时,经常是水平放置的。但是如果需要格子的尺寸大些,水平放置就过于宽了,于是也可以选择垂直放置。参见 calendar.orient。
/// 尺寸的自适应
/// 可以设置日历坐标系使他支持不同尺寸的容器(页面)大小变化的自适应。首先,和 echarts 其他组件一样,日历坐标系可以选择使用 left right top bottom width height 来描述尺寸和位置,从而将日历摆放在上下左右各种位置,并随着页面尺寸变动而改变自身尺寸。另外,也可以使用 cellSize 来固定日历格子的长宽。
/// 中西方日历习惯的支持
/// 中西方日历有所差别,西方常使用星期日作为一周的第一天,中国使用星期一为一周的第一天。日历坐标系做了这种切换的支持。参见 calendar.dayLabel.firstDay。
/// 另外,日历上的『月份』和『星期几』的文字,也可以较方便的切换中英文,甚至自定义。参见 calendar.dayLabel.nameMap calendar.monthLabel.nameMap。
/// </remark>
public class Calendar
{
/// <summary>组件 ID</summary>
/// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
public String Id { get; set; }
/// <summary>所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>calendar组件离容器左侧的距离</summary>
/// <remark>
/// left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'left', 'center', 'right'。
/// 如果 left 的值为 'left', 'center', 'right',组件会根据相应的位置自动对齐。
/// </remark>
public Object Left { get; set; }
/// <summary>calendar组件离容器上侧的距离</summary>
/// <remark>
/// top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'top', 'middle', 'bottom'。
/// 如果 top 的值为 'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
/// </remark>
public Object Top { get; set; }
/// <summary>calendar组件离容器右侧的距离</summary>
/// <remark>
/// right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
/// 默认自适应。
/// </remark>
public Object Right { get; set; }
/// <summary>calendar组件离容器下侧的距离</summary>
/// <remark>
/// bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
/// 默认自适应。
/// </remark>
public Object Bottom { get; set; }
/// <summary></summary>
/// <remark>
/// 日历坐标的整体宽度
/// 注意: 默认cellSize 为20若设置了width的值, 则cellSize中的宽度强制转为auto;
/// </remark>
public Object Width { get; set; }
/// <summary>日历坐标的整体高度</summary>
/// <remark>注意: 默认cellSize 为20若设置了height的值, 则cellSize中的高度强制转为auto;</remark>
public Object Height { get; set; }
/// <summary>必填</summary>
/// <remark>
/// 日历坐标的范围 支持多种格式
/// 使用示例:
/// // 某一年
/// range: 2017
/// // 某个月
/// range: '2017-02'
/// // 某个区间
/// range: ['2017-01-02', '2017-02-23']
/// // 注意 此写法会识别为['2017-01-01', '2017-02-01']
/// range: ['2017-01', '2017-02']
/// </remark>
public Object Range { get; set; }
/// <summary></summary>
/// <remark>
/// 日历每格框的大小,可设置单值 或数组 第一个元素是宽 第二个元素是高。
/// 支持设置自适应auto, 默认为高宽均为20
/// 使用示例:
/// // 设置宽高均为20
/// cellSize: 20
/// // 设置宽为20高为40
/// cellSize: [20, 40]
/// // 设置宽高均为40
/// cellSize: [40]
/// // 设置宽高均自适应
/// cellSize: 'auto'
/// // 设置宽自适应高为40
/// cellSize: ['auto', 40]
/// </remark>
public Object CellSize { get; set; }
/// <summary>日历坐标的布局朝向</summary>
/// <remark>
/// 可选:
/// 'horizontal'
/// 'vertical'
/// </remark>
public String Orient { get; set; }
/// <summary>设置日历坐标分隔线的样式</summary>
public Object SplitLine { get; set; }
/// <summary>设置日历格的样式</summary>
public Object ItemStyle { get; set; }
/// <summary>设置日历坐标中 星期轴的样式</summary>
public Object DayLabel { get; set; }
/// <summary>设置日历坐标中 月份轴的样式</summary>
public Object MonthLabel { get; set; }
/// <summary>设置日历坐标中 年的样式</summary>
public Object YearLabel { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
}

View File

@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Web.Script.Serialization;
using NewLife.Collections;
using NewLife.Cube.Charts.Models;
@ -7,6 +8,7 @@ using NewLife.Data;
using NewLife.Reflection;
using NewLife.Security;
using NewLife.Serialization;
using NewLife.Web;
using XCode.Configuration;
namespace NewLife.Cube.Charts;
@ -41,7 +43,7 @@ public class ECharts : IExtend
/// <summary>图例组件。</summary>
/// <remarks>图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。</remarks>
public Object Legend { get; set; }
public Legend Legend { get; set; }
/// <summary>X轴</summary>
public IList<XAxis> XAxis { get; set; } = [];
@ -52,6 +54,9 @@ public class ECharts : IExtend
/// <summary>工具箱</summary>
public Toolbox Toolbox { get; set; }
/// <summary>日历坐标系</summary>
public Calendar Calendar { get; set; }
/// <summary>数据缩放</summary>
public DataZoom[] DataZoom { get; set; }
@ -87,7 +92,7 @@ public class ECharts : IExtend
public XAxis SetX(IEnumerable<Object> data)
{
var axis = new XAxis { Data = data.ToArray() };
XAxis.Add(axis);
XAxis = [axis];
return axis;
}
@ -102,7 +107,7 @@ public class ECharts : IExtend
{
Data = list.Select(e => selector == null ? e[name] + "" : selector(e)).ToArray()
};
XAxis.Add(axis);
XAxis = [axis];
_xField = name;
@ -121,13 +126,16 @@ public class ECharts : IExtend
Type = "time",
};
//if (name.EndsWithIgnoreCase("Date")) axis.AxisLabel = new { formatter = "{yyyy}-{MM}-{dd}" };
XAxis.Add(axis);
XAxis = [axis];
_timeField = name;
_xField = name;
if (selector != null)
_timeSelector = e => selector(e as T) + "";
// time 类型的坐标轴是“连续型”坐标轴(基于时间戳),它不依赖 xAxis.data而是从 series 数据中自动提取时间信息 来决定坐标轴的刻度和范围。
//axis.Data = list.Select(GetTimeValue).ToArray();
if (Symbol.IsNullOrEmpty() && list.Count > 100) Symbol = "none";
return axis;
@ -177,7 +185,7 @@ public class ECharts : IExtend
public YAxis SetY(String name, String type = "value")
{
var axis = new YAxis { Name = name, Type = type };
YAxis.Add(axis);
YAxis = [axis];
return axis;
}
@ -194,7 +202,7 @@ public class ECharts : IExtend
public YAxis SetY(String name, String type, String formatter)
{
var axis = new YAxis { Name = name, Type = type, AxisLabel = new { formatter } };
YAxis.Add(axis);
YAxis = [axis];
return axis;
}
@ -288,7 +296,7 @@ public class ECharts : IExtend
var p2 = formatterScript.IndexOf('(', p);
if (p2 < 0) throw new ArgumentOutOfRangeException(nameof(formatterScript), "无效js函数");
var name = formatterScript.Substring(p, p2 - p).Trim();
var name = formatterScript[p..p2].Trim();
var tooltip = new Tooltip
{
@ -301,13 +309,17 @@ public class ECharts : IExtend
return Tooltip = tooltip;
}
/// <summary>设置提示</summary>
/// <summary>设置图例</summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="field"></param>
/// <param name="selector"></param>
public void SetLegend<T>(IList<T> list, FieldItem field, Func<T, String> selector = null) where T : IModel
=> Legend = list.Select(e => selector == null ? e[field.Name] + "" : selector(e)).ToArray();
=> Legend = new Legend { Data = list.Select(e => selector == null ? e[field.Name] + "" : selector(e)).ToArray() };
/// <summary>设置图例</summary>
/// <param name="names"></param>
public void SetLegend(String[] names) => Legend = new Legend { Data = names };
/// <summary>设置工具栏</summary>
/// <param name="orient">布局朝向。纵向vertical默认横向horizontal</param>
@ -373,29 +385,37 @@ public class ECharts : IExtend
Series.Add(series);
}
private Series Create(String name, String type, Object[] data = null)
/// <summary>创建系列</summary>
public Series Create(String name, String type, Object[] data = null)
{
if (type.IsNullOrEmpty()) type = "line";
var sr = type switch
{
"line" => new SeriesLine { Type = type },
"line3D" => new SeriesLine3D { Type = type },
"lines" => new SeriesLines { Type = type },
"lines3D" => new SeriesLines3D { Type = type },
"bar" => new SeriesBar { Type = type },
"bar3D" => new SeriesBar3D { Type = type },
"pie" => new SeriesPie { Type = type },
"graph" => new SeriesGraph { Type = type },
"effectScatter" => new SeriesEffectScatter { Type = type },
"boxplot" => new SeriesBoxplot { Type = type },
"scatter" => new SeriesScatter { Type = type },
"map" => new SeriesMap { Type = type },
"candlestick" => new SeriesCandlestick { Type = type },
"radar" => new SeriesRadar { Type = type },
"funnel" => new SeriesFunnel { Type = type },
"gauge" => new SeriesGauge { Type = type },
"boxplot" => new SeriesBoxplot { Type = type },
"heatmap" => new SeriesHeatmap { Type = type },
"sunburst" => new SeriesSunburst { Type = type },
"graph" => new SeriesGraph { Type = type },
"lines" => new SeriesLines { Type = type },
"tree" => new SeriesTree { Type = type },
"treemap" => new SeriesTreemap { Type = type },
"sunburst" => new SeriesSunburst { Type = type },
"parallel" => new SeriesParallel { Type = type },
"sankey" => new SeriesSankey { Type = type },
"funnel" => new SeriesFunnel { Type = type },
"gauge" => new SeriesGauge { Type = type },
"pictorialBar" => new SeriesPictorialBar { Type = type },
"themeRiver" => new SeriesThemeRiver { Type = type },
"custom" => new SeriesCustom { Type = type },
"line3D" => new SeriesLine3D { Type = type },
"lines3D" => new SeriesLines3D { Type = type },
"bar3D" => new SeriesBar3D { Type = type },
"effectScatter" => new SeriesEffectScatter { Type = type },
_ => new Series { Type = type },
};
sr.Name = name;
@ -404,6 +424,48 @@ public class ECharts : IExtend
return sr;
}
/// <summary>创建系列图</summary>
/// <param name="name"></param>
/// <param name="type"></param>
/// <param name="data"></param>
/// <returns></returns>
public Series Create(String name, SeriesTypes type, Object[] data = null)
{
var sr = type switch
{
SeriesTypes.Line => new SeriesLine(),
SeriesTypes.Bar => new SeriesBar(),
SeriesTypes.Pie => new SeriesPie(),
SeriesTypes.Scatter => new SeriesScatter(),
SeriesTypes.Map => new SeriesMap(),
SeriesTypes.Candlestick => new SeriesCandlestick(),
SeriesTypes.Radar => new SeriesRadar(),
SeriesTypes.Boxplot => new SeriesBoxplot(),
SeriesTypes.Heatmap => new SeriesHeatmap(),
SeriesTypes.Graph => new SeriesGraph(),
SeriesTypes.Lines => new SeriesLines(),
SeriesTypes.Tree => new SeriesTree(),
SeriesTypes.Treemap => new SeriesTreemap(),
SeriesTypes.Sunburst => new SeriesSunburst(),
SeriesTypes.Parallel => new SeriesParallel(),
SeriesTypes.Sankey => new SeriesSankey(),
SeriesTypes.Funnel => new SeriesFunnel(),
SeriesTypes.Gauge => new SeriesGauge(),
SeriesTypes.PictorialBar => new SeriesPictorialBar(),
SeriesTypes.ThemeRiver => new SeriesThemeRiver(),
SeriesTypes.Custom => new SeriesCustom(),
SeriesTypes.Line3D => new SeriesLine3D(),
SeriesTypes.Lines3D => new SeriesLines3D(),
SeriesTypes.Bar3D => new SeriesBar3D(),
SeriesTypes.EffectScatter => new SeriesEffectScatter(),
_ => new Series { Type = type.ToString().ToLower() },
};
sr.Name = name;
sr.Data = data;
return sr;
}
/// <summary>添加系列数据</summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">实体列表</param>
@ -464,7 +526,7 @@ public class ECharts : IExtend
list.Select(e => new Object[] { GetTimeValue(e), selector == null ? e[field.Name] : selector(e) }).ToArray() :
list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray();
var sr = Create(field?.DisplayName ?? field.Name, type.ToString().ToLower(), data);
var sr = Create(field?.DisplayName ?? field.Name, type, data);
if (!Symbol.IsNullOrEmpty()) sr.Symbol = Symbol;
@ -497,7 +559,7 @@ public class ECharts : IExtend
list.Select(e => new Object[] { GetTimeValue(e), selector == null ? e[field.Name] : selector(e) }).ToArray() :
list.Select(e => selector == null ? e[field.Name] : selector(e)).ToArray();
series = Create(field?.DisplayName ?? field.Name, type.ToString().ToLower(), data);
series = Create(field?.DisplayName ?? field.Name, type, data);
if (!Symbol.IsNullOrEmpty()) series.Symbol = Symbol;
@ -638,16 +700,16 @@ public class ECharts : IExtend
return sr;
}
/// <summary>添加。有向图/引力图</summary>
/// <summary>添加关系图。有向图/引力图</summary>
/// <param name="model"></param>
/// <returns></returns>
public Series AddGraph(GraphViewModel model)
{
var graph = Create(model.Title, "graph");
graph["Layout"] = model.Layout;
var graph = Create(model.Title, SeriesTypes.Graph) as SeriesGraph;
graph.Layout = model.Layout;
if (model.Layout == "force")
{
graph["Force"] = new
graph.Force = new
{
initLayout = "circular",
Repulsion = 300,
@ -658,21 +720,109 @@ public class ECharts : IExtend
};
}
graph["edgeSymbol"] = new[] { "circle", "arrow" };
graph["edgeSymbolSize"] = new[] { 4, 10 };
graph["roam"] = true;
graph["label"] = new { show = true, position = "right" };
graph["labelLayout"] = new { hideOverlap = true, moveOverlap = true };
graph["lineStyle"] = new { color = "target", curveness = 0.3, opacity = 0.8, width = 3 };
graph.EdgeSymbol = new[] { "circle", "arrow" };
graph.EdgeSymbolSize = new[] { 4, 10 };
graph.Roam = true;
graph.Label = new { show = true, position = "right" };
graph.LabelLayout = new { hideOverlap = true, moveOverlap = true };
graph.LineStyle = new { color = "target", curveness = 0.3, opacity = 0.8, width = 3 };
graph.Data = model.Nodes;
graph["links"] = model.Links;
graph["categories"] = model.Categories;
graph.Links = model.Links;
graph.Categories = model.Categories;
Legend = new { Data = model.Categories.Select(e => e.Name).ToArray() };
Legend = new Legend { Data = model.Categories.Select(e => new { e.Name, Icon = e.Symbol }).ToArray() };
return graph;
}
/// <summary>添加箱线图</summary>
/// <param name="name">图例名称</param>
/// <param name="items">数据集</param>
/// <param name="itemNames">五个名字。不一定是最小值最大值</param>
/// <returns></returns>
public Series AddBoxplot(String name, IEnumerable<BoxplotItem> items, String[] itemNames = null)
{
var box = Create(!name.IsNullOrEmpty() ? name : "boxplot", SeriesTypes.Boxplot) as SeriesBoxplot;
box.Data = items.Select(e => new[] { e.Min, e.Q1, e.Median, e.Q3, e.Max }).ToArray();
Add(box);
if (!name.IsNullOrEmpty()) SetLegend([name]);
//// 绘制平均线和最大最小值
//box.SetMarkLine(true);
//box.SetMarkPoint(true, true);
var script = """
function boxplotFormatter(params) {
return `${params.name}<br/>
: ${params.value[1]}<br/>
: ${params.value[2]}<br/>
: ${params.value[3]}<br/>
: ${params.value[4]}<br/>
: ${params.value[5]}`;
}
""";
if (itemNames != null && itemNames.Length >= 5)
{
// 名称为null时表示不替换
if (itemNames[0] != null) script = script.Replace("最小值", itemNames[0]);
if (itemNames[1] != null) script = script.Replace("下四分", itemNames[1]);
if (itemNames[2] != null) script = script.Replace("中位数", itemNames[2]);
if (itemNames[3] != null) script = script.Replace("上四分", itemNames[3]);
if (itemNames[4] != null) script = script.Replace("最大值", itemNames[4]);
}
SetTooltip("item", script);
// 添加Y轴
if (YAxis == null || YAxis.Count == 0) SetY("值", "value");
return box;
}
/// <summary>添加K线图</summary>
/// <param name="name">图例名称</param>
/// <param name="items">数据集</param>
/// <param name="itemNames">四个名字。不一定是最小值最大值</param>
/// <returns></returns>
public Series AddCandlestick(String name, IEnumerable<CandlestickItem> items, String[] itemNames = null)
{
var box = Create(!name.IsNullOrEmpty() ? name : "candlestick", SeriesTypes.Candlestick) as SeriesCandlestick;
box.Data = items.Select(e => new[] { e.Open, e.Close, e.Lowest, e.Highest }).ToArray();
Add(box);
if (!name.IsNullOrEmpty()) SetLegend([name]);
//// 绘制平均线和最大最小值
//box.SetMarkLine(true);
//box.SetMarkPoint(true, true);
var script = """
function candlestickFormatter(params) {
return `${params.name}<br/>
: ${params.value[1]}<br/>
: ${params.value[2]}<br/>
: ${params.value[3]}<br/>
: ${params.value[4]}`;
}
""";
if (itemNames != null && itemNames.Length >= 4)
{
// 名称为null时表示不替换
if (itemNames[0] != null) script = script.Replace("开盘值", itemNames[0]);
if (itemNames[1] != null) script = script.Replace("收盘值", itemNames[1]);
if (itemNames[2] != null) script = script.Replace("最低值", itemNames[2]);
if (itemNames[3] != null) script = script.Replace("最高值", itemNames[3]);
}
SetTooltip("item", script);
// 添加Y轴
if (YAxis == null || YAxis.Count == 0) SetY("值", "value");
return box;
}
#endregion
#region
@ -696,18 +846,18 @@ public class ECharts : IExtend
if (legend == null && series != null && series.Count > 0)
{
if (series.Any(e => e.Type == "line" || e.Type == "bar"))
legend = series.Select(e => e.Name).ToArray();
legend = new Legend { Data = series.Select(e => e.Name).ToArray() };
else if (series.Any(e => e.Type == "pie"))
legend = new { show = true, top = "5%", bottom = "5%", left = "center" };
legend = new Legend { Show = true, Top = "5%", Bottom = "5%", Left = "center" };
}
if (legend != null)
{
if (legend is String str)
legend = new { data = new[] { str } };
else if (legend is String[] ss)
legend = new { data = ss };
//if (legend is String str)
// legend = new { data = new[] { str } };
//else if (legend is String[] ss)
// legend = new { data = ss };
dic[nameof(legend)] = legend;
dic[nameof(legend)] = GetJsonObject(legend);
}
// 网格

View File

@ -0,0 +1,424 @@
namespace NewLife.Cube.Charts;
/// <summary>图例组件</summary>
/// <remark>
/// 图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
/// ECharts 3 中单个 echarts 实例中可以存在多个图例组件,会方便多个图例的布局。
/// 当图例数量过多时,可以使用 滚动图例(垂直) 或 滚动图例水平参见legend.type
/// </remark>
public class Legend
{
/// <summary>图例的类型</summary>
/// <remark>
/// 可选值:
/// 'plain':普通图例。缺省就是普通图例。
/// 'scroll':可滚动翻页的图例。当图例数量较多时可以使用。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// 当使用 'scroll' 时,使用这些设置进行细节配置:
/// legend.scrollDataIndex
/// legend.pageButtonItemGap
/// legend.pageButtonGap
/// legend.pageButtonPosition
/// legend.pageFormatter
/// legend.pageIcons
/// legend.pageIconColor
/// legend.pageIconInactiveColor
/// legend.pageIconSize
/// legend.pageTextStyle
/// legend.animation
/// legend.animationDurationUpdate
/// </remark>
public String Type { get; set; }
/// <summary>组件 ID</summary>
/// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
public String Id { get; set; }
/// <summary>是否显示</summary>
public Boolean? Show { get; set; }
/// <summary>所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>图例组件离容器左侧的距离</summary>
/// <remark>
/// left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'left', 'center', 'right'。
/// 如果 left 的值为 'left', 'center', 'right',组件会根据相应的位置自动对齐。
/// </remark>
public Object Left { get; set; }
/// <summary>图例组件离容器上侧的距离</summary>
/// <remark>
/// top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'top', 'middle', 'bottom'。
/// 如果 top 的值为 'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
/// </remark>
public Object Top { get; set; }
/// <summary>图例组件离容器右侧的距离</summary>
/// <remark>
/// right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
/// 默认自适应。
/// </remark>
public Object Right { get; set; }
/// <summary>图例组件离容器下侧的距离</summary>
/// <remark>
/// bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
/// 默认自适应。
/// </remark>
public Object Bottom { get; set; }
/// <summary>图例组件的宽度</summary>
/// <remark>默认自适应。</remark>
public Object Width { get; set; }
/// <summary>图例组件的高度</summary>
/// <remark>默认自适应。</remark>
public Object Height { get; set; }
/// <summary>图例列表的布局朝向</summary>
/// <remark>
/// 可选:
/// 'horizontal'
/// 'vertical'
/// </remark>
public String Orient { get; set; }
/// <summary>图例标记和文本的对齐</summary>
/// <remark>
/// 默认自动,根据组件的位置和 orient 决定,当组件的 left 值为 'right' 以及纵向布局orient 为 'vertical')的时候为右对齐,即为 'right'。
/// 可选:
/// 'auto'
/// 'left'
/// 'right'
/// </remark>
public String Align { get; set; }
/// <summary></summary>
/// <remark>
/// 图例内边距单位px默认各方向内边距为5接受数组分别设定上右下左边距。
/// 使用示例:
/// // 设置内边距为 5
/// padding: 5
/// // 设置上下的内边距为 5左右的内边距为 10
/// padding: [5, 10]
/// // 分别设置四个方向的内边距
/// padding: [
/// 5, // 上
/// 10, // 右
/// 5, // 下
/// 10, // 左
/// ]
/// </remark>
public Object Padding { get; set; }
/// <summary>图例每项之间的间隔</summary>
/// <remark>横向布局时为水平间隔,纵向布局时为纵向间隔。</remark>
public Double? ItemGap { get; set; }
/// <summary>图例标记的图形宽度</summary>
public Double? ItemWidth { get; set; }
/// <summary>图例标记的图形高度</summary>
public Double? ItemHeight { get; set; }
/// <summary>图例的图形样式</summary>
/// <remark>其属性的取值为 'inherit' 时,表示继承系列中的属性值。</remark>
public Object ItemStyle { get; set; }
/// <summary>图例图形中线的样式,用于诸如折线图图例横线的样式设置</summary>
/// <remark>其属性的取值为 'inherit' 时,表示继承系列中的属性值。</remark>
public Object LineStyle { get; set; }
/// <summary>图形旋转角度,类型为 number | 'inherit'</summary>
/// <remark>如果为 'inherit',表示取系列的 symbolRotate。</remark>
public Object SymbolRotate { get; set; }
/// <summary>用来格式化图例文本,支持字符串模板和回调函数两种形式</summary>
/// <remark>
/// 示例:
/// // 使用字符串模板,模板变量为图例名称 {name}
/// formatter: 'Legend {name}'
/// // 使用回调函数
/// formatter: function (name) {
/// return 'Legend ' + name;
/// }
/// </remark>
public String Formatter { get; set; }
/// <summary>图例选择的模式,控制是否可以通过点击图例改变系列的显示状态</summary>
/// <remark>
/// 默认开启图例选择,可以设成 false 关闭。
/// 除此之外也可以设成 'single' 或者 'multiple' 使用单选或者多选模式。
/// </remark>
public Object SelectedMode { get; set; }
/// <summary>图例关闭时的颜色</summary>
public String InactiveColor { get; set; }
/// <summary>图例关闭时的描边颜色</summary>
public String InactiveBorderColor { get; set; }
/// <summary>图例关闭时的描边粗细</summary>
/// <remark>
/// 如果为 'auto' 表示:如果系列存在描边,则取 2如果系列不存在描边则取 0。
/// 如果为 'inherit' 表示:始终取系列的描边粗细。
/// </remark>
public Object InactiveBorderWidth { get; set; }
/// <summary>图例选中状态表</summary>
/// <remark>
/// 示例:
/// selected: {
/// // 选中'系列1'
/// '系列1': true,
/// // 不选中'系列2'
/// '系列2': false
/// }
/// </remark>
public Object Selected { get; set; }
/// <summary>图例的公用文本样式</summary>
public Object TextStyle { get; set; }
/// <summary>图例的 tooltip 配置,配置项同 tooltip</summary>
/// <remark>
/// 默认不显示,可以在 legend 文字很多的时候对文字做裁剪并且开启 tooltip如下示例
/// legend: {
/// formatter: function (name) {
/// return echarts.format.truncateText(name, 40, '14px Microsoft Yahei', '…');
/// },
/// tooltip: {
/// show: true
/// }
/// }
/// </remark>
public Tooltip Tooltip { get; set; }
/// <summary>图例项的 icon</summary>
/// <remark>
/// ECharts 提供的标记类型包括
/// 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
/// 可以通过 'image://url' 设置为图片,其中 URL 为图片的链接,或者 dataURI。
/// URL 为图片链接例如:
/// 'image://http://example.website/a/b.png'
/// URL 为 dataURI 例如:
/// 'image://data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'
/// 可以通过 'path://' 将图标设置为任意的矢量路径。这种方式相比于使用图片的方式,不用担心因为缩放而产生锯齿或模糊,而且可以设置为任意颜色。路径图形会自适应调整为合适的大小。路径的格式参见 SVG PathData。可以从 Adobe Illustrator 等工具编辑导出。
/// 例如:
/// 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z'
/// </remark>
public String Icon { get; set; }
/// <summary>图例的数据数组</summary>
/// <remark>
/// 数组项通常为一个字符串,每一项代表一个系列的 name如果是饼图也可以是饼图单个数据的 name。图例组件会自动根据对应系列的图形标记symbol来绘制自己的颜色和标记特殊字符串 ''(空字符串)或者 '\n'(换行字符串)用于图例的换行。
/// 如果 data 没有被指定,会自动从当前系列中获取。多数系列会取自 series.name 或者 series.encode 的 seriesName 所指定的维度。如 饼图 and 漏斗图 等会取自 series.data 中的 name。
/// 如果要设置单独一项的样式,也可以把该项写成配置项对象。此时必须使用 name 属性对应表示系列的 name。
/// 示例
/// data: [{
/// name: '系列1',
/// // 强制设置图形为圆。
/// icon: 'circle',
/// // 设置文本为红色
/// textStyle: {
/// color: 'red'
/// }
/// }]
/// </remark>
public Object[] Data { get; set; }
/// <summary>图例背景色,默认透明</summary>
/// <remark>颜色可以使用 RGB 表示,比如 'rgb(128, 128, 128)' ,如果想要加上 alpha 通道,可以使用 RGBA比如 'rgba(128, 128, 128, 0.5)',也可以使用十六进制格式,比如 '#ccc'</remark>
public String BackgroundColor { get; set; }
/// <summary>图例的边框颜色</summary>
/// <remark>支持的颜色格式同 backgroundColor。</remark>
public String BorderColor { get; set; }
/// <summary>图例的边框线宽</summary>
public Double? BorderWidth { get; set; }
/// <summary>圆角半径单位px支持传入数组分别指定 4 个圆角半径</summary>
/// <remark>
/// 如:
/// borderRadius: 5, // 统一设置四个角的圆角大小
/// borderRadius: [5, 5, 0, 0] //(顺时针左上,右上,右下,左下)
/// </remark>
public Object BorderRadius { get; set; }
/// <summary>图形阴影的模糊大小</summary>
/// <remark>
/// 该属性配合 shadowColor,shadowOffsetX, shadowOffsetY 一起设置图形的阴影效果。
/// 示例:
/// {
/// shadowColor: 'rgba(0, 0, 0, 0.5)',
/// shadowBlur: 10
/// }
/// 注意:此配置项生效的前提是,设置了 show: true 以及值不为 transparent 的背景色 backgroundColor。
/// </remark>
public Double? ShadowBlur { get; set; }
/// <summary>阴影颜色</summary>
/// <remark>
/// 支持的格式同color。
/// 注意:此配置项生效的前提是,设置了 show: true。
/// </remark>
public String ShadowColor { get; set; }
/// <summary>阴影水平方向上的偏移距离</summary>
/// <remark>注意:此配置项生效的前提是,设置了 show: true。</remark>
public Double? ShadowOffsetX { get; set; }
/// <summary>阴影垂直方向上的偏移距离</summary>
/// <remark>注意:此配置项生效的前提是,设置了 show: true。</remark>
public Double? ShadowOffsetY { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 图例当前最左上显示项的 dataIndex。
/// setOption 时指定此项的话,可决定当前图例滚动到哪里。
/// 但是,如果仅仅想改变图例翻页,一般并不调用 setOption因为这太重量了仅仅使用 action legendScroll 即可。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public Double? ScrollDataIndex { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 图例控制块中,按钮和页信息之间的间隔。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public Double? PageButtonItemGap { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 图例控制块和图例项之间的间隔。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public Double? PageButtonGap { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 图例控制块的位置。可选值为:
/// 'start':控制块在左或上。
/// 'end':控制块在右或下。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public String PageButtonPosition { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 图例控制块中,页信息的显示格式。默认为 '{current}/{total}',其中 {current} 是当前页号(从 1 开始计数),{total} 是总页数。
/// 如果 pageFormatter 使用函数,须返回字符串,参数为:
/// {
/// current: number
/// total: number
/// }
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public String PageFormatter { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>图例控制块的图标。</remark>
public Object PageIcons { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 翻页按钮的颜色。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public String PageIconColor { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 翻页按钮不激活时(即翻页到头时)的颜色。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public String PageIconInactiveColor { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>
/// 翻页按钮的大小。可以是数字,也可以是数组,如 [10, 3],表示 [宽,高]。
/// 参见 滚动图例(垂直) 或 滚动图例(水平)。
/// </remark>
public Object PageIconSize { get; set; }
/// <summary>legend.type 为 'scroll' 时有效</summary>
/// <remark>图例页信息的文字样式。</remark>
public Object PageTextStyle { get; set; }
/// <summary>图例翻页是否使用动画</summary>
public Boolean? Animation { get; set; }
/// <summary>图例翻页时的动画时长</summary>
public Double? AnimationDurationUpdate { get; set; }
/// <summary>强调重要性</summary>
public Object Emphasis { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 图例组件中的选择器按钮,目前包括“全选”和“反选”两种功能。默认不显示,用户可手动开启,也可以手动配置每个按钮的标题。
/// 使用方式如下:
/// selector: [
/// {
/// // 全选
/// type: 'all',
/// // 可以是任意你喜欢的标题
/// title: '全选'
/// },
/// {
/// // 反选
/// type: 'inverse',
/// // 可以是任意你喜欢的标题
/// title: '反选'
/// }
/// ]
/// // 或
/// selector: true
/// // 或
/// selector: ['all', 'inverse']
/// </remark>
public Object Selector { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 选择器按钮的文本标签样式,默认显示。
/// </remark>
public Object SelectorLabel { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 选择器的位置,可以放在图例的尾部或者头部,对应的值分别为 'end' 和 'start'。默认情况下,图例横向布局的时候,选择器放在图例的尾部;图例纵向布局的时候,选择器放在图例的头部。
/// </remark>
public String SelectorPosition { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 选择器按钮之间的间隔。
/// </remark>
public Double? SelectorItemGap { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 选择器按钮与图例组件之间的间隔。
/// </remark>
public Double? SelectorButtonGap { get; set; }
}

View File

@ -0,0 +1,9 @@
namespace NewLife.Cube.Charts.Models;
/// <summary>箱线图元素</summary>
/// <param name="Min">最小值</param>
/// <param name="Q1">下四分位数</param>
/// <param name="Median">中位数</param>
/// <param name="Q3">上四分位数</param>
/// <param name="Max">最大值</param>
public record BoxplotItem(Double Min, Double Q1, Double Median, Double Q3, Double Max);

View File

@ -0,0 +1,8 @@
namespace NewLife.Cube.Charts.Models;
/// <summary>K线图元素</summary>
/// <param name="Open">开盘值</param>
/// <param name="Close">收盘值</param>
/// <param name="Lowest">最低值</param>
/// <param name="Highest">最高值</param>
public record CandlestickItem(Double Open, Double Close, Double Lowest, Double Highest);

View File

@ -6,6 +6,9 @@
/// </remark>
public class SeriesBar : Series
{
/// <summary>实例化柱状图</summary>
public SeriesBar() => Type = "bar";
//public String Type { get; set; } = "bar";
///// <summary>组件 ID</summary>

View File

@ -7,6 +7,9 @@
/// </remark>
public class SeriesBar3D : Series
{
/// <summary>实例化3D柱状图</summary>
public SeriesBar3D() => Type = "bar3D";
//public String Type { get; set; } = "bar3D";
///// <summary></summary>

View File

@ -8,6 +8,9 @@
/// </remark>
public class SeriesBoxplot : Series
{
/// <summary>实例化箱形图</summary>
public SeriesBoxplot() => Type = "boxplot";
//public String Type { get; set; } = "boxplot";
///// <summary>组件 ID</summary>

View File

@ -0,0 +1,398 @@
namespace NewLife.Cube.Charts;
/// <summary>Candlestick 即我们常说的 K线图</summary>
/// <remark>
/// 在 ECharts3 中,同时支持 'candlestick' 和 'k'这两种 'series.type''k' 会被自动转为 'candlestick')。
/// 示例如下:
/// 关于『涨』『跌』的颜色:
/// 不同国家或地区对于 K线图 的颜色定义不一样可能是『红涨绿跌』或『红涨蓝跌』如大陆、台湾、日本、韩国等可能是『绿涨红跌』如西方国家、香港、新加坡等。K线图也不一定要用红蓝、红绿来表示涨跌也可以是『有色/无色』等表示方法。
/// 默认配置项,采用的是『红涨蓝跌』。如果想更改这个颜色配置,在这些配置项中更改即可:
/// series-candlestick.itemStyle.color阳线填充色即『涨』
/// series-candlestick.itemStyle.color0阴线填充色即『跌』
/// series-candlestick.itemStyle.borderColor阳线边框色即『涨』
/// series-candlestick.itemStyle.borderColor0阴线边框色即『跌』
/// series-candlestick.itemStyle.borderColorDoji十字星边框色即开盘价等于收盘价时候的边框色
/// </remark>
public class SeriesCandlestick : Series
{
/// <summary>实例化K线图</summary>
public SeriesCandlestick() => Type = "candlestick";
//public String Type { get; set; } = "candlestick";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
/// <summary></summary>
/// <remark>
/// 该系列使用的坐标系,可选:
/// 'cartesian2d'
/// 使用二维的直角坐标系(也称笛卡尔坐标系),通过 xAxisIndex, yAxisIndex指定相应的坐标轴组件。
/// </remark>
public String CoordinateSystem { get; set; }
///// <summary>使用的 x 轴的 index在单个图表实例中存在多个 x 轴的时候有用。</summary>
//public Double? XAxisIndex { get; set; }
///// <summary>使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用。</summary>
//public Double? YAxisIndex { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary>是否启用图例 hover 时的联动高亮</summary>
public Boolean? LegendHoverLink { get; set; }
/// <summary></summary>
/// <remark>
/// 布局方式,可选值:
/// 'horizontal':水平排布各个 box。
/// 'vertical':竖直排布各个 box。
/// 默认值根据当前坐标系状况决定:如果 category 轴为横轴,则水平排布;否则竖直排布;如果没有 category 轴则水平排布。
/// </remark>
public String Layout { get; set; }
/// <summary>指定柱宽度</summary>
/// <remark>可以使用绝对数值(如 10或百分比如 '20%',表示 band width 的百分之多少)。默认自适应。</remark>
public Double? BarWidth { get; set; }
/// <summary>指定柱最小宽度</summary>
/// <remark>可以使用绝对数值(如 10或百分比如 '20%',表示 band width 的百分之多少)。默认自适应。</remark>
public Object BarMinWidth { get; set; }
/// <summary>指定柱最大宽度</summary>
/// <remark>可以使用绝对数值(如 10或百分比如 '20%',表示 band width 的百分之多少)。默认自适应。</remark>
public Object BarMaxWidth { get; set; }
/// <summary>K 线图的图形样式</summary>
public Object ItemStyle { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.6.0 开始支持
/// K 线图的高亮状态。
/// </remark>
public Object Emphasis { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.6.0 开始支持
/// K 线图的淡出状态。开启 emphasis.focus 后有效
/// </remark>
public Object Blur { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// K 线图的选中状态。开启 selectedMode 后有效。
/// </remark>
public Object Select { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中模式的配置,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选'single''multiple''series' 分别表示单选,多选以及选择整个系列。
/// 从 v5.3.0 开始支持 'series'。
/// </remark>
public Object SelectedMode { get; set; }
/// <summary></summary>
/// <remark>
/// 是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。
/// 开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。
/// 缺点:优化后不能自定义设置单个数据项的样式。
/// </remark>
public Boolean? Large { get; set; }
/// <summary>开启绘制优化的阈值</summary>
public Double? LargeThreshold { get; set; }
/// <summary></summary>
/// <remark>
/// 渐进式渲染时每一帧绘制图形数量,设为 0 时不启用渐进式渲染,支持每个系列单独配置。
/// 在图中有数千到几千万图形元素的时候一下子把图形绘制出来或者交互重绘的时候可能会造成界面的卡顿甚至假死。ECharts 4 开始全流程支持渐进渲染progressive rendering渲染的时候会把创建好的图形分到数帧中渲染每一帧渲染只渲染指定数量的图形。
/// 该配置项就是用于配置该系列每一帧渲染的图形数,可以根据图表图形复杂度的需要适当调整这个数字使得在不影响交互流畅性的前提下达到绘制速度的最大化。比如在 lines 图或者平行坐标中线宽大于 1 的 polyline 绘制会很慢,这个数字就可以设置小一点,而线宽小于等于 1 的 polyline 绘制非常快,该配置项就可以相对调得比较大。
/// </remark>
public Double? Progressive { get; set; }
/// <summary>启用渐进式渲染的图形数量阈值,在单个系列的图形数量超过该阈值时启用渐进式渲染。</summary>
public Double? ProgressiveThreshold { get; set; }
/// <summary>分片的方式</summary>
/// <remark>
/// 可选值:
/// 'sequential': 按照数据的顺序分片。缺点是渲染过程不自然。
/// 'mod': 取模分片,即每个片段中的点会遍布于整个数据,从而能够视觉上均匀得渲染。
/// </remark>
public String ProgressiveChunkMode { get; set; }
/// <summary></summary>
/// <remark>
/// 使用 dimensions 定义 series.data 或者 dataset.source 的每个维度的信息。
/// 注意:如果使用了 dataset那么可以在 dataset.dimensions 中定义 dimension ,或者在 dataset.source 的第一行/列中给出 dimension 名称。于是就不用在这里指定 dimension。但如果在这里指定了 dimensions那么优先使用这里的。
/// 例如:
/// option = {
/// dataset: {
/// source: [
/// // 有了上面 dimensions 定义后,下面这五个维度的名称分别为:
/// // 'date', 'open', 'close', 'highest', 'lowest'
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// // 定义了每个维度的名称。这个名称会被显示到默认的 tooltip 中。
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest']
/// }
/// }
/// series: {
/// type: 'xxx',
/// dimensions: [
/// null, // 如果此维度不想给出定义,则使用 null 即可
/// {type: 'ordinal'}, // 只定义此维度的类型。
/// // 'ordinal' 表示离散型,一般文本使用这种类型。
/// // 如果类型没有被定义,会自动猜测类型。
/// {name: 'good', type: 'number'},
/// 'bad' // 等同于 {name: 'bad'}
/// ]
/// }
/// dimensions 数组中的每一项可以是:
/// string如 'someName',等同于 {name: 'someName'}
/// Object属性可以有
/// name: string。
/// type: string支持
/// number默认表示普通数据。
/// ordinal对于类目、文本这些 string 类型的数据,如果需要能在数轴上使用,须是 'ordinal' 类型。ECharts 默认会自动判断这个类型。但是自动判断也是不可能很完备的,所以使用者也可以手动强制指定。
/// float即 Float64Array。
/// int即 Int32Array。
/// time表示时间类型。设置成 'time' 则能支持自动解析数据成时间戳timestamp比如该维度的数据是 '2017-05-10',会自动被解析。时间类型的支持参见 data。
/// displayName: 一般用于 tooltip 中维度名的展示。string 如果没有指定,默认使用 name 来展示。
/// 值得一提的是,当定义了 dimensions 后,默认 tooltip 中对个维度的显示,会变为『竖排』,从而方便显示每个维度的名称。如果没有定义 dimensions则默认 tooltip 会横排显示,且只显示数值没有维度名称可显示。
/// </remark>
public Double[] Dimensions { get; set; }
/// <summary>可以定义 data 的哪个维度被编码成什么</summary>
/// <remark>
/// 比如:
/// option = {
/// dataset: {
/// source: [
/// // 每一列称为一个『维度』。
/// // 这里分别是维度 0、1、2、3、4。
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// encode: {
/// x: [3, 1, 5], // 表示维度 3、1、5 映射到 x 轴。
/// y: 2, // 表示维度 2 映射到 y 轴。
/// tooltip: [3, 2, 4] // 表示维度 3、2、4 会在 tooltip 中显示。
/// }
/// }
/// }
/// 当使用 dimensions 给维度定义名称后encode 中可直接引用名称,例如:
/// series: {
/// type: 'xxx',
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest'],
/// encode: {
/// x: 'date',
/// y: ['open', 'close', 'highest', 'lowest']
/// }
/// }
/// encode 声明的基本结构如下,其中冒号左边是坐标系、标签等特定名称,如 'x', 'y', 'tooltip' 等冒号右边是数据中的维度名string 格式或者维度的序号number 格式,从 0 开始计数),可以指定一个或多个维度(使用数组)。通常情况下,下面各种信息不需要所有的都写,按需写即可。
/// 下面是 encode 支持的属性:
/// // 在任何坐标系和系列中,都支持:
/// encode: {
/// // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示
/// tooltip: ['product', 'score']
/// // 使用第一个维度和第三个维度的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)
/// seriesName: [1, 3],
/// // 表示使用第二个维度中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画。
/// itemId: 2,
/// // 指定数据项的名称使用第三个维度在饼图等图表中有用可以使这个名字显示在图例legend中。
/// itemName: 3,
/// // 指定数据项的组 ID (groupId)。当全局过渡动画功能开启时setOption 前后拥有相同 groupId 的数据项会进行动画过渡。
/// itemGroupId: 4,
/// // 指定数据项对应的子数据组 ID (childGroupId),用于实现多层下钻和聚合。详见 childGroupId。
/// // 从 v5.5.0 开始支持
/// itemChildGroupId: 5
/// }
/// // 直角坐标系grid/cartesian特有的属性
/// encode: {
/// // 把 “维度1”、“维度5”、“名为 score 的维度” 映射到 X 轴:
/// x: [1, 5, 'score'],
/// // 把“维度0”映射到 Y 轴。
/// y: 0
/// }
/// // 单轴singleAxis特有的属性
/// encode: {
/// single: 3
/// }
/// // 极坐标系polar特有的属性
/// encode: {
/// radius: 3,
/// angle: 2
/// }
/// // 地理坐标系geo特有的属性
/// encode: {
/// lng: 3,
/// lat: 2
/// }
/// // 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:
/// encode: {
/// value: 3
/// }
/// 这是个更丰富的 encode 的示例:
/// 特殊地,在 自定义系列custom seriesencode 中轴可以不指定或设置为 null/undefined从而使系列免于受这个轴控制也就是说轴的范围extent不会受此系列数值的影响轴被 dataZoom 控制时也不会过滤掉这个系列:
/// var option = {
/// xAxis: {},
/// yAxis: {},
/// dataZoom: [{
/// xAxisIndex: 0
/// }, {
/// yAxisIndex: 0
/// }],
/// series: {
/// type: 'custom',
/// renderItem: function (params, api) {
/// return {
/// type: 'circle',
/// shape: {
/// cx: 100, // x 位置永远为 100
/// cy: api.coord([0, api.value(0)])[1],
/// r: 30
/// },
/// style: {
/// fill: 'blue'
/// }
/// };
/// },
/// encode: {
/// // 这样这个系列就不会被 x 轴以及 x
/// // 轴上的 dataZoom 控制了。
/// x: -1,
/// y: 1
/// },
/// data: [ ... ]
/// }
/// };
/// </remark>
public Object Encode { get; set; }
/// <summary>该系列所有数据项的组 ID优先级低于groupId</summary>
/// <remark>详见series.data.groupId。</remark>
public String DataGroupId { get; set; }
/// <summary>数据格式是如下的二维数组</summary>
/// <remark>
/// [
/// [2320.26, 2320.26, 2287.3, 2362.94],
/// [2300, 2291.3, 2288.26, 2308.38],
/// { // 数据项也可以是 Object从而里面能含有对此数据项的特殊设置。
/// value: [2300, 2291.3, 2288.26, 2308.38],
/// itemStyle: {...}
/// },
/// ...
/// ]
/// 二维数组的每一数组项上例中的每行是渲染一个box它含有四个量值依次是
/// [open, close, lowest, highest] (即:[开盘值, 收盘值, 最低值, 最高值]
/// </remark>
public override Object[] Data { get; set; }
///// <summary>图表标注</summary>
//public Object MarkPoint { get; set; }
///// <summary>图表标线</summary>
//public Object MarkLine { get; set; }
/// <summary>图表标域,常用于标记图表中某个范围的数据,例如标出某段时间投放了广告。</summary>
public Object MarkArea { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.5.0 开始支持
/// 是否裁剪超出坐标系部分的图形,具体裁剪效果根据系列决定:
/// 散点图/带有涟漪特效动画的散点(气泡)图:忽略中心点超出坐标系的图形,但是不裁剪单个图形
/// 柱状图:裁掉完全超出的柱子,但是不会裁剪只超出部分的柱子
/// 折线图:裁掉所有超出坐标系的折线部分,拐点图形的逻辑按照散点图处理
/// 路径图:裁掉所有超出坐标系的部分
/// K 线图:忽略整体都超出坐标系的图形,但是不裁剪单个图形
/// 象形柱图:裁掉所有超出坐标系的部分(从 v5.5.0 开始支持)
/// 自定义系列:裁掉所有超出坐标系的部分
/// 除了象形柱图和自定义系列,其它系列的默认值都为 true及开启裁剪如果你觉得不想要裁剪的话可以设置成 false 关闭。
/// </remark>
public Boolean? Clip { get; set; }
/// <summary>K线图所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>K线图组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
/// <summary>初始动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的初始动画效果:
/// animationDuration: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDuration { get; set; }
/// <summary>初始动画的缓动效果</summary>
/// <remark>不同的缓动效果可以参考 缓动示例。</remark>
public String AnimationEasing { get; set; }
/// <summary></summary>
/// <remark>
/// 初始动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的初始动画效果。
/// 如下示例:
/// animationDelay: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelay { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.2.0 开始支持
/// 全局过渡动画相关的配置。
/// 全局过渡动画Universal Transition提供了任意系列之间进行变形动画的功能。开启该功能后每次setOption相同id的系列之间会自动关联进行动画的过渡更细粒度的关联配置见universalTransition.seriesKey配置。
/// 通过配置数据项的groupId和childGroupId还可以实现诸如下钻聚合等一对多或者多对一的动画。
/// 可以直接在系列中配置 universalTransition: true 开启该功能。也可以提供一个对象进行更多属性的配置。
/// </remark>
public Object UniversalTransition { get; set; }
/// <summary>本系列特定的 tooltip 设定</summary>
public Object Tooltip { get; set; }
}

View File

@ -0,0 +1,644 @@
namespace NewLife.Cube.Charts;
/// <summary>自定义系列</summary>
/// <remark>
/// 自定义系列可以自定义系列中的图形元素渲染。从而能扩展出不同的图表。
/// 同时echarts 会统一管理图形的创建删除、动画、与其他组件(如 dataZoom、visualMap的联动使开发者不必纠结这些细节。
/// 例如,下面的例子使用 custom series 扩展出了 x-range 图:
/// 更多的例子参见custom examples
/// 这里是个教程
/// 开发者自定义渲染逻辑renderItem 函数)
/// custom 系列需要开发者自己提供图形渲染的逻辑。这个渲染逻辑一般命名为 renderItem。例如
/// var option = {
/// ...,
/// series: [{
/// type: 'custom',
/// renderItem: function (params, api) {
/// var categoryIndex = api.value(0);
/// var start = api.coord([api.value(1), categoryIndex]);
/// var end = api.coord([api.value(2), categoryIndex]);
/// var height = api.size([0, 1])[1] * 0.6;
/// var rectShape = echarts.graphic.clipRectByRect({
/// x: start[0],
/// y: start[1] - height / 2,
/// width: end[0] - start[0],
/// height: height
/// }, {
/// x: params.coordSys.x,
/// y: params.coordSys.y,
/// width: params.coordSys.width,
/// height: params.coordSys.height
/// });
/// return rectShape && {
/// type: 'rect',
/// shape: rectShape,
/// style: api.style()
/// };
/// },
/// data: data
/// }]
/// }
/// 对于 data 中的每个数据项(为方便描述,这里称为 dataItem),会调用此 renderItem 函数。
/// renderItem 函数提供了两个参数:
/// params包含了当前数据信息和坐标系的信息。
/// api是一些开发者可调用的方法集合。
/// renderItem 函数须返回根据此 dataItem 绘制出的图形元素的定义信息,参见 renderItem.return。
/// 一般来说renderItem 函数的主要逻辑,是将 dataItem 里的值映射到坐标系上的图形元素。这一般需要用到 renderItem.arguments.api 中的两个函数:
/// api.value(...),意思是取出 dataItem 中的数值。例如 api.value(0) 表示取出当前 dataItem 中第一个维度的数值。
/// api.coord(...),意思是进行坐标转换计算。例如 var point = api.coord([api.value(0), api.value(1)]) 表示 dataItem 中的数值转换成坐标系上的点。
/// 有时候还需要用到 api.size(...) 函数,表示得到坐标系上一段数值范围对应的长度。
/// 返回值中样式的设置可以使用 api.style(...) 函数,他能得到 series.itemStyle 中定义的样式信息以及视觉映射的样式信息。也可以用这种方式覆盖这些样式信息api.style({fill: 'green', stroke: 'yellow'})。
/// 维度的映射encode 和 dimensions 属性)
/// custom 系列往往需要定义 series.encode主要用于指明 data 的哪些维度映射到哪些数轴上。从而echarts 能根据这些维度的值的范围,画出合适的数轴刻度。
/// 同时encode.tooltip 和 encode.label 也可以被指定,指明默认的 tooltip 和 label 显示什么内容。series.dimensions 也可以被指定,指明显示在 tooltip 中的维度名称,或者维度的类型。
/// 例如:
/// series: {
/// type: 'custom',
/// renderItem: function () {
/// ...
/// },
/// encode: {
/// x: [2, 4, 3],
/// y: 1,
/// label: 0,
/// tooltip: [2, 4, 3]
/// }
/// }
/// 与 dataZoom 组件的结合
/// 与 dataZoom 结合使用的时候,常常使用会设置 dataZoom.filterMode 为 'weakFilter',从而让 dataItem 部分超出坐标系边界的时候,不会整体被过滤掉。
/// 关于 dataIndex 和 dataIndexInside 的区别
/// dataIndex 指的 dataItem 在原始数据中的 index。
/// dataIndexInside 指的是 dataItem 在当前数据窗口(参见 dataZoom中的 index。
/// renderItem.arguments.api 中使用的参数都是 dataIndexInside 而非 dataIndex因为从 dataIndex 转换成 dataIndexInside 需要时间开销。
/// Event listener
/// chart.setOption({
/// // ...
/// series: {
/// type: 'custom',
/// renderItem: function () {
/// // ...
/// return {
/// type: 'group',
/// children: [{
/// type: 'circle'
/// // ...
/// }, {
/// type: 'circle',
/// name: 'aaa',
/// // 用户指定的信息,可以在 event handler 访问到。
/// info: 12345,
/// // ...
/// }]
/// };
/// }
/// }
/// });
/// chart.on('click', {element: 'aaa'}, function (params) {
/// // 当 name 为 'aaa' 的图形元素被点击时,此回调被触发。
/// console.log(params.info);
/// });
/// </remark>
public class SeriesCustom : Series
{
/// <summary>实例化自定义系列</summary>
public SeriesCustom() => Type = "custom";
//public String Type { get; set; } = "custom";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary>是否启用图例 hover 时的联动高亮</summary>
public Boolean? LegendHoverLink { get; set; }
/// <summary></summary>
/// <remark>
/// 该系列使用的坐标系,可选:
/// null 或者 'none'
/// 无坐标系。
/// 'cartesian2d'
/// 使用二维的直角坐标系(也称笛卡尔坐标系),通过 xAxisIndex, yAxisIndex指定相应的坐标轴组件。
/// 'polar'
/// 使用极坐标系,通过 polarIndex 指定相应的极坐标组件
/// 'geo'
/// 使用地理坐标系,通过 geoIndex 指定相应的地理坐标系组件。
/// 'calendar'
/// 使用日历坐标系,通过 calendarIndex 指定相应的日历坐标系组件。
/// 'none'
/// 不使用坐标系。
/// </remark>
public String CoordinateSystem { get; set; }
///// <summary>使用的 x 轴的 index在单个图表实例中存在多个 x 轴的时候有用。</summary>
//public Double? XAxisIndex { get; set; }
///// <summary>使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用。</summary>
//public Double? YAxisIndex { get; set; }
/// <summary>使用的极坐标系的 index在单个图表实例中存在多个极坐标系的时候有用。</summary>
public Double? PolarIndex { get; set; }
/// <summary>使用的地理坐标系的 index在单个图表实例中存在多个地理坐标系的时候有用。</summary>
public Double? GeoIndex { get; set; }
/// <summary>使用的日历坐标系的 index在单个图表实例中存在多个日历坐标系的时候有用。</summary>
public Double? CalendarIndex { get; set; }
/// <summary>custom 系列需要开发者自己提供图形渲染的逻辑</summary>
/// <remark>
/// 这个渲染逻辑一般命名为 renderItem。例如
/// var option = {
/// ...,
/// series: [{
/// type: 'custom',
/// renderItem: function (params, api) {
/// var categoryIndex = api.value(0);
/// var start = api.coord([api.value(1), categoryIndex]);
/// var end = api.coord([api.value(2), categoryIndex]);
/// var height = api.size([0, 1])[1] * 0.6;
/// var rectShape = echarts.graphic.clipRectByRect({
/// x: start[0],
/// y: start[1] - height / 2,
/// width: end[0] - start[0],
/// height: height
/// }, {
/// x: params.coordSys.x,
/// y: params.coordSys.y,
/// width: params.coordSys.width,
/// height: params.coordSys.height
/// });
/// return rectShape && {
/// type: 'rect',
/// shape: rectShape,
/// style: api.style()
/// };
/// },
/// data: data
/// }]
/// }
/// 对于 data 中的每个数据项(为方便描述,这里称为 dataItem),会调用此 renderItem 函数。
/// renderItem 函数提供了两个参数:
/// params包含了当前数据信息和坐标系的信息。
/// api是一些开发者可调用的方法集合。
/// renderItem 函数须返回根据此 dataItem 绘制出的图形元素的定义信息,参见 renderItem.return。
/// 一般来说renderItem 函数的主要逻辑,是将 dataItem 里的值映射到坐标系上的图形元素。这一般需要用到 renderItem.arguments.api 中的两个函数:
/// api.value(...),意思是取出 dataItem 中的数值。例如 api.value(0) 表示取出当前 dataItem 中第一个维度的数值。
/// api.coord(...),意思是进行坐标转换计算。例如 var point = api.coord([api.value(0), api.value(1)]) 表示 dataItem 中的数值转换成坐标系上的点。
/// 有时候还需要用到 api.size(...) 函数,表示得到坐标系上一段数值范围对应的长度。
/// 返回值中样式的设置可以使用 api.style(...) 函数,他能得到 series.itemStyle 中定义的样式信息以及视觉映射的样式信息。也可以用这种方式覆盖这些样式信息api.style({fill: 'green', stroke: 'yellow'})。
/// </remark>
public Object RenderItem { get; set; }
/// <summary>图形样式</summary>
public Object ItemStyle { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的视觉引导线配置。
/// </remark>
public Object LabelLine { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的统一布局配置。
/// 该配置项是在每个系列默认的标签布局基础上,统一调整标签的(x, y)位置,标签对齐等属性以实现想要的标签布局效果。
/// 该配置项也可以是一个有如下参数的回调函数
/// // 标签对应数据的 dataIndex
/// dataIndex: number
/// // 标签对应的数据类型,只在关系图中会有 node 和 edge 数据类型的区分
/// dataType?: string
/// // 标签对应的系列的 index
/// seriesIndex: number
/// // 标签显示的文本
/// text: string
/// // 默认的标签的包围盒,由系列默认的标签布局决定
/// labelRect: {x: number, y: number, width: number, height: number}
/// // 默认的标签水平对齐
/// align: 'left' | 'center' | 'right'
/// // 默认的标签垂直对齐
/// verticalAlign: 'top' | 'middle' | 'bottom'
/// // 标签所对应的数据图形的包围盒,可用于定位标签位置
/// rect: {x: number, y: number, width: number, height: number}
/// // 默认引导线的位置,目前只有饼图(pie)和漏斗图(funnel)有默认标签位置
/// // 如果没有该值则为 null
/// labelLinePoints?: number[][]
/// 示例:
/// 将标签显示在图形右侧 10px 的位置,并且垂直居中:
/// labelLayout(params) {
/// return {
/// x: params.rect.x + 10,
/// y: params.rect.y + params.rect.height / 2,
/// verticalAlign: 'middle',
/// align: 'left'
/// }
/// }
/// 根据图形的包围盒尺寸决定文本尺寸
/// labelLayout(params) {
/// return {
/// fontSize: Math.max(params.rect.width / 10, 5)
/// };
/// }
/// </remark>
public Object LabelLayout { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中模式的配置,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选'single''multiple''series' 分别表示单选,多选以及选择整个系列。
/// 从 v5.3.0 开始支持 'series'。
/// </remark>
public Object SelectedMode { get; set; }
/// <summary></summary>
/// <remark>
/// 使用 dimensions 定义 series.data 或者 dataset.source 的每个维度的信息。
/// 注意:如果使用了 dataset那么可以在 dataset.dimensions 中定义 dimension ,或者在 dataset.source 的第一行/列中给出 dimension 名称。于是就不用在这里指定 dimension。但如果在这里指定了 dimensions那么优先使用这里的。
/// 例如:
/// option = {
/// dataset: {
/// source: [
/// // 有了上面 dimensions 定义后,下面这五个维度的名称分别为:
/// // 'date', 'open', 'close', 'highest', 'lowest'
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// // 定义了每个维度的名称。这个名称会被显示到默认的 tooltip 中。
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest']
/// }
/// }
/// series: {
/// type: 'xxx',
/// dimensions: [
/// null, // 如果此维度不想给出定义,则使用 null 即可
/// {type: 'ordinal'}, // 只定义此维度的类型。
/// // 'ordinal' 表示离散型,一般文本使用这种类型。
/// // 如果类型没有被定义,会自动猜测类型。
/// {name: 'good', type: 'number'},
/// 'bad' // 等同于 {name: 'bad'}
/// ]
/// }
/// dimensions 数组中的每一项可以是:
/// string如 'someName',等同于 {name: 'someName'}
/// Object属性可以有
/// name: string。
/// type: string支持
/// number默认表示普通数据。
/// ordinal对于类目、文本这些 string 类型的数据,如果需要能在数轴上使用,须是 'ordinal' 类型。ECharts 默认会自动判断这个类型。但是自动判断也是不可能很完备的,所以使用者也可以手动强制指定。
/// float即 Float64Array。
/// int即 Int32Array。
/// time表示时间类型。设置成 'time' 则能支持自动解析数据成时间戳timestamp比如该维度的数据是 '2017-05-10',会自动被解析。时间类型的支持参见 data。
/// displayName: 一般用于 tooltip 中维度名的展示。string 如果没有指定,默认使用 name 来展示。
/// 值得一提的是,当定义了 dimensions 后,默认 tooltip 中对个维度的显示,会变为『竖排』,从而方便显示每个维度的名称。如果没有定义 dimensions则默认 tooltip 会横排显示,且只显示数值没有维度名称可显示。
/// </remark>
public Double[] Dimensions { get; set; }
/// <summary>可以定义 data 的哪个维度被编码成什么</summary>
/// <remark>
/// 比如:
/// option = {
/// dataset: {
/// source: [
/// // 每一列称为一个『维度』。
/// // 这里分别是维度 0、1、2、3、4。
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// encode: {
/// x: [3, 1, 5], // 表示维度 3、1、5 映射到 x 轴。
/// y: 2, // 表示维度 2 映射到 y 轴。
/// tooltip: [3, 2, 4] // 表示维度 3、2、4 会在 tooltip 中显示。
/// }
/// }
/// }
/// 当使用 dimensions 给维度定义名称后encode 中可直接引用名称,例如:
/// series: {
/// type: 'xxx',
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest'],
/// encode: {
/// x: 'date',
/// y: ['open', 'close', 'highest', 'lowest']
/// }
/// }
/// encode 声明的基本结构如下,其中冒号左边是坐标系、标签等特定名称,如 'x', 'y', 'tooltip' 等冒号右边是数据中的维度名string 格式或者维度的序号number 格式,从 0 开始计数),可以指定一个或多个维度(使用数组)。通常情况下,下面各种信息不需要所有的都写,按需写即可。
/// 下面是 encode 支持的属性:
/// // 在任何坐标系和系列中,都支持:
/// encode: {
/// // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示
/// tooltip: ['product', 'score']
/// // 使用第一个维度和第三个维度的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)
/// seriesName: [1, 3],
/// // 表示使用第二个维度中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画。
/// itemId: 2,
/// // 指定数据项的名称使用第三个维度在饼图等图表中有用可以使这个名字显示在图例legend中。
/// itemName: 3,
/// // 指定数据项的组 ID (groupId)。当全局过渡动画功能开启时setOption 前后拥有相同 groupId 的数据项会进行动画过渡。
/// itemGroupId: 4,
/// // 指定数据项对应的子数据组 ID (childGroupId),用于实现多层下钻和聚合。详见 childGroupId。
/// // 从 v5.5.0 开始支持
/// itemChildGroupId: 5
/// }
/// // 直角坐标系grid/cartesian特有的属性
/// encode: {
/// // 把 “维度1”、“维度5”、“名为 score 的维度” 映射到 X 轴:
/// x: [1, 5, 'score'],
/// // 把“维度0”映射到 Y 轴。
/// y: 0
/// }
/// // 单轴singleAxis特有的属性
/// encode: {
/// single: 3
/// }
/// // 极坐标系polar特有的属性
/// encode: {
/// radius: 3,
/// angle: 2
/// }
/// // 地理坐标系geo特有的属性
/// encode: {
/// lng: 3,
/// lat: 2
/// }
/// // 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:
/// encode: {
/// value: 3
/// }
/// 这是个更丰富的 encode 的示例:
/// 特殊地,在 自定义系列custom seriesencode 中轴可以不指定或设置为 null/undefined从而使系列免于受这个轴控制也就是说轴的范围extent不会受此系列数值的影响轴被 dataZoom 控制时也不会过滤掉这个系列:
/// var option = {
/// xAxis: {},
/// yAxis: {},
/// dataZoom: [{
/// xAxisIndex: 0
/// }, {
/// yAxisIndex: 0
/// }],
/// series: {
/// type: 'custom',
/// renderItem: function (params, api) {
/// return {
/// type: 'circle',
/// shape: {
/// cx: 100, // x 位置永远为 100
/// cy: api.coord([0, api.value(0)])[1],
/// r: 30
/// },
/// style: {
/// fill: 'blue'
/// }
/// };
/// },
/// encode: {
/// // 这样这个系列就不会被 x 轴以及 x
/// // 轴上的 dataZoom 控制了。
/// x: -1,
/// y: 1
/// },
/// data: [ ... ]
/// }
/// };
/// </remark>
public Object Encode { get; set; }
/// <summary></summary>
/// <remark>
/// 当使用 dataset 时seriesLayoutBy 指定了 dataset 中用行还是列对应到系列上,也就是说,系列“排布”到 dataset 的行还是列上。可取值:
/// 'column'默认dataset 的列对应于系列,从而 dataset 中每一列是一个维度dimension
/// 'row'dataset 的行对应于系列,从而 dataset 中每一行是一个维度dimension
/// 参见这个 示例
/// </remark>
public String SeriesLayoutBy { get; set; }
/// <summary></summary>
/// <remark>如果 series.data 没有指定,并且 dataset 存在,那么就会使用 dataset。datasetIndex 指定本系列使用哪个 dataset。</remark>
public Double? DatasetIndex { get; set; }
/// <summary>该系列所有数据项的组 ID优先级低于groupId</summary>
/// <remark>详见series.data.groupId。</remark>
public String DataGroupId { get; set; }
/// <summary>系列中的数据内容数组</summary>
/// <remark>
/// 数组项通常为具体的数据项。
/// 注意,如果系列没有指定 data并且 option 有 dataset那么默认使用第一个 dataset。如果指定了 data则不会再使用 dataset。
/// 可以使用 series.datasetIndex 指定其他的 dataset。
/// 通常来说,数据用一个二维数组表示。如下,每一列被称为一个『维度』。
/// series: [{
/// data: [
/// // 维度X 维度Y 其他维度 ...
/// [ 3.4, 4.5, 15, 43],
/// [ 4.2, 2.3, 20, 91],
/// [ 10.8, 9.5, 30, 18],
/// [ 7.2, 8.8, 18, 57]
/// ]
/// }]
/// 在 直角坐标系 (grid) 中『维度X』和『维度Y』会默认对应于 xAxis 和 yAxis。
/// 在 极坐标系 (polar) 中『维度X』和『维度Y』会默认对应于 radiusAxis 和 angleAxis。
/// 后面的其他维度是可选的,可以在别处被使用,例如:
/// 在 visualMap 中可以将一个或多个维度映射到颜色,大小等多个图形属性上。
/// 在 series.symbolSize 中可以使用回调函数,基于某个维度得到 symbolSize 值。
/// 使用 tooltip.formatter 或 series.label.formatter 可以把其他维度的值展示出来。
/// 特别地当只有一个轴为类目轴axis.type 为 'category')的时候,数据可以简化用一个一维数组表示。例如:
/// xAxis: {
/// data: ['a', 'b', 'm', 'n']
/// },
/// series: [{
/// // 与 xAxis.data 一一对应。
/// data: [23, 44, 55, 19]
/// // 它其实是下面这种形式的简化:
/// // data: [[0, 23], [1, 44], [2, 55], [3, 19]]
/// }]
/// 『值』与 轴类型 的关系:
/// 当某维度对应于数值轴axis.type 为 'value' 或者 'log')的时候:
/// 其值可以为 number例如 12也可以兼容 string 形式的 number例如 '12'
/// 当某维度对应于类目轴axis.type 为 'category')的时候:
/// 其值须为类目的『序数』(从 0 开始)或者类目的『字符串值』。例如:
/// xAxis: {
/// type: 'category',
/// data: ['星期一', '星期二', '星期三', '星期四']
/// },
/// yAxis: {
/// type: 'category',
/// data: ['a', 'b', 'm', 'n', 'p', 'q']
/// },
/// series: [{
/// data: [
/// // xAxis yAxis
/// [ 0, 0, 2 ], // 意思是此点位于 xAxis: '星期一', yAxis: 'a'。
/// [ '星期四', 2, 1 ], // 意思是此点位于 xAxis: '星期四', yAxis: 'm'。
/// [ 2, 'p', 2 ], // 意思是此点位于 xAxis: '星期三', yAxis: 'p'。
/// [ 3, 3, 5 ]
/// ]
/// }]
/// 双类目轴的示例可以参考 Github Punchcard 示例。
/// 当某维度对应于时间轴type 为 'time')的时候,值可以为:
/// 一个时间戳,如 1484141700832表示 UTC 时间。
/// 或者字符串形式的时间描述:
/// ISO 8601 的子集,只包含这些形式(这几种格式,除非指明时区,否则均表示本地时间,与 moment 一致):
/// 部分年月日时间: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06'.
/// 使用 'T' 或空格分割: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123'.
/// 时区设定: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00'.
/// 其他的时间字符串,包括(均表示本地时间):
/// '2012', '2012-3-1', '2012/3/1', '2012/03/01',
/// '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
/// 或者用户自行初始化的 Date 实例:
/// 注意,用户自行初始化 Date 实例的时候,浏览器的行为有差异,不同字符串的表示也不同。
/// 例如:在 chrome 中new Date('2012-01-01') 表示 UTC 时间的 2012 年 1 月 1 日,而 new Date('2012-1-1') 和 new Date('2012/01/01') 表示本地时间的 2012 年 1 月 1 日。在 safari 中,不支持 new Date('2012-1-1') 这种表示方法。
/// 所以,使用 new Date(dataString) 时,可使用第三方库解析(如 moment或者使用 echarts.time.parse或者参见 这里。
/// 当需要对个别数据进行个性化定义时:
/// 数组项可用对象,其中的 value 像表示具体的数值,如:
/// [
/// 12,
/// 34,
/// {
/// value : 56,
/// //自定义标签样式,仅对该数据项有效
/// label: {},
/// //自定义特殊 itemStyle仅对该数据项有效
/// itemStyle:{}
/// },
/// 10
/// ]
/// // 或
/// [
/// [12, 33],
/// [34, 313],
/// {
/// value: [56, 44],
/// label: {},
/// itemStyle:{}
/// },
/// [10, 33]
/// ]
/// 空值:
/// 当某数据不存在时ps不存在不代表值为 0可以用 '-' 或者 null 或者 undefined 或者 NaN 表示。
/// 例如,无数据在折线图中可表现为该点是断开的,在其它图中可表示为图形不存在。
/// </remark>
public override Object[] Data { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 是否裁剪超出坐标系部分的图形,具体裁剪效果根据系列决定:
/// 散点图/带有涟漪特效动画的散点(气泡)图:忽略中心点超出坐标系的图形,但是不裁剪单个图形
/// 柱状图:裁掉完全超出的柱子,但是不会裁剪只超出部分的柱子
/// 折线图:裁掉所有超出坐标系的折线部分,拐点图形的逻辑按照散点图处理
/// 路径图:裁掉所有超出坐标系的部分
/// K 线图:忽略整体都超出坐标系的图形,但是不裁剪单个图形
/// 象形柱图:裁掉所有超出坐标系的部分(从 v5.5.0 开始支持)
/// 自定义系列:裁掉所有超出坐标系的部分
/// 除了象形柱图和自定义系列,其它系列的默认值都为 true及开启裁剪如果你觉得不想要裁剪的话可以设置成 false 关闭。
/// </remark>
public Boolean? Clip { get; set; }
/// <summary>自定义图所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>自定义图组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
/// <summary>是否开启动画</summary>
public Boolean? Animation { get; set; }
/// <summary>是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。</summary>
public Double? AnimationThreshold { get; set; }
/// <summary>初始动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的初始动画效果:
/// animationDuration: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDuration { get; set; }
/// <summary>初始动画的缓动效果</summary>
/// <remark>不同的缓动效果可以参考 缓动示例。</remark>
public String AnimationEasing { get; set; }
/// <summary></summary>
/// <remark>
/// 初始动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的初始动画效果。
/// 如下示例:
/// animationDelay: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelay { get; set; }
/// <summary>数据更新动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的更新动画效果:
/// animationDurationUpdate: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDurationUpdate { get; set; }
/// <summary>数据更新动画的缓动效果</summary>
public String AnimationEasingUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 数据更新动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的更新动画效果。
/// 如下示例:
/// animationDelayUpdate: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelayUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.2.0 开始支持
/// 全局过渡动画相关的配置。
/// 全局过渡动画Universal Transition提供了任意系列之间进行变形动画的功能。开启该功能后每次setOption相同id的系列之间会自动关联进行动画的过渡更细粒度的关联配置见universalTransition.seriesKey配置。
/// 通过配置数据项的groupId和childGroupId还可以实现诸如下钻聚合等一对多或者多对一的动画。
/// 可以直接在系列中配置 universalTransition: true 开启该功能。也可以提供一个对象进行更多属性的配置。
/// </remark>
public Object UniversalTransition { get; set; }
/// <summary>本系列特定的 tooltip 设定</summary>
public Object Tooltip { get; set; }
}

View File

@ -7,6 +7,9 @@
/// </remark>
public class SeriesEffectScatter : Series
{
/// <summary>实例化散点图</summary>
public SeriesEffectScatter() => Type = "effectScatter";
//public String Type { get; set; } = "effectScatter";
///// <summary>组件 ID</summary>

View File

@ -3,6 +3,9 @@
/// <summary>漏斗图</summary>
public class SeriesFunnel : Series
{
/// <summary>实例化漏斗图</summary>
public SeriesFunnel() => Type = "funnel";
//public String Type { get; set; } = "funnel";
///// <summary>组件 ID</summary>

View File

@ -7,6 +7,9 @@
/// </remark>
public class SeriesGauge : Series
{
/// <summary>实例化仪表盘</summary>
public SeriesGauge() => Type = "gauge";
//public String Type { get; set; } = "gauge";
///// <summary>组件 ID</summary>

View File

@ -1,13 +1,15 @@
namespace NewLife.Cube.Charts;
/// <summary></summary>
/// <summary>关系图</summary>
/// <remark>
/// 关系图
/// 用于展现节点以及节点之间的关系数据。
/// 示例:
/// </remark>
public class SeriesGraph : Series
{
/// <summary>实例化关系图</summary>
public SeriesGraph() => Type = "graph";
//public String Type { get; set; } = "graph";
///// <summary>组件 ID</summary>

View File

@ -9,6 +9,9 @@
/// </remark>
public class SeriesHeatmap : Series
{
/// <summary>实例化热力图</summary>
public SeriesHeatmap() => Type = "heatmap";
//public String Type { get; set; } = "heatmap";
///// <summary>组件 ID</summary>

View File

@ -8,6 +8,9 @@
/// </remark>
public class SeriesLine : Series
{
/// <summary>初始化</summary>
public SeriesLine() => Type = "line";
//public String Type { get; set; } = "line";
///// <summary>组件 ID</summary>

View File

@ -4,6 +4,9 @@
/// <remark>可以用于三维直角坐标系 grid3D。</remark>
public class SeriesLine3D : Series
{
/// <summary>实例化三维折线图</summary>
public SeriesLine3D() => Type = "line3D";
//public String Type { get; set; } = "line3D";
///// <summary></summary>

View File

@ -7,6 +7,9 @@
/// </remark>
public class SeriesLines : Series
{
/// <summary>实例化路径图</summary>
public SeriesLines() => Type = "lines";
//public String Type { get; set; } = "lines";
///// <summary>组件 ID</summary>

View File

@ -7,6 +7,9 @@
/// </remark>
public class SeriesLines3D : Series
{
/// <summary>实例化三维飞线图</summary>
public SeriesLines3D() => Type = "lines3D";
//public String Type { get; set; } = "lines3D";
///// <summary></summary>

View File

@ -0,0 +1,377 @@
namespace NewLife.Cube.Charts;
/// <summary>地图</summary>
/// <remark>
/// 地图主要用于地理区域数据的可视化,配合 visualMap 组件用于展示不同区域的人口分布密度等数据。
/// 多个地图类型相同的系列会在同一地图上显示,这时候使用第一个系列的配置项作为地图绘制的配置。
/// Tip: 在 ECharts 3 中不再建议在地图类型的图表使用 markLine 和 markPoint。如果要实现点数据或者线数据的可视化可以使用在地理坐标系组件上的散点图和线图。
/// </remark>
public class SeriesMap : Series
{
/// <summary>实例化地图</summary>
public SeriesMap() => Type = "map";
//public String Type { get; set; }="map";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary>使用 registerMap 注册的地图名称</summary>
/// <remark>
/// geoJSON 引入示例
/// $.get('map/china_geo.json', function (geoJson) {
/// echarts.registerMap('china', {geoJSON: geoJson});
/// var chart = echarts.init(document.getElementById('main'));
/// chart.setOption({
/// series: [{
/// type: 'map',
/// map: 'china',
/// ...
/// }]
/// });
/// });
/// 也参见示例 USA Population Estimates。
/// 如上所示ECharts 可以使用 GeoJSON 格式的数据作为地图的轮廓,你可以获取第三方的 GeoJSON 数据注册到 ECharts 中。例如第三方资源 maps。
/// SVG 引入示例
/// $.get('map/topographic_map.svg', function (svg) {
/// echarts.registerMap('topo', {svg: svg});
/// var chart = echarts.init(document.getElementById('main'));
/// chart.setOption({
/// series: [{
/// type: 'map',
/// map: 'topo',
/// ...
/// }]
/// });
/// });
/// 也参见示例 Beef Cuts。
/// 如上所示ECharts 也可以使用 SVG 格式的地图。详情参见SVG 底图。
/// </remark>
public String Map { get; set; }
/// <summary>是否开启鼠标缩放和平移漫游</summary>
/// <remark>默认不开启。如果只想要开启缩放或者平移,可以设置成 'scale' 或者 'move'。设置成 true 为都开启</remark>
public Object Roam { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.3.0 开始支持
/// 自定义地图投影至少需要提供project, unproject两个方法分别用来计算投影后的坐标以及计算投影前的坐标。
/// 比如墨卡托投影:
/// series: {
/// type: 'map',
/// projection: {
/// project: (point) => [point[0] / 180 * Math.PI, -Math.log(Math.tan((Math.PI / 2 + point[1] / 180 * Math.PI) / 2))],
/// unproject: (point) => [point[0] * 180 / Math.PI, 2 * 180 / Math.PI * Math.atan(Math.exp(point[1])) - 90]
/// }
/// }
/// 除了我们自己实现投影公式,我们也可以使用 d3-geo 等第三方库提供的现成的投影实现:
/// const projection = d3.geoConicEqualArea();
/// // ...
/// series: {
/// type: 'map',
/// projection: {
/// project: (point) => projection(point),
/// unproject: (point) => projection.invert(point)
/// }
/// }
/// 注自定义投影只有在使用GeoJSON作为数据源的时候有用。
/// </remark>
public Object Projection { get; set; }
/// <summary>当前视角的中心点</summary>
/// <remark>
/// 可以是包含两个 number 类型(表示像素值)或 string 类型(表示相对容器的百分比)的数组。
/// 从 5.3.3 版本开始支持 string 类型。
/// 例如:
/// center: [115.97, '30%']
/// </remark>
public Double[] Center { get; set; }
/// <summary></summary>
/// <remark>
/// 这个参数用于 scale 地图的长宽比如果设置了projection则无效。
/// 最终的 aspect 的计算方式是geoBoundingRect.width / geoBoundingRect.height * aspectScale。
/// </remark>
public Double? AspectScale { get; set; }
/// <summary>二维数组,定义定位的左上角以及右下角分别所对应的经纬度</summary>
/// <remark>
/// 例如
/// // 设置为一张完整经纬度的世界地图
/// map: 'world',
/// left: 0, top: 0, right: 0, bottom: 0,
/// boundingCoords: [
/// // 定位左上角经纬度
/// [-180, 90],
/// // 定位右下角经纬度
/// [180, -90]
/// ],
/// </remark>
public Double[] BoundingCoords { get; set; }
/// <summary>当前视角的缩放比例</summary>
public Double? Zoom { get; set; }
/// <summary>滚轮缩放的极限控制,通过 min 和 max 限制最小和最大的缩放值。</summary>
public Object ScaleLimit { get; set; }
/// <summary>自定义地区的名称映射</summary>
/// <remark>
/// 如:
/// {
/// 'China' : '中国'
/// }
/// </remark>
public Object NameMap { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.8.0 开始支持
/// 默认是 'name',针对 GeoJSON 要素的自定义属性名称,作为主键用于关联数据点和 GeoJSON 地理要素。
/// 例如:
/// {
/// nameProperty: 'NAME', // 数据点中的 nameAlabama 会关联到 GeoJSON 中 NAME 属性值为 Alabama 的地理要素{"type":"Feature","id":"01","properties":{"NAME":"Alabama"}, "geometry": { ... }}
/// data:[
/// {name: 'Alabama', value: 4822023},
/// {name: 'Alaska', value: 731449},
/// ]
/// }
/// </remark>
public String NameProperty { get; set; }
/// <summary></summary>
/// <remark>选中模式,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选'single'表示单选,或者'multiple'表示多选。</remark>
public Object SelectedMode { get; set; }
/// <summary>图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。</summary>
public Object Label { get; set; }
/// <summary>地图区域的多边形 图形样式</summary>
public Object ItemStyle { get; set; }
/// <summary>高亮状态下的多边形和标签样式</summary>
public Object Emphasis { get; set; }
/// <summary>选中状态下的多边形和标签样式</summary>
public Object Select { get; set; }
/// <summary>所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>组件离容器左侧的距离</summary>
/// <remark>
/// left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'left', 'center', 'right'。
/// 如果 left 的值为 'left', 'center', 'right',组件会根据相应的位置自动对齐。
/// </remark>
public Object Left { get; set; }
/// <summary>组件离容器上侧的距离</summary>
/// <remark>
/// top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'top', 'middle', 'bottom'。
/// 如果 top 的值为 'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
/// </remark>
public Object Top { get; set; }
/// <summary>组件离容器右侧的距离</summary>
/// <remark>
/// right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
/// 默认自适应。
/// </remark>
public Object Right { get; set; }
/// <summary>组件离容器下侧的距离</summary>
/// <remark>
/// bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。
/// 默认自适应。
/// </remark>
public Object Bottom { get; set; }
/// <summary></summary>
/// <remark>
/// layoutCenter 和 layoutSize 提供了除了 left/right/top/bottom/width/height 之外的布局手段。
/// 在使用 left/right/top/bottom/width/height 的时候,可能很难在保持地图高宽比的情况下把地图放在某个盒形区域的正中间,并且保证不超出盒形的范围。此时可以通过 layoutCenter 属性定义地图中心在屏幕中的位置layoutSize 定义地图的大小。如下示例
/// layoutCenter: ['30%', '30%'],
/// // 如果宽高比大于 1 则宽度为 100如果小于 1 则高度为 100保证了不超过 100x100 的区域
/// layoutSize: 100
/// 设置这两个值后 left/right/top/bottom/width/height 无效。
/// </remark>
public Double[] LayoutCenter { get; set; }
/// <summary>地图的大小,见 layoutCenter</summary>
/// <remark>支持相对于屏幕宽高的百分比或者绝对的像素大小。</remark>
public Object LayoutSize { get; set; }
/// <summary></summary>
/// <remark>
/// 默认情况下map series 会自己生成内部专用的 geo 组件。但是也可以用这个 geoIndex 指定一个 geo 组件。这样的话map 和 其他 series例如散点图就可以共享一个 geo 组件了。并且geo 组件的颜色也可以被这个 map series 控制,从而用 visualMap 来更改。
/// 当设定了 geoIndex 后series-map.map 属性,以及 series-map.itemStyle 等样式配置不再起作用,而是采用 geo 中的相应属性。
/// </remark>
public Double? GeoIndex { get; set; }
/// <summary></summary>
/// <remark>
/// 多个拥有相同地图类型的系列会使用同一个地图展现如果多个系列都在同一个区域有值ECharts 会对这些值统计得到一个数据。这个配置项就是用于配置统计的方式,目前有:
/// 'sum' 取和。
/// 'average' 取平均值。
/// 'max' 取最大值。
/// 'min' 取最小值。
/// </remark>
public String MapValueCalculation { get; set; }
/// <summary></summary>
/// <remark>在图例相应区域显示图例的颜色标识(系列标识的小圆点),存在 legend 组件时生效。</remark>
public Boolean? ShowLegendSymbol { get; set; }
/// <summary></summary>
/// <remark>
/// 当使用 dataset 时seriesLayoutBy 指定了 dataset 中用行还是列对应到系列上,也就是说,系列“排布”到 dataset 的行还是列上。可取值:
/// 'column'默认dataset 的列对应于系列,从而 dataset 中每一列是一个维度dimension
/// 'row'dataset 的行对应于系列,从而 dataset 中每一行是一个维度dimension
/// 参见这个 示例
/// </remark>
public String SeriesLayoutBy { get; set; }
/// <summary></summary>
/// <remark>如果 series.data 没有指定,并且 dataset 存在,那么就会使用 dataset。datasetIndex 指定本系列使用哪个 dataset。</remark>
public Double? DatasetIndex { get; set; }
/// <summary>该系列所有数据项的组 ID优先级低于groupId</summary>
/// <remark>详见series.data.groupId。</remark>
public String DataGroupId { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的统一布局配置。
/// 该配置项是在每个系列默认的标签布局基础上,统一调整标签的(x, y)位置,标签对齐等属性以实现想要的标签布局效果。
/// 该配置项也可以是一个有如下参数的回调函数
/// // 标签对应数据的 dataIndex
/// dataIndex: number
/// // 标签对应的数据类型,只在关系图中会有 node 和 edge 数据类型的区分
/// dataType?: string
/// // 标签对应的系列的 index
/// seriesIndex: number
/// // 标签显示的文本
/// text: string
/// // 默认的标签的包围盒,由系列默认的标签布局决定
/// labelRect: {x: number, y: number, width: number, height: number}
/// // 默认的标签水平对齐
/// align: 'left' | 'center' | 'right'
/// // 默认的标签垂直对齐
/// verticalAlign: 'top' | 'middle' | 'bottom'
/// // 标签所对应的数据图形的包围盒,可用于定位标签位置
/// rect: {x: number, y: number, width: number, height: number}
/// // 默认引导线的位置,目前只有饼图(pie)和漏斗图(funnel)有默认标签位置
/// // 如果没有该值则为 null
/// labelLinePoints?: number[][]
/// 示例:
/// 将标签显示在图形右侧 10px 的位置,并且垂直居中:
/// labelLayout(params) {
/// return {
/// x: params.rect.x + 10,
/// y: params.rect.y + params.rect.height / 2,
/// verticalAlign: 'middle',
/// align: 'left'
/// }
/// }
/// 根据图形的包围盒尺寸决定文本尺寸
/// labelLayout(params) {
/// return {
/// fontSize: Math.max(params.rect.width / 10, 5)
/// };
/// }
/// </remark>
public Object LabelLayout { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的视觉引导线配置。
/// </remark>
public Object LabelLine { get; set; }
/// <summary>地图系列中的数据内容数组</summary>
/// <remark>
/// 数组项可以为单个数值,如:
/// [12, 34, 56, 10, 23]
/// 如果需要在数据中加入其它维度给 visualMap 组件用来映射到颜色等其它图形属性。每个数据项也可以是数组,如:
/// [[12, 14], [34, 50], [56, 30], [10, 15], [23, 10]]
/// 这时候可以将每项数组中的第二个值指定给 visualMap 组件。
/// 更多时候我们需要指定每个数据项的名称,这时候需要每个项为一个对象:
/// [{
/// // 数据项的名称
/// name: '数据1',
/// // 数据项值8
/// value: 10
/// }, {
/// name: '数据2',
/// value: 20
/// }]
/// 需要对个别内容指定进行个性化定义时:
/// [{
/// name: '数据1',
/// value: 10
/// }, {
/// // 数据项名称
/// name: '数据2',
/// value : 56,
/// //自定义特殊 tooltip仅对该数据项有效
/// tooltip:{},
/// //自定义特殊itemStyle仅对该item有效
/// itemStyle:{}
/// }]
/// </remark>
public override Object[] Data { get; set; }
///// <summary>图表标注</summary>
//public Object MarkPoint { get; set; }
///// <summary>图表标线</summary>
//public Object MarkLine { get; set; }
/// <summary>图表标域,常用于标记图表中某个范围的数据,例如标出某段时间投放了广告。</summary>
public Object MarkArea { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.2.0 开始支持
/// 全局过渡动画相关的配置。
/// 全局过渡动画Universal Transition提供了任意系列之间进行变形动画的功能。开启该功能后每次setOption相同id的系列之间会自动关联进行动画的过渡更细粒度的关联配置见universalTransition.seriesKey配置。
/// 通过配置数据项的groupId和childGroupId还可以实现诸如下钻聚合等一对多或者多对一的动画。
/// 可以直接在系列中配置 universalTransition: true 开启该功能。也可以提供一个对象进行更多属性的配置。
/// </remark>
public Object UniversalTransition { get; set; }
/// <summary>本系列特定的 tooltip 设定</summary>
public Object Tooltip { get; set; }
}

View File

@ -0,0 +1,266 @@
using System;
using System.Collections.Generic;
namespace NewLife.Cube.Charts;
/// <summary>平行坐标系的系列</summary>
/// <remark>
/// 平行坐标系介绍
/// 平行坐标系Parallel Coordinates 是一种常用的可视化高维数据的图表。
/// 例如 series-parallel.data 中有如下数据:
/// [
/// [1, 55, 9, 56, 0.46, 18, 6, '良'],
/// [2, 25, 11, 21, 0.65, 34, 9, '优'],
/// [3, 56, 7, 63, 0.3, 14, 5, '良'],
/// [4, 33, 7, 29, 0.33, 16, 6, '优'],
/// { // 数据项也可以是 Object从而里面能含有对线条的特殊设置。
/// value: [5, 42, 24, 44, 0.76, 40, 16, '优']
/// lineStyle: {...},
/// }
/// ...
/// ]
/// 数据中,每一行是一个『数据项』,每一列属于一个『维度』。(例如上面数据每一列的含义分别是:『日期』,『AQI指数』, 『PM2.5』, 『PM10』, 『一氧化碳值』, 『二氧化氮值』, 『二氧化硫值』)。
/// 平行坐标系适用于对这种多维数据进行可视化分析。每一个维度(每一列)对应一个坐标轴,每一个『数据项』是一条线,贯穿多个坐标轴。在坐标轴上,可以进行数据选取等操作。如下:
/// 配置方式概要
/// 『平行坐标系』的 option 基本配置如下例:
/// option = {
/// parallelAxis: [ // 这是一个个『坐标轴』的定义
/// {dim: 0, name: schema[0].text}, // 每个『坐标轴』有个 'dim' 属性,表示坐标轴的维度号。
/// {dim: 1, name: schema[1].text},
/// {dim: 2, name: schema[2].text},
/// {dim: 3, name: schema[3].text},
/// {dim: 4, name: schema[4].text},
/// {dim: 5, name: schema[5].text},
/// {dim: 6, name: schema[6].text},
/// {dim: 7, name: schema[7].text,
/// type: 'category', // 坐标轴也可以支持类别型数据
/// data: ['优', '良', '轻度污染', '中度污染', '重度污染', '严重污染']
/// }
/// ],
/// parallel: { // 这是『坐标系』的定义
/// left: '5%', // 平行坐标系的位置设置
/// right: '13%',
/// bottom: '10%',
/// top: '20%',
/// parallelAxisDefault: { // 『坐标轴』的公有属性可以配置在这里避免重复书写
/// type: 'value',
/// nameLocation: 'end',
/// nameGap: 20
/// }
/// },
/// series: [ // 这里三个系列共用一个平行坐标系
/// {
/// name: '北京',
/// type: 'parallel', // 这个系列类型是 'parallel'
/// data: [
/// [1, 55, 9, 56, 0.46, 18, 6, '良'],
/// [2, 25, 11, 21, 0.65, 34, 9, '优'],
/// ...
/// ]
/// },
/// {
/// name: '上海',
/// type: 'parallel',
/// data: [
/// [3, 56, 7, 63, 0.3, 14, 5, '良'],
/// [4, 33, 7, 29, 0.33, 16, 6, '优'],
/// ...
/// ]
/// },
/// {
/// name: '广州',
/// type: 'parallel',
/// data: [
/// [4, 33, 7, 29, 0.33, 16, 6, '优'],
/// [5, 42, 24, 44, 0.76, 40, 16, '优'],
/// ...
/// ]
/// }
/// ]
/// };
/// 需要涉及到三个组件parallel、parallelAxis、series-parallel
/// parallel
/// 这个配置项是平行坐标系的『坐标系』本身。一个系列series或多个系列如上图中的『北京』、『上海』、『广州』分别各是一个系列可以共用这个『坐标系』。
/// 和其他坐标系一样,坐标系也可以创建多个。
/// 位置设置,也是放在这里进行。
/// parallelAxis
/// 这个是『坐标系』中的坐标轴的配置。自然,需要有多个坐标轴。
/// 其中有 parallelAxis.parallelIndex 属性,指定这个『坐标轴』在哪个『坐标系』中。默认使用第一个『坐标系』。
/// series-parallel
/// 这个是『系列』的定义。系列被画到『坐标系』上。
/// 其中有 series-parallel.parallelIndex 属性,指定使用哪个『坐标系』。默认使用第一个『坐标系』。
/// 配置注意和最佳实践
/// 配置多个 parallelAxis 时,有些值一样的属性,如果书写多遍则比较繁琐,那么可以放置在 parallel.parallelAxisDefault 里。在坐标轴初始化前parallel.parallelAxisDefault 里的配置项,会分别融合进 parallelAxis形成最终的坐标轴的配置。
/// 如果数据量很大并且发生卡顿
/// 建议把 series-parallel.lineStyle.width 设为 0.5(或更小),
/// 可能显著改善性能。
/// 高维数据的显示
/// 维度比较多时,比如有 50+ 的维度,那么就会有 50+ 个轴。那么可能会页面显示不下。
/// 可以通过 parallel.axisExpandable 来改善显示效果。
/// </remark>
public class SeriesParallel : Series
{
/// <summary>实例化平行坐标系</summary>
public SeriesParallel() => Type = "parallel";
//public String Type { get; set; }="parallel";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
/// <summary></summary>
/// <remark>
/// 该系列使用的坐标系,可选:
/// 'parallel'
/// 使用平行坐标系,通过 parallelIndex 指定相应的平行坐标系组件。
/// </remark>
public String CoordinateSystem { get; set; }
/// <summary>使用的平行坐标系的 index在单个图表实例中存在多个平行坐标系的时候有用。</summary>
public Double? ParallelIndex { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary>线条样式</summary>
public Object LineStyle { get; set; }
/// <summary></summary>
public Object Emphasis { get; set; }
/// <summary>框选时,未被选中的条线会设置成这个『透明度』(从而可以达到变暗的效果)。</summary>
public Double? InactiveOpacity { get; set; }
/// <summary>框选时,选中的条线会设置成这个『透明度』(从而可以达到高亮的效果)。</summary>
public Double? ActiveOpacity { get; set; }
/// <summary>是否实时刷新</summary>
public Boolean? Realtime { get; set; }
/// <summary>是否使用平滑曲线</summary>
/// <remark>默认为 false可以设置为 true 或者一个范围为 0 到 1 的小数值,指定平滑程度。</remark>
public Object Smooth { get; set; }
/// <summary></summary>
/// <remark>
/// 渐进式渲染时每一帧绘制图形数量,设为 0 时不启用渐进式渲染,支持每个系列单独配置。
/// 在图中有数千到几千万图形元素的时候一下子把图形绘制出来或者交互重绘的时候可能会造成界面的卡顿甚至假死。ECharts 4 开始全流程支持渐进渲染progressive rendering渲染的时候会把创建好的图形分到数帧中渲染每一帧渲染只渲染指定数量的图形。
/// 该配置项就是用于配置该系列每一帧渲染的图形数,可以根据图表图形复杂度的需要适当调整这个数字使得在不影响交互流畅性的前提下达到绘制速度的最大化。比如在 lines 图或者平行坐标中线宽大于 1 的 polyline 绘制会很慢,这个数字就可以设置小一点,而线宽小于等于 1 的 polyline 绘制非常快,该配置项就可以相对调得比较大。
/// </remark>
public Double? Progressive { get; set; }
/// <summary>启用渐进式渲染的图形数量阈值,在单个系列的图形数量超过该阈值时启用渐进式渲染。</summary>
public Double? ProgressiveThreshold { get; set; }
/// <summary>分片的方式</summary>
/// <remark>
/// 可选值:
/// 'sequential': 按照数据的顺序分片。缺点是渲染过程不自然。
/// 'mod': 取模分片,即每个片段中的点会遍布于整个数据,从而能够视觉上均匀得渲染。
/// </remark>
public String ProgressiveChunkMode { get; set; }
/// <summary></summary>
/// <remark>
/// 例如 series-parallel.data 中有如下数据:
/// [
/// [1, 55, 9, 56, 0.46, 18, 6, '良'],
/// [2, 25, 11, 21, 0.65, 34, 9, '优'],
/// [3, 56, 7, 63, 0.3, 14, 5, '良'],
/// [4, 33, 7, 29, 0.33, 16, 6, '优'],
/// { // 数据项也可以是 Object从而里面能含有对线条的特殊设置。
/// value: [5, 42, 24, 44, 0.76, 40, 16, '优']
/// lineStyle: {...},
/// }
/// ...
/// ]
/// 数据中,每一行是一个『数据项』,每一列属于一个『维度』。(例如上面数据每一列的含义分别是:『日期』,『AQI指数』, 『PM2.5』, 『PM10』, 『一氧化碳值』, 『二氧化氮值』, 『二氧化硫值』)。
/// </remark>
public override Object[] Data { get; set; }
/// <summary>平行坐标所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>平行坐标组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
/// <summary>是否开启动画</summary>
public Boolean? Animation { get; set; }
/// <summary>是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。</summary>
public Double? AnimationThreshold { get; set; }
/// <summary>初始动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的初始动画效果:
/// animationDuration: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDuration { get; set; }
/// <summary>初始动画的缓动效果</summary>
/// <remark>不同的缓动效果可以参考 缓动示例。</remark>
public String AnimationEasing { get; set; }
/// <summary></summary>
/// <remark>
/// 初始动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的初始动画效果。
/// 如下示例:
/// animationDelay: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelay { get; set; }
/// <summary>数据更新动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的更新动画效果:
/// animationDurationUpdate: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDurationUpdate { get; set; }
/// <summary>数据更新动画的缓动效果</summary>
public String AnimationEasingUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 数据更新动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的更新动画效果。
/// 如下示例:
/// animationDelayUpdate: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelayUpdate { get; set; }
}

View File

@ -0,0 +1,898 @@
namespace NewLife.Cube.Charts;
/// <summary>象形柱图</summary>
/// <remark>
/// 象形柱图是可以设置各种具象图形元素如图片、SVG PathData 等)的柱状图。往往用在信息图中。用于有至少一个类目轴或时间轴的直角坐标系上。
/// 示例:
///
/// 布局
/// 象形柱图可以被想象为它首先是个柱状图但是柱状图的柱子并不显示。这些柱子我们称为『基准柱reference bar根据基准柱来定位和显示各种象形图形包括图片
/// 每个象形图形根据基准柱的定位,是通过 symbolPosition、symbolOffset 来调整其于基准柱的相对位置。
/// 参见例子:
/// 可以使用 symbolSize 调整大小,从而形成各种视图效果。
/// 参见例子:
///
/// 象形图形类型
/// 每个图形可以配置成『单独』和『重复』两种类型,即通过 symbolRepeat 来设置。
/// 设置为 false默认则一个图形来代表一个数据项。
/// 设置为 true则一组重复的图形来代表一个数据项。
/// 参见例子:
/// 每个象形图形可以是基本图形(如 'circle', 'rect', ...、SVG PathData、图片参见symbolType。
/// 参见例子:
/// 可以使用 symbolClip 对图形进行剪裁。
/// 参见例子:
/// </remark>
public class SeriesPictorialBar : Series
{
/// <summary>实例化象形柱图</summary>
public SeriesPictorialBar() => Type = "pictorialBar";
//public String Type { get; set; } = "pictorialBar";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary>是否启用图例 hover 时的联动高亮</summary>
public Boolean? LegendHoverLink { get; set; }
/// <summary></summary>
/// <remark>
/// 该系列使用的坐标系,可选:
/// 'cartesian2d'
/// 使用二维的直角坐标系(也称笛卡尔坐标系),通过 xAxisIndex, yAxisIndex指定相应的坐标轴组件。
/// </remark>
public String CoordinateSystem { get; set; }
///// <summary>使用的 x 轴的 index在单个图表实例中存在多个 x 轴的时候有用。</summary>
//public Double? XAxisIndex { get; set; }
///// <summary>使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用。</summary>
//public Double? YAxisIndex { get; set; }
/// <summary>鼠标悬浮时在图形元素上时鼠标的样式是什么</summary>
/// <remark>同 CSS 的 cursor。</remark>
public String Cursor { get; set; }
/// <summary>图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。</summary>
public Object Label { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的视觉引导线配置。
/// </remark>
public Object LabelLine { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的统一布局配置。
/// 该配置项是在每个系列默认的标签布局基础上,统一调整标签的(x, y)位置,标签对齐等属性以实现想要的标签布局效果。
/// 该配置项也可以是一个有如下参数的回调函数
/// // 标签对应数据的 dataIndex
/// dataIndex: number
/// // 标签对应的数据类型,只在关系图中会有 node 和 edge 数据类型的区分
/// dataType?: string
/// // 标签对应的系列的 index
/// seriesIndex: number
/// // 标签显示的文本
/// text: string
/// // 默认的标签的包围盒,由系列默认的标签布局决定
/// labelRect: {x: number, y: number, width: number, height: number}
/// // 默认的标签水平对齐
/// align: 'left' | 'center' | 'right'
/// // 默认的标签垂直对齐
/// verticalAlign: 'top' | 'middle' | 'bottom'
/// // 标签所对应的数据图形的包围盒,可用于定位标签位置
/// rect: {x: number, y: number, width: number, height: number}
/// // 默认引导线的位置,目前只有饼图(pie)和漏斗图(funnel)有默认标签位置
/// // 如果没有该值则为 null
/// labelLinePoints?: number[][]
/// 示例:
/// 将标签显示在图形右侧 10px 的位置,并且垂直居中:
/// labelLayout(params) {
/// return {
/// x: params.rect.x + 10,
/// y: params.rect.y + params.rect.height / 2,
/// verticalAlign: 'middle',
/// align: 'left'
/// }
/// }
/// 根据图形的包围盒尺寸决定文本尺寸
/// labelLayout(params) {
/// return {
/// fontSize: Math.max(params.rect.width / 10, 5)
/// };
/// }
/// </remark>
public Object LabelLayout { get; set; }
/// <summary>图形样式</summary>
public Object ItemStyle { get; set; }
/// <summary>高亮状态配置</summary>
public Object Emphasis { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 淡出状态配置。开启 emphasis.focus 后有效。
/// </remark>
public Object Blur { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中状态配置。开启 selectedMode 后有效。
/// </remark>
public Object Select { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中模式的配置,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选'single''multiple''series' 分别表示单选,多选以及选择整个系列。
/// 从 v5.3.0 开始支持 'series'。
/// </remark>
public Object SelectedMode { get; set; }
/// <summary>柱条的宽度,不设时自适应</summary>
/// <remark>
/// 可以是绝对值例如 40 或者百分数例如 '60%'。百分数基于自动计算出的每一类目的宽度。
/// 在同一坐标系上,此属性会被多个 'pictorialBar' 系列共享。此属性应设置于此坐标系中最后一个 'pictorialBar' 系列上才会生效,并且是对此坐标系中所有 'pictorialBar' 系列生效。
/// </remark>
public Object BarWidth { get; set; }
/// <summary>柱条的最大宽度</summary>
/// <remark>
/// 比 barWidth 优先级高。
/// 可以是绝对值例如 40 或者百分数例如 '60%'。百分数基于自动计算出的每一类目的宽度。
/// 在同一坐标系上,此属性会被多个 'pictorialBar' 系列共享。此属性应设置于此坐标系中最后一个 'pictorialBar' 系列上才会生效,并且是对此坐标系中所有 'pictorialBar' 系列生效。
/// </remark>
public Object BarMaxWidth { get; set; }
/// <summary>柱条的最小宽度</summary>
/// <remark>
/// 在直角坐标系中,默认值是 1。否则默认值是 null。
/// 比 barWidth 优先级高。
/// 可以是绝对值例如 40 或者百分数例如 '60%'。百分数基于自动计算出的每一类目的宽度。
/// 在同一坐标系上,此属性会被多个 'pictorialBar' 系列共享。此属性应设置于此坐标系中最后一个 'pictorialBar' 系列上才会生效,并且是对此坐标系中所有 'pictorialBar' 系列生效。
/// </remark>
public Object BarMinWidth { get; set; }
/// <summary>柱条最小高度,可用于防止某数据项的值过小而影响交互</summary>
public Double? BarMinHeight { get; set; }
/// <summary>柱条最小角度,可用于防止某数据项的值过小而影响交互</summary>
/// <remark>仅对极坐标系柱状图有效。</remark>
public Double? BarMinAngle { get; set; }
/// <summary></summary>
/// <remark>
/// 不同系列的柱间距离,为百分比(如 '20%',表示柱子宽度的 20%)。
/// 如果想要两个系列的柱子重叠,可以设置 barGap 为 '-100%'。这在用柱子做背景的时候有用。
/// 在同一坐标系上,此属性会被多个 'pictorialBar' 系列共享。此属性应设置于此坐标系中最后一个 'pictorialBar' 系列上才会生效,并且是对此坐标系中所有 'pictorialBar' 系列生效。
/// 例子:
/// </remark>
public String BarGap { get; set; }
/// <summary></summary>
/// <remark>
/// 同一系列的柱间距离,默认情况下根据柱状图的系列数量计算得到合适的间距,系列较多时间距会适当调小,可设固定值
/// 在同一坐标系上,此属性会被多个 'pictorialBar' 系列共享。此属性应设置于此坐标系中最后一个 'pictorialBar' 系列上才会生效,并且是对此坐标系中所有 'pictorialBar' 系列生效。
/// </remark>
public Object BarCategoryGap { get; set; }
///// <summary>图形类型</summary>
///// <remark>
///// ECharts 提供的标记类型包括
///// 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
///// 可以通过 'image://url' 设置为图片,其中 URL 为图片的链接,或者 dataURI。
///// URL 为图片链接例如:
///// 'image://http://example.website/a/b.png'
///// URL 为 dataURI 例如:
///// 'image://data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'
///// 可以通过 'path://' 将图标设置为任意的矢量路径。这种方式相比于使用图片的方式,不用担心因为缩放而产生锯齿或模糊,而且可以设置为任意颜色。路径图形会自适应调整为合适的大小。路径的格式参见 SVG PathData。可以从 Adobe Illustrator 等工具编辑导出。
///// 例如:
///// 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z'
///// 例子:
///// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
///// 例如:
///// series: [{
///// symbol: ... // 对 data 中所有数据项生效。
///// data: [23, 56]
///// }]
///// 或者
///// series: [{
///// data: [{
///// value: 23
///// symbol: ... // 只对此数据项生效
///// }, {
///// value: 56
///// symbol: ... // 只对此数据项生效
///// }]
///// }]
///// </remark>
//public String Symbol { get; set; }
/// <summary>图形的大小</summary>
/// <remark>
/// 可以用数组分开表示宽和高,例如 [20, 10] 表示标记宽为20高为10也可以设置成诸如 10 这样单一的数字,表示 [10, 10]。
/// 可以设置成绝对值(如 10也可以设置成百分比如 '120%'、['55%', 23])。
/// 当设置为百分比时,图形的大小是基于 基准柱 的尺寸计算出来的。
/// 例如,当基准柱基于 x 轴即柱子是纵向的symbolSize 设置为 ['30%', '50%'],那么最终图形的尺寸是:
/// 宽度:基准柱的宽度 * 30%。
/// 高度:
/// 如果 symbolRepeat 为 false基准柱的高度 * 50%。
/// 如果 symbolRepeat 为 true基准柱的宽度 * 50%。
/// 基准柱基于 y 轴(即柱子是横向的)的情况类似对调可得出。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolSize: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolSize: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolSize: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Object SymbolSize { get; set; }
/// <summary>图形的定位位置</summary>
/// <remark>
/// 可取值:
/// 'start':图形边缘与柱子开始的地方内切。
/// 'end':图形边缘与柱子结束的地方内切。
/// 'center':图形在柱子里居中。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolPosition: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolPosition: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolPosition: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public String SymbolPosition { get; set; }
/// <summary>图形相对于原本位置的偏移</summary>
/// <remark>
/// symbolOffset 是图形定位中最后计算的一个步骤,可以对图形计算出来的位置进行微调。
/// 可以设置成绝对值(如 10也可以设置成百分比如 '120%'、['55%', 23])。
/// 当设置为百分比时,表示相对于自身尺寸 symbolSize 的百分比。
/// 例如 [0, '-50%'] 就是把图形向上移动了自身尺寸的一半的位置。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolOffset: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolOffset: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolOffset: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Double[] SymbolOffset { get; set; }
/// <summary>图形的旋转角度</summary>
/// <remark>
/// 注意symbolRotate 并不会影响图形的定位(哪怕超出基准柱的边界),而只是单纯得绕自身中心旋转。
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolRotate: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolRotate: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolRotate: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Double? SymbolRotate { get; set; }
/// <summary>指定图形元素是否重复</summary>
/// <remark>
/// 值可为:
/// false/null/undefined不重复即每个数据值用一个图形元素表示。
/// true使图形元素重复即每个数据值用一组重复的图形元素表示。重复的次数依据 data 计算得到。
/// a number使图形元素重复即每个数据值用一组重复的图形元素表示。重复的次数是给定的定值。
/// 'fixed':使图形元素重复,即每个数据值用一组重复的图形元素表示。重复的次数依据 symbolBoundingData 计算得到,即与 data 无关。这在此图形被用于做背景时有用。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolRepeat: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolRepeat: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolRepeat: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Object SymbolRepeat { get; set; }
/// <summary>指定图形元素重复时,绘制的顺序</summary>
/// <remark>
/// 这个属性在两种情况下有用处:
/// 当 symbolMargin 设置为负值时,重复的图形会互相覆盖,这是可以使用 symbolRepeatDirection 来指定覆盖顺序。
/// 当 animationDelay 或 animationDelayUpdate 被使用时symbolRepeatDirection 指定了 index 顺序。
/// 这个属性的值可以是:'start' 或 'end'。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolRepeatDirection: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolRepeatDirection: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolRepeatDirection: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public String SymbolRepeatDirection { get; set; }
/// <summary>图形的两边间隔(『两边』是指其数值轴方向的两边)</summary>
/// <remark>
/// 可以是绝对数值(如 20或者百分比值如 '-30%'),表示相对于自身尺寸 symbolSize 的百分比。只有当 symbolRepeat 被使用时有意义。
/// 可以是正值,表示间隔大;也可以是负数。当 symbolRepeat 被使用时,负数时能使图形重叠。
/// 可以在其值结尾处加一个 "!",如 "30%!" 或 25!,表示第一个图形的开始和最后一个图形结尾留白,不紧贴边界。默认会紧贴边界。
/// 注意:
/// 当 symbolRepeat 为 true/'fixed' 的时候:
/// 这里设置的 symbolMargin 只是个参考值,真正最后的图形间隔,是根据 symbolRepeat、symbolMargin、symbolBoundingData 综合计算得到。
/// 当 symbolRepeat 为一个固定数值的时候:
/// 这里设置的 symbolMargin 无效。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolMargin: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolMargin: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolMargin: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Object SymbolMargin { get; set; }
/// <summary>是否剪裁图形</summary>
/// <remark>
/// false/null/undefined图形本身表示数值大小。
/// true图形被剪裁后剩余的部分表示数值大小。
/// symbolClip 常在这种场景下使用:同时表达『总值』和『当前数值』。在这种场景下,可以使用两个系列,一个系列是完整的图形,当做『背景』来表达总数值,另一个系列是使用 symbolClip 进行剪裁过的图形,表达当前数值。
/// 例子:
/// 在这个例子中:
/// 『背景系列』和『当前值系列』使用相同的 symbolBoundingData使得绘制出的图形的大小是一样的。
/// 『当前值系列』设置了比『背景系列』更高的 z使得其覆盖在『背景系列』上。
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolClip: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolClip: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolClip: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Boolean? SymbolClip { get; set; }
/// <summary>这个属性是『指定图形界限的值』</summary>
/// <remark>
/// 它指定了一个 data这个 data 映射在坐标系上的位置,是图形绘制的界限。也就是说,如果设置了 symbolBoundingData图形的尺寸则由 symbolBoundingData 决定。
/// 当柱子是水平的symbolBoundingData 对应到 x 轴上当柱子是竖直的symbolBoundingData 对应到 y 轴上。
/// 规则:
/// 没有使用 symbolRepeat 时:
/// symbolBoundingData 缺省情况下和『参考柱』的尺寸一样。图形的尺寸由零点和 symbolBoundingData 决定。举例,当柱子是竖直的,柱子对应的 data 为 24symbolSize 设置为 [30, '50%']symbolBoundingData 设置为 124那么最终图形的高度为 124 * 50% = 62。如果 symbolBoundingData 不设置,那么最终图形的高度为 24 * 50% = 12。
/// 使用了 symbolRepeat 时:
/// symbolBoundingData 缺省情况取当前坐标系所显示出的最值。symbolBoundingData 定义了一个 bounding重复的图形在这个 bounding 中,依据 symbolMargin 和 symbolRepeat 和 symbolSize 进行排布。这几个变量决定了图形的间隔大小。
/// 在这些场景中,你可能会需要设置 symbolBoundingData
/// 使用了 symbolCilp 时:
/// 使用一个系列表达『总值』,另一个系列表达『当前值』的时候,需要两个系列画出的图形一样大。那么就把两个系列的 symbolBoundingData 设为一样大。
/// 例子:
///
/// 使用了 symbolRepeat 时:
/// 如果需要不同柱子中的图形的间隔保持一致,那么可以把 symbolBoundingData 设为一致的数值。当然,不设置 symbolBoundingData 也是可以的,因为其缺省值就是一个定值(坐标系所显示出的最值)。
/// 例子:
///
/// symbolBoundingData 可以是一个数组,例如 [-40, 60],表示同时指定了正值的 symbolBoundingData 和负值的 symbolBoundingData。
/// 参见例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolBoundingData: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolBoundingData: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolBoundingData: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Object SymbolBoundingData { get; set; }
/// <summary>可以使用图片作为图形的 pattern</summary>
/// <remark>
/// var textureImg = new Image();
/// textureImg.src = 'data:image/jpeg;base64,...'; // dataURI
/// // 或者
/// // textureImg.src = 'http://example.website/xx.png'; // URL
/// ...
/// itemStyle: {
/// color: {
/// image: textureImg,
/// repeat: 'repeat'
/// }
/// }
/// 这时候symbolPatternSize 指定了 pattern 的缩放尺寸。比如 symbolPatternSize 为 400 时表示图片显示为 400px * 400px 的尺寸。
/// 例子:
/// 此属性可以被设置在系列的 根部,表示对此系列中所有数据都生效;也可以被设置在 data 中的 每个数据项中,表示只对此数据项生效。
/// 例如:
/// series: [{
/// symbolPatternSize: ... // 对 data 中所有数据项生效。
/// data: [23, 56]
/// }]
/// 或者
/// series: [{
/// data: [{
/// value: 23
/// symbolPatternSize: ... // 只对此数据项生效
/// }, {
/// value: 56
/// symbolPatternSize: ... // 只对此数据项生效
/// }]
/// }]
/// </remark>
public Double? SymbolPatternSize { get; set; }
/// <summary>是否开启动画</summary>
public Boolean? Animation { get; set; }
/// <summary>是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。</summary>
public Double? AnimationThreshold { get; set; }
/// <summary>初始动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的初始动画效果:
/// animationDuration: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDuration { get; set; }
/// <summary>初始动画的缓动效果</summary>
/// <remark>不同的缓动效果可以参考 缓动示例。</remark>
public String AnimationEasing { get; set; }
/// <summary>数据更新动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的更新动画效果:
/// animationDurationUpdate: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDurationUpdate { get; set; }
/// <summary>数据更新动画的缓动效果</summary>
public Object AnimationEasingUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 动画开始之前的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的更新动画效果。
/// 如下示例:
/// animationDelay: function (dataIndex, params) {
/// return params.index * 30;
/// }
/// 或者反向:
/// animationDelay: function (dataIndex, params) {
/// return (params.count - 1 - params.index) * 30;
/// }
/// 例子:
/// </remark>
public Object AnimationDelay { get; set; }
/// <summary></summary>
/// <remark>
/// 数据更新动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的更新动画效果。
/// 如下示例:
/// animationDelay: function (dataIndex, params) {
/// return params.index * 30;
/// }
/// 或者反向:
/// animationDelay: function (dataIndex, params) {
/// return (params.count - 1 - params.index) * 30;
/// }
/// 例子:
/// </remark>
public Object AnimationDelayUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 使用 dimensions 定义 series.data 或者 dataset.source 的每个维度的信息。
/// 注意:如果使用了 dataset那么可以在 dataset.dimensions 中定义 dimension ,或者在 dataset.source 的第一行/列中给出 dimension 名称。于是就不用在这里指定 dimension。但如果在这里指定了 dimensions那么优先使用这里的。
/// 例如:
/// option = {
/// dataset: {
/// source: [
/// // 有了上面 dimensions 定义后,下面这五个维度的名称分别为:
/// // 'date', 'open', 'close', 'highest', 'lowest'
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// // 定义了每个维度的名称。这个名称会被显示到默认的 tooltip 中。
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest']
/// }
/// }
/// series: {
/// type: 'xxx',
/// dimensions: [
/// null, // 如果此维度不想给出定义,则使用 null 即可
/// {type: 'ordinal'}, // 只定义此维度的类型。
/// // 'ordinal' 表示离散型,一般文本使用这种类型。
/// // 如果类型没有被定义,会自动猜测类型。
/// {name: 'good', type: 'number'},
/// 'bad' // 等同于 {name: 'bad'}
/// ]
/// }
/// dimensions 数组中的每一项可以是:
/// string如 'someName',等同于 {name: 'someName'}
/// Object属性可以有
/// name: string。
/// type: string支持
/// number默认表示普通数据。
/// ordinal对于类目、文本这些 string 类型的数据,如果需要能在数轴上使用,须是 'ordinal' 类型。ECharts 默认会自动判断这个类型。但是自动判断也是不可能很完备的,所以使用者也可以手动强制指定。
/// float即 Float64Array。
/// int即 Int32Array。
/// time表示时间类型。设置成 'time' 则能支持自动解析数据成时间戳timestamp比如该维度的数据是 '2017-05-10',会自动被解析。时间类型的支持参见 data。
/// displayName: 一般用于 tooltip 中维度名的展示。string 如果没有指定,默认使用 name 来展示。
/// 值得一提的是,当定义了 dimensions 后,默认 tooltip 中对个维度的显示,会变为『竖排』,从而方便显示每个维度的名称。如果没有定义 dimensions则默认 tooltip 会横排显示,且只显示数值没有维度名称可显示。
/// </remark>
public Double[] Dimensions { get; set; }
/// <summary>可以定义 data 的哪个维度被编码成什么</summary>
/// <remark>
/// 比如:
/// option = {
/// dataset: {
/// source: [
/// // 每一列称为一个『维度』。
/// // 这里分别是维度 0、1、2、3、4。
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// encode: {
/// x: [3, 1, 5], // 表示维度 3、1、5 映射到 x 轴。
/// y: 2, // 表示维度 2 映射到 y 轴。
/// tooltip: [3, 2, 4] // 表示维度 3、2、4 会在 tooltip 中显示。
/// }
/// }
/// }
/// 当使用 dimensions 给维度定义名称后encode 中可直接引用名称,例如:
/// series: {
/// type: 'xxx',
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest'],
/// encode: {
/// x: 'date',
/// y: ['open', 'close', 'highest', 'lowest']
/// }
/// }
/// encode 声明的基本结构如下,其中冒号左边是坐标系、标签等特定名称,如 'x', 'y', 'tooltip' 等冒号右边是数据中的维度名string 格式或者维度的序号number 格式,从 0 开始计数),可以指定一个或多个维度(使用数组)。通常情况下,下面各种信息不需要所有的都写,按需写即可。
/// 下面是 encode 支持的属性:
/// // 在任何坐标系和系列中,都支持:
/// encode: {
/// // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示
/// tooltip: ['product', 'score']
/// // 使用第一个维度和第三个维度的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)
/// seriesName: [1, 3],
/// // 表示使用第二个维度中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画。
/// itemId: 2,
/// // 指定数据项的名称使用第三个维度在饼图等图表中有用可以使这个名字显示在图例legend中。
/// itemName: 3,
/// // 指定数据项的组 ID (groupId)。当全局过渡动画功能开启时setOption 前后拥有相同 groupId 的数据项会进行动画过渡。
/// itemGroupId: 4,
/// // 指定数据项对应的子数据组 ID (childGroupId),用于实现多层下钻和聚合。详见 childGroupId。
/// // 从 v5.5.0 开始支持
/// itemChildGroupId: 5
/// }
/// // 直角坐标系grid/cartesian特有的属性
/// encode: {
/// // 把 “维度1”、“维度5”、“名为 score 的维度” 映射到 X 轴:
/// x: [1, 5, 'score'],
/// // 把“维度0”映射到 Y 轴。
/// y: 0
/// }
/// // 单轴singleAxis特有的属性
/// encode: {
/// single: 3
/// }
/// // 极坐标系polar特有的属性
/// encode: {
/// radius: 3,
/// angle: 2
/// }
/// // 地理坐标系geo特有的属性
/// encode: {
/// lng: 3,
/// lat: 2
/// }
/// // 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:
/// encode: {
/// value: 3
/// }
/// 这是个更丰富的 encode 的示例:
/// 特殊地,在 自定义系列custom seriesencode 中轴可以不指定或设置为 null/undefined从而使系列免于受这个轴控制也就是说轴的范围extent不会受此系列数值的影响轴被 dataZoom 控制时也不会过滤掉这个系列:
/// var option = {
/// xAxis: {},
/// yAxis: {},
/// dataZoom: [{
/// xAxisIndex: 0
/// }, {
/// yAxisIndex: 0
/// }],
/// series: {
/// type: 'custom',
/// renderItem: function (params, api) {
/// return {
/// type: 'circle',
/// shape: {
/// cx: 100, // x 位置永远为 100
/// cy: api.coord([0, api.value(0)])[1],
/// r: 30
/// },
/// style: {
/// fill: 'blue'
/// }
/// };
/// },
/// encode: {
/// // 这样这个系列就不会被 x 轴以及 x
/// // 轴上的 dataZoom 控制了。
/// x: -1,
/// y: 1
/// },
/// data: [ ... ]
/// }
/// };
/// </remark>
public Object Encode { get; set; }
/// <summary>该系列所有数据项的组 ID优先级低于groupId</summary>
/// <remark>详见series.data.groupId。</remark>
public String DataGroupId { get; set; }
/// <summary>系列中的数据内容数组</summary>
/// <remark>
/// 数组项通常为具体的数据项。
/// 注意,如果系列没有指定 data并且 option 有 dataset那么默认使用第一个 dataset。如果指定了 data则不会再使用 dataset。
/// 可以使用 series.datasetIndex 指定其他的 dataset。
/// 通常来说,数据用一个二维数组表示。如下,每一列被称为一个『维度』。
/// series: [{
/// data: [
/// // 维度X 维度Y 其他维度 ...
/// [ 3.4, 4.5, 15, 43],
/// [ 4.2, 2.3, 20, 91],
/// [ 10.8, 9.5, 30, 18],
/// [ 7.2, 8.8, 18, 57]
/// ]
/// }]
/// 在 直角坐标系 (grid) 中『维度X』和『维度Y』会默认对应于 xAxis 和 yAxis。
/// 在 极坐标系 (polar) 中『维度X』和『维度Y』会默认对应于 radiusAxis 和 angleAxis。
/// 后面的其他维度是可选的,可以在别处被使用,例如:
/// 在 visualMap 中可以将一个或多个维度映射到颜色,大小等多个图形属性上。
/// 在 series.symbolSize 中可以使用回调函数,基于某个维度得到 symbolSize 值。
/// 使用 tooltip.formatter 或 series.label.formatter 可以把其他维度的值展示出来。
/// 特别地当只有一个轴为类目轴axis.type 为 'category')的时候,数据可以简化用一个一维数组表示。例如:
/// xAxis: {
/// data: ['a', 'b', 'm', 'n']
/// },
/// series: [{
/// // 与 xAxis.data 一一对应。
/// data: [23, 44, 55, 19]
/// // 它其实是下面这种形式的简化:
/// // data: [[0, 23], [1, 44], [2, 55], [3, 19]]
/// }]
/// 『值』与 轴类型 的关系:
/// 当某维度对应于数值轴axis.type 为 'value' 或者 'log')的时候:
/// 其值可以为 number例如 12也可以兼容 string 形式的 number例如 '12'
/// 当某维度对应于类目轴axis.type 为 'category')的时候:
/// 其值须为类目的『序数』(从 0 开始)或者类目的『字符串值』。例如:
/// xAxis: {
/// type: 'category',
/// data: ['星期一', '星期二', '星期三', '星期四']
/// },
/// yAxis: {
/// type: 'category',
/// data: ['a', 'b', 'm', 'n', 'p', 'q']
/// },
/// series: [{
/// data: [
/// // xAxis yAxis
/// [ 0, 0, 2 ], // 意思是此点位于 xAxis: '星期一', yAxis: 'a'。
/// [ '星期四', 2, 1 ], // 意思是此点位于 xAxis: '星期四', yAxis: 'm'。
/// [ 2, 'p', 2 ], // 意思是此点位于 xAxis: '星期三', yAxis: 'p'。
/// [ 3, 3, 5 ]
/// ]
/// }]
/// 双类目轴的示例可以参考 Github Punchcard 示例。
/// 当某维度对应于时间轴type 为 'time')的时候,值可以为:
/// 一个时间戳,如 1484141700832表示 UTC 时间。
/// 或者字符串形式的时间描述:
/// ISO 8601 的子集,只包含这些形式(这几种格式,除非指明时区,否则均表示本地时间,与 moment 一致):
/// 部分年月日时间: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06'.
/// 使用 'T' 或空格分割: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123'.
/// 时区设定: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00'.
/// 其他的时间字符串,包括(均表示本地时间):
/// '2012', '2012-3-1', '2012/3/1', '2012/03/01',
/// '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
/// 或者用户自行初始化的 Date 实例:
/// 注意,用户自行初始化 Date 实例的时候,浏览器的行为有差异,不同字符串的表示也不同。
/// 例如:在 chrome 中new Date('2012-01-01') 表示 UTC 时间的 2012 年 1 月 1 日,而 new Date('2012-1-1') 和 new Date('2012/01/01') 表示本地时间的 2012 年 1 月 1 日。在 safari 中,不支持 new Date('2012-1-1') 这种表示方法。
/// 所以,使用 new Date(dataString) 时,可使用第三方库解析(如 moment或者使用 echarts.time.parse或者参见 这里。
/// 当需要对个别数据进行个性化定义时:
/// 数组项可用对象,其中的 value 像表示具体的数值,如:
/// [
/// 12,
/// 34,
/// {
/// value : 56,
/// //自定义标签样式,仅对该数据项有效
/// label: {},
/// //自定义特殊 itemStyle仅对该数据项有效
/// itemStyle:{}
/// },
/// 10
/// ]
/// // 或
/// [
/// [12, 33],
/// [34, 313],
/// {
/// value: [56, 44],
/// label: {},
/// itemStyle:{}
/// },
/// [10, 33]
/// ]
/// 空值:
/// 当某数据不存在时ps不存在不代表值为 0可以用 '-' 或者 null 或者 undefined 或者 NaN 表示。
/// 例如,无数据在折线图中可表现为该点是断开的,在其它图中可表示为图形不存在。
/// </remark>
public override Object[] Data { get; set; }
///// <summary>图表标注</summary>
//public Object MarkPoint { get; set; }
///// <summary>图表标线</summary>
//public Object MarkLine { get; set; }
/// <summary>图表标域,常用于标记图表中某个范围的数据,例如标出某段时间投放了广告。</summary>
public Object MarkArea { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 是否裁剪超出坐标系部分的图形,具体裁剪效果根据系列决定:
/// 散点图/带有涟漪特效动画的散点(气泡)图:忽略中心点超出坐标系的图形,但是不裁剪单个图形
/// 柱状图:裁掉完全超出的柱子,但是不会裁剪只超出部分的柱子
/// 折线图:裁掉所有超出坐标系的折线部分,拐点图形的逻辑按照散点图处理
/// 路径图:裁掉所有超出坐标系的部分
/// K 线图:忽略整体都超出坐标系的图形,但是不裁剪单个图形
/// 象形柱图:裁掉所有超出坐标系的部分(从 v5.5.0 开始支持)
/// 自定义系列:裁掉所有超出坐标系的部分
/// 除了象形柱图和自定义系列,其它系列的默认值都为 true及开启裁剪如果你觉得不想要裁剪的话可以设置成 false 关闭。
/// </remark>
public Boolean? Clip { get; set; }
/// <summary>象形柱图所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>象形柱图组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.2.0 开始支持
/// 全局过渡动画相关的配置。
/// 全局过渡动画Universal Transition提供了任意系列之间进行变形动画的功能。开启该功能后每次setOption相同id的系列之间会自动关联进行动画的过渡更细粒度的关联配置见universalTransition.seriesKey配置。
/// 通过配置数据项的groupId和childGroupId还可以实现诸如下钻聚合等一对多或者多对一的动画。
/// 可以直接在系列中配置 universalTransition: true 开启该功能。也可以提供一个对象进行更多属性的配置。
/// </remark>
public Object UniversalTransition { get; set; }
/// <summary>本系列特定的 tooltip 设定</summary>
public Object Tooltip { get; set; }
}

View File

@ -10,6 +10,9 @@
/// </remark>
public class SeriesPie : Series
{
/// <summary>实例化饼图</summary>
public SeriesPie() => Type = "pie";
//public String Type { get; set; } = "pie";
///// <summary>组件 ID</summary>

View File

@ -7,6 +7,9 @@
/// </remark>
public class SeriesRadar : Series
{
/// <summary>实例化雷达图</summary>
public SeriesRadar() => Type = "radar";
//public String Type { get; set; } = "radar";
///// <summary>组件 ID</summary>

View File

@ -13,6 +13,9 @@
/// </remark>
public class SeriesSankey : Series
{
/// <summary>实例化桑基图</summary>
public SeriesSankey() => Type = "sankey";
//public String Type { get; set; } = "sankey";
///// <summary>组件 ID</summary>

View File

@ -0,0 +1,605 @@
namespace NewLife.Cube.Charts;
/// <summary>散点(气泡)图</summary>
/// <remark>
/// 直角坐标系上的散点图可以用来展现数据的 xy 之间的关系,如果数据项有多个维度,其它维度的值可以通过不同大小的 symbol 展现成气泡图,也可以用颜色来表现。这些可以配合 visualMap 组件完成。
/// 可以应用在直角坐标系,极坐标系,地理坐标系上。
/// </remark>
public class SeriesScatter : Series
{
/// <summary>实例化散点图</summary>
public SeriesScatter() => Type = "scatter";
//public String Type { get; set; } = "scatter";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary></summary>
/// <remark>
/// 该系列使用的坐标系,可选:
/// 'cartesian2d'
/// 使用二维的直角坐标系(也称笛卡尔坐标系),通过 xAxisIndex, yAxisIndex指定相应的坐标轴组件。
/// 'polar'
/// 使用极坐标系,通过 polarIndex 指定相应的极坐标组件
/// 'geo'
/// 使用地理坐标系,通过 geoIndex 指定相应的地理坐标系组件。
/// 'calendar'
/// 使用日历坐标系,通过 calendarIndex 指定相应的日历坐标系组件。
/// </remark>
public String CoordinateSystem { get; set; }
///// <summary>使用的 x 轴的 index在单个图表实例中存在多个 x 轴的时候有用。</summary>
//public Double? XAxisIndex { get; set; }
///// <summary>使用的 y 轴的 index在单个图表实例中存在多个 y轴的时候有用。</summary>
//public Double? YAxisIndex { get; set; }
/// <summary>使用的极坐标系的 index在单个图表实例中存在多个极坐标系的时候有用。</summary>
public Double? PolarIndex { get; set; }
/// <summary>使用的地理坐标系的 index在单个图表实例中存在多个地理坐标系的时候有用。</summary>
public Double? GeoIndex { get; set; }
/// <summary>使用的日历坐标系的 index在单个图表实例中存在多个日历坐标系的时候有用。</summary>
public Double? CalendarIndex { get; set; }
/// <summary>是否启用图例 hover 时的联动高亮</summary>
public Boolean? LegendHoverLink { get; set; }
///// <summary>标记的图形</summary>
///// <remark>
///// ECharts 提供的标记类型包括
///// 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
///// 可以通过 'image://url' 设置为图片,其中 URL 为图片的链接,或者 dataURI。
///// URL 为图片链接例如:
///// 'image://http://example.website/a/b.png'
///// URL 为 dataURI 例如:
///// 'image://data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'
///// 可以通过 'path://' 将图标设置为任意的矢量路径。这种方式相比于使用图片的方式,不用担心因为缩放而产生锯齿或模糊,而且可以设置为任意颜色。路径图形会自适应调整为合适的大小。路径的格式参见 SVG PathData。可以从 Adobe Illustrator 等工具编辑导出。
///// 例如:
///// 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z'
///// 如果需要每个数据的图形不一样,可以设置为如下格式的回调函数:
///// (value: Array|number, params: Object) => string
///// 其中第一个参数 value 为 data 中的数据值。第二个参数params 是其它的数据项参数。
///// </remark>
//public String Symbol { get; set; }
/// <summary></summary>
/// <remark>
/// 标记的大小,可以设置成诸如 10 这样单一的数字,也可以用数组分开表示宽和高,例如 [20, 10] 表示标记宽为20高为10。
/// 如果需要每个数据的图形大小不一样,可以设置为如下格式的回调函数:
/// (value: Array|number, params: Object) => number|Array
/// 其中第一个参数 value 为 data 中的数据值。第二个参数params 是其它的数据项参数。
/// </remark>
public Object SymbolSize { get; set; }
/// <summary>标记的旋转角度(而非弧度)</summary>
/// <remark>
/// 正值表示逆时针旋转。注意在 markLine 中当 symbol 为 'arrow' 时会忽略 symbolRotate 强制设置为切线的角度。
/// 如果需要每个数据的旋转角度不一样,可以设置为如下格式的回调函数:
/// (value: Array|number, params: Object) => number
/// 其中第一个参数 value 为 data 中的数据值。第二个参数params 是其它的数据项参数。
/// 从 4.8.0 开始支持回调函数。
/// </remark>
public Object SymbolRotate { get; set; }
/// <summary></summary>
/// <remark>如果 symbol 是 path:// 的形式,是否在缩放时保持该图形的长宽比。</remark>
public Boolean? SymbolKeepAspect { get; set; }
/// <summary>标记相对于原本位置的偏移</summary>
/// <remark>
/// 默认情况下,标记会居中置放在数据对应的位置,但是如果 symbol 是自定义的矢量路径或者图片,就有可能不希望 symbol 居中。这时候可以使用该配置项配置 symbol 相对于原本居中的偏移,可以是绝对的像素值,也可以是相对的百分比。
/// 例如 [0, '-50%'] 就是把自己向上移动了一半的位置,在 symbol 图形是气泡的时候可以让图形下端的箭头对准数据点。
/// </remark>
public Double[] SymbolOffset { get; set; }
/// <summary></summary>
/// <remark>
/// 是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。
/// 开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。
/// 缺点:优化后不能自定义设置单个数据项的样式。
/// </remark>
public Boolean? Large { get; set; }
/// <summary>开启绘制优化的阈值</summary>
public Double? LargeThreshold { get; set; }
/// <summary>鼠标悬浮时在图形元素上时鼠标的样式是什么</summary>
/// <remark>同 CSS 的 cursor。</remark>
public String Cursor { get; set; }
/// <summary>图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。</summary>
public Object Label { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的视觉引导线配置。
/// </remark>
public Object LabelLine { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的统一布局配置。
/// 该配置项是在每个系列默认的标签布局基础上,统一调整标签的(x, y)位置,标签对齐等属性以实现想要的标签布局效果。
/// 该配置项也可以是一个有如下参数的回调函数
/// // 标签对应数据的 dataIndex
/// dataIndex: number
/// // 标签对应的数据类型,只在关系图中会有 node 和 edge 数据类型的区分
/// dataType?: string
/// // 标签对应的系列的 index
/// seriesIndex: number
/// // 标签显示的文本
/// text: string
/// // 默认的标签的包围盒,由系列默认的标签布局决定
/// labelRect: {x: number, y: number, width: number, height: number}
/// // 默认的标签水平对齐
/// align: 'left' | 'center' | 'right'
/// // 默认的标签垂直对齐
/// verticalAlign: 'top' | 'middle' | 'bottom'
/// // 标签所对应的数据图形的包围盒,可用于定位标签位置
/// rect: {x: number, y: number, width: number, height: number}
/// // 默认引导线的位置,目前只有饼图(pie)和漏斗图(funnel)有默认标签位置
/// // 如果没有该值则为 null
/// labelLinePoints?: number[][]
/// 示例:
/// 将标签显示在图形右侧 10px 的位置,并且垂直居中:
/// labelLayout(params) {
/// return {
/// x: params.rect.x + 10,
/// y: params.rect.y + params.rect.height / 2,
/// verticalAlign: 'middle',
/// align: 'left'
/// }
/// }
/// 根据图形的包围盒尺寸决定文本尺寸
/// labelLayout(params) {
/// return {
/// fontSize: Math.max(params.rect.width / 10, 5)
/// };
/// }
/// </remark>
public Object LabelLayout { get; set; }
/// <summary>图形样式</summary>
public Object ItemStyle { get; set; }
/// <summary>高亮的图形和标签样式</summary>
public Object Emphasis { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 淡出状态的配置。开启 emphasis.focus 后有效。
/// </remark>
public Object Blur { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中状态的配置。开启 selectedMode 后有效。
/// </remark>
public Object Select { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中模式的配置,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选'single''multiple''series' 分别表示单选,多选以及选择整个系列。
/// 从 v5.3.0 开始支持 'series'。
/// </remark>
public Object SelectedMode { get; set; }
/// <summary></summary>
/// <remark>
/// 渐进式渲染时每一帧绘制图形数量,设为 0 时不启用渐进式渲染,支持每个系列单独配置。
/// 在图中有数千到几千万图形元素的时候一下子把图形绘制出来或者交互重绘的时候可能会造成界面的卡顿甚至假死。ECharts 4 开始全流程支持渐进渲染progressive rendering渲染的时候会把创建好的图形分到数帧中渲染每一帧渲染只渲染指定数量的图形。
/// 该配置项就是用于配置该系列每一帧渲染的图形数,可以根据图表图形复杂度的需要适当调整这个数字使得在不影响交互流畅性的前提下达到绘制速度的最大化。比如在 lines 图或者平行坐标中线宽大于 1 的 polyline 绘制会很慢,这个数字就可以设置小一点,而线宽小于等于 1 的 polyline 绘制非常快,该配置项就可以相对调得比较大。
/// </remark>
public Double? Progressive { get; set; }
/// <summary>启用渐进式渲染的图形数量阈值,在单个系列的图形数量超过该阈值时启用渐进式渲染。</summary>
public Double? ProgressiveThreshold { get; set; }
/// <summary></summary>
/// <remark>
/// 使用 dimensions 定义 series.data 或者 dataset.source 的每个维度的信息。
/// 注意:如果使用了 dataset那么可以在 dataset.dimensions 中定义 dimension ,或者在 dataset.source 的第一行/列中给出 dimension 名称。于是就不用在这里指定 dimension。但如果在这里指定了 dimensions那么优先使用这里的。
/// 例如:
/// option = {
/// dataset: {
/// source: [
/// // 有了上面 dimensions 定义后,下面这五个维度的名称分别为:
/// // 'date', 'open', 'close', 'highest', 'lowest'
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// // 定义了每个维度的名称。这个名称会被显示到默认的 tooltip 中。
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest']
/// }
/// }
/// series: {
/// type: 'xxx',
/// dimensions: [
/// null, // 如果此维度不想给出定义,则使用 null 即可
/// {type: 'ordinal'}, // 只定义此维度的类型。
/// // 'ordinal' 表示离散型,一般文本使用这种类型。
/// // 如果类型没有被定义,会自动猜测类型。
/// {name: 'good', type: 'number'},
/// 'bad' // 等同于 {name: 'bad'}
/// ]
/// }
/// dimensions 数组中的每一项可以是:
/// string如 'someName',等同于 {name: 'someName'}
/// Object属性可以有
/// name: string。
/// type: string支持
/// number默认表示普通数据。
/// ordinal对于类目、文本这些 string 类型的数据,如果需要能在数轴上使用,须是 'ordinal' 类型。ECharts 默认会自动判断这个类型。但是自动判断也是不可能很完备的,所以使用者也可以手动强制指定。
/// float即 Float64Array。
/// int即 Int32Array。
/// time表示时间类型。设置成 'time' 则能支持自动解析数据成时间戳timestamp比如该维度的数据是 '2017-05-10',会自动被解析。时间类型的支持参见 data。
/// displayName: 一般用于 tooltip 中维度名的展示。string 如果没有指定,默认使用 name 来展示。
/// 值得一提的是,当定义了 dimensions 后,默认 tooltip 中对个维度的显示,会变为『竖排』,从而方便显示每个维度的名称。如果没有定义 dimensions则默认 tooltip 会横排显示,且只显示数值没有维度名称可显示。
/// </remark>
public Double[] Dimensions { get; set; }
/// <summary>可以定义 data 的哪个维度被编码成什么</summary>
/// <remark>
/// 比如:
/// option = {
/// dataset: {
/// source: [
/// // 每一列称为一个『维度』。
/// // 这里分别是维度 0、1、2、3、4。
/// [12, 44, 55, 66, 2],
/// [23, 6, 16, 23, 1],
/// ...
/// ]
/// },
/// series: {
/// type: 'xxx',
/// encode: {
/// x: [3, 1, 5], // 表示维度 3、1、5 映射到 x 轴。
/// y: 2, // 表示维度 2 映射到 y 轴。
/// tooltip: [3, 2, 4] // 表示维度 3、2、4 会在 tooltip 中显示。
/// }
/// }
/// }
/// 当使用 dimensions 给维度定义名称后encode 中可直接引用名称,例如:
/// series: {
/// type: 'xxx',
/// dimensions: ['date', 'open', 'close', 'highest', 'lowest'],
/// encode: {
/// x: 'date',
/// y: ['open', 'close', 'highest', 'lowest']
/// }
/// }
/// encode 声明的基本结构如下,其中冒号左边是坐标系、标签等特定名称,如 'x', 'y', 'tooltip' 等冒号右边是数据中的维度名string 格式或者维度的序号number 格式,从 0 开始计数),可以指定一个或多个维度(使用数组)。通常情况下,下面各种信息不需要所有的都写,按需写即可。
/// 下面是 encode 支持的属性:
/// // 在任何坐标系和系列中,都支持:
/// encode: {
/// // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示
/// tooltip: ['product', 'score']
/// // 使用第一个维度和第三个维度的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)
/// seriesName: [1, 3],
/// // 表示使用第二个维度中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画。
/// itemId: 2,
/// // 指定数据项的名称使用第三个维度在饼图等图表中有用可以使这个名字显示在图例legend中。
/// itemName: 3,
/// // 指定数据项的组 ID (groupId)。当全局过渡动画功能开启时setOption 前后拥有相同 groupId 的数据项会进行动画过渡。
/// itemGroupId: 4,
/// // 指定数据项对应的子数据组 ID (childGroupId),用于实现多层下钻和聚合。详见 childGroupId。
/// // 从 v5.5.0 开始支持
/// itemChildGroupId: 5
/// }
/// // 直角坐标系grid/cartesian特有的属性
/// encode: {
/// // 把 “维度1”、“维度5”、“名为 score 的维度” 映射到 X 轴:
/// x: [1, 5, 'score'],
/// // 把“维度0”映射到 Y 轴。
/// y: 0
/// }
/// // 单轴singleAxis特有的属性
/// encode: {
/// single: 3
/// }
/// // 极坐标系polar特有的属性
/// encode: {
/// radius: 3,
/// angle: 2
/// }
/// // 地理坐标系geo特有的属性
/// encode: {
/// lng: 3,
/// lat: 2
/// }
/// // 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:
/// encode: {
/// value: 3
/// }
/// 这是个更丰富的 encode 的示例:
/// 特殊地,在 自定义系列custom seriesencode 中轴可以不指定或设置为 null/undefined从而使系列免于受这个轴控制也就是说轴的范围extent不会受此系列数值的影响轴被 dataZoom 控制时也不会过滤掉这个系列:
/// var option = {
/// xAxis: {},
/// yAxis: {},
/// dataZoom: [{
/// xAxisIndex: 0
/// }, {
/// yAxisIndex: 0
/// }],
/// series: {
/// type: 'custom',
/// renderItem: function (params, api) {
/// return {
/// type: 'circle',
/// shape: {
/// cx: 100, // x 位置永远为 100
/// cy: api.coord([0, api.value(0)])[1],
/// r: 30
/// },
/// style: {
/// fill: 'blue'
/// }
/// };
/// },
/// encode: {
/// // 这样这个系列就不会被 x 轴以及 x
/// // 轴上的 dataZoom 控制了。
/// x: -1,
/// y: 1
/// },
/// data: [ ... ]
/// }
/// };
/// </remark>
public Object Encode { get; set; }
/// <summary></summary>
/// <remark>
/// 当使用 dataset 时seriesLayoutBy 指定了 dataset 中用行还是列对应到系列上,也就是说,系列“排布”到 dataset 的行还是列上。可取值:
/// 'column'默认dataset 的列对应于系列,从而 dataset 中每一列是一个维度dimension
/// 'row'dataset 的行对应于系列,从而 dataset 中每一行是一个维度dimension
/// 参见这个 示例
/// </remark>
public String SeriesLayoutBy { get; set; }
/// <summary></summary>
/// <remark>如果 series.data 没有指定,并且 dataset 存在,那么就会使用 dataset。datasetIndex 指定本系列使用哪个 dataset。</remark>
public Double? DatasetIndex { get; set; }
/// <summary>该系列所有数据项的组 ID优先级低于groupId</summary>
/// <remark>详见series.data.groupId。</remark>
public String DataGroupId { get; set; }
/// <summary>系列中的数据内容数组</summary>
/// <remark>
/// 数组项通常为具体的数据项。
/// 注意,如果系列没有指定 data并且 option 有 dataset那么默认使用第一个 dataset。如果指定了 data则不会再使用 dataset。
/// 可以使用 series.datasetIndex 指定其他的 dataset。
/// 通常来说,数据用一个二维数组表示。如下,每一列被称为一个『维度』。
/// series: [{
/// data: [
/// // 维度X 维度Y 其他维度 ...
/// [ 3.4, 4.5, 15, 43],
/// [ 4.2, 2.3, 20, 91],
/// [ 10.8, 9.5, 30, 18],
/// [ 7.2, 8.8, 18, 57]
/// ]
/// }]
/// 在 直角坐标系 (grid) 中『维度X』和『维度Y』会默认对应于 xAxis 和 yAxis。
/// 在 极坐标系 (polar) 中『维度X』和『维度Y』会默认对应于 radiusAxis 和 angleAxis。
/// 后面的其他维度是可选的,可以在别处被使用,例如:
/// 在 visualMap 中可以将一个或多个维度映射到颜色,大小等多个图形属性上。
/// 在 series.symbolSize 中可以使用回调函数,基于某个维度得到 symbolSize 值。
/// 使用 tooltip.formatter 或 series.label.formatter 可以把其他维度的值展示出来。
/// 特别地当只有一个轴为类目轴axis.type 为 'category')的时候,数据可以简化用一个一维数组表示。例如:
/// xAxis: {
/// data: ['a', 'b', 'm', 'n']
/// },
/// series: [{
/// // 与 xAxis.data 一一对应。
/// data: [23, 44, 55, 19]
/// // 它其实是下面这种形式的简化:
/// // data: [[0, 23], [1, 44], [2, 55], [3, 19]]
/// }]
/// 『值』与 轴类型 的关系:
/// 当某维度对应于数值轴axis.type 为 'value' 或者 'log')的时候:
/// 其值可以为 number例如 12也可以兼容 string 形式的 number例如 '12'
/// 当某维度对应于类目轴axis.type 为 'category')的时候:
/// 其值须为类目的『序数』(从 0 开始)或者类目的『字符串值』。例如:
/// xAxis: {
/// type: 'category',
/// data: ['星期一', '星期二', '星期三', '星期四']
/// },
/// yAxis: {
/// type: 'category',
/// data: ['a', 'b', 'm', 'n', 'p', 'q']
/// },
/// series: [{
/// data: [
/// // xAxis yAxis
/// [ 0, 0, 2 ], // 意思是此点位于 xAxis: '星期一', yAxis: 'a'。
/// [ '星期四', 2, 1 ], // 意思是此点位于 xAxis: '星期四', yAxis: 'm'。
/// [ 2, 'p', 2 ], // 意思是此点位于 xAxis: '星期三', yAxis: 'p'。
/// [ 3, 3, 5 ]
/// ]
/// }]
/// 双类目轴的示例可以参考 Github Punchcard 示例。
/// 当某维度对应于时间轴type 为 'time')的时候,值可以为:
/// 一个时间戳,如 1484141700832表示 UTC 时间。
/// 或者字符串形式的时间描述:
/// ISO 8601 的子集,只包含这些形式(这几种格式,除非指明时区,否则均表示本地时间,与 moment 一致):
/// 部分年月日时间: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06'.
/// 使用 'T' 或空格分割: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123'.
/// 时区设定: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00'.
/// 其他的时间字符串,包括(均表示本地时间):
/// '2012', '2012-3-1', '2012/3/1', '2012/03/01',
/// '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
/// 或者用户自行初始化的 Date 实例:
/// 注意,用户自行初始化 Date 实例的时候,浏览器的行为有差异,不同字符串的表示也不同。
/// 例如:在 chrome 中new Date('2012-01-01') 表示 UTC 时间的 2012 年 1 月 1 日,而 new Date('2012-1-1') 和 new Date('2012/01/01') 表示本地时间的 2012 年 1 月 1 日。在 safari 中,不支持 new Date('2012-1-1') 这种表示方法。
/// 所以,使用 new Date(dataString) 时,可使用第三方库解析(如 moment或者使用 echarts.time.parse或者参见 这里。
/// 当需要对个别数据进行个性化定义时:
/// 数组项可用对象,其中的 value 像表示具体的数值,如:
/// [
/// 12,
/// 34,
/// {
/// value : 56,
/// //自定义标签样式,仅对该数据项有效
/// label: {},
/// //自定义特殊 itemStyle仅对该数据项有效
/// itemStyle:{}
/// },
/// 10
/// ]
/// // 或
/// [
/// [12, 33],
/// [34, 313],
/// {
/// value: [56, 44],
/// label: {},
/// itemStyle:{}
/// },
/// [10, 33]
/// ]
/// 空值:
/// 当某数据不存在时ps不存在不代表值为 0可以用 '-' 或者 null 或者 undefined 或者 NaN 表示。
/// 例如,无数据在折线图中可表现为该点是断开的,在其它图中可表示为图形不存在。
/// </remark>
public override Object[] Data { get; set; }
///// <summary>图表标注</summary>
//public Object MarkPoint { get; set; }
///// <summary>图表标线</summary>
//public Object MarkLine { get; set; }
/// <summary>图表标域,常用于标记图表中某个范围的数据,例如标出某段时间投放了广告。</summary>
public Object MarkArea { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v4.4.0 开始支持
/// 是否裁剪超出坐标系部分的图形,具体裁剪效果根据系列决定:
/// 散点图/带有涟漪特效动画的散点(气泡)图:忽略中心点超出坐标系的图形,但是不裁剪单个图形
/// 柱状图:裁掉完全超出的柱子,但是不会裁剪只超出部分的柱子
/// 折线图:裁掉所有超出坐标系的折线部分,拐点图形的逻辑按照散点图处理
/// 路径图:裁掉所有超出坐标系的部分
/// K 线图:忽略整体都超出坐标系的图形,但是不裁剪单个图形
/// 象形柱图:裁掉所有超出坐标系的部分(从 v5.5.0 开始支持)
/// 自定义系列:裁掉所有超出坐标系的部分
/// 除了象形柱图和自定义系列,其它系列的默认值都为 true及开启裁剪如果你觉得不想要裁剪的话可以设置成 false 关闭。
/// </remark>
public Boolean? Clip { get; set; }
/// <summary>散点图所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>散点图组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>图形是否不响应和触发鼠标事件,默认为 false即响应和触发鼠标事件。</summary>
public Boolean? Silent { get; set; }
/// <summary>是否开启动画</summary>
public Boolean? Animation { get; set; }
/// <summary>是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。</summary>
public Double? AnimationThreshold { get; set; }
/// <summary>初始动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的初始动画效果:
/// animationDuration: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDuration { get; set; }
/// <summary>初始动画的缓动效果</summary>
/// <remark>不同的缓动效果可以参考 缓动示例。</remark>
public String AnimationEasing { get; set; }
/// <summary></summary>
/// <remark>
/// 初始动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的初始动画效果。
/// 如下示例:
/// animationDelay: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelay { get; set; }
/// <summary>数据更新动画的时长</summary>
/// <remark>
/// 支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的更新动画效果:
/// animationDurationUpdate: function (idx) {
/// // 越往后的数据时长越大
/// return idx * 100;
/// }
/// </remark>
public Object AnimationDurationUpdate { get; set; }
/// <summary>数据更新动画的缓动效果</summary>
public String AnimationEasingUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 数据更新动画的延迟,支持回调函数,可以通过每个数据返回不同的 delay 时间实现更戏剧的更新动画效果。
/// 如下示例:
/// animationDelayUpdate: function (idx) {
/// // 越往后的数据延迟越大
/// return idx * 100;
/// }
/// 也可以看该示例
/// </remark>
public Object AnimationDelayUpdate { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.2.0 开始支持
/// 全局过渡动画相关的配置。
/// 全局过渡动画Universal Transition提供了任意系列之间进行变形动画的功能。开启该功能后每次setOption相同id的系列之间会自动关联进行动画的过渡更细粒度的关联配置见universalTransition.seriesKey配置。
/// 通过配置数据项的groupId和childGroupId还可以实现诸如下钻聚合等一对多或者多对一的动画。
/// 可以直接在系列中配置 universalTransition: true 开启该功能。也可以提供一个对象进行更多属性的配置。
/// </remark>
public Object UniversalTransition { get; set; }
/// <summary>本系列特定的 tooltip 设定</summary>
public Object Tooltip { get; set; }
}

View File

@ -10,6 +10,9 @@
/// </remark>
public class SeriesSunburst : Series
{
/// <summary>实例化旭日图</summary>
public SeriesSunburst() => Type = "sunburst";
//public String Type { get; set; } = "sunburst";
///// <summary>组件 ID</summary>

View File

@ -0,0 +1,197 @@
namespace NewLife.Cube.Charts;
/// <summary>主题河流</summary>
/// <remark>
/// 是一种特殊的流图, 它主要用来表示事件或主题等在一段时间内的变化。
/// 示例:
/// 可视编码:
/// 主题河流中不同颜色的条带状河流分支编码了不同的事件或主题河流分支的宽度编码了原数据集中的value值。
/// 此外,原数据集中的时间属性,映射到单个时间轴上。
/// </remark>
public class SeriesThemeRiver : Series
{
/// <summary>实例化主题河流</summary>
public SeriesThemeRiver() => Type = "themeRiver";
//public String Type { get; set; } = "themeRiver";
///// <summary>组件 ID</summary>
///// <remark>默认不指定。指定则可用于在 option 或者 API 中引用组件。</remark>
//public String Id { get; set; }
///// <summary></summary>
///// <remark>系列名称用于tooltip的显示legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。</remark>
//public String Name { get; set; }
///// <summary></summary>
///// <remark>
///// 从 v5.2.0 开始支持
///// 从调色盘 option.color 中取色的策略,可取值为:
///// 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
///// 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
///// </remark>
//public String ColorBy { get; set; }
/// <summary>所有图形的 zlevel 值</summary>
/// <remark>
/// zlevel用于 Canvas 分层不同zlevel值的图形会放置在不同的 Canvas 中Canvas 分层是一种常见的优化手段。我们可以把一些图形变化频繁例如有动画的组件设置成一个单独的zlevel。需要注意的是过多的 Canvas 会引起内存开销的增大,在手机端上需要谨慎使用以防崩溃。
/// zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。
/// </remark>
public Double? Zlevel { get; set; }
/// <summary>组件的所有图形的z值</summary>
/// <remark>
/// 控制图形的前后顺序。z值小的图形会被z值大的图形覆盖。
/// z相比zlevel优先级更低而且不会创建新的 Canvas。
/// </remark>
public Double? Z { get; set; }
/// <summary>thmemRiver组件离容器左侧的距离</summary>
/// <remark>
/// left 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'left', 'center', 'right'。
/// 如果 left 的值为 'left', 'center', 'right',组件会根据相应的位置自动对齐。
/// </remark>
public Object Left { get; set; }
/// <summary>thmemRiver组件离容器上侧的距离</summary>
/// <remark>
/// top 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比,也可以是 'top', 'middle', 'bottom'。
/// 如果 top 的值为 'top', 'middle', 'bottom',组件会根据相应的位置自动对齐。
/// </remark>
public Object Top { get; set; }
/// <summary>thmemRiver组件离容器右侧的距离</summary>
/// <remark>right 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。</remark>
public Object Right { get; set; }
/// <summary>thmemRiver组件离容器下侧的距离</summary>
/// <remark>bottom 的值可以是像 20 这样的具体像素值,可以是像 '20%' 这样相对于容器高宽的百分比。</remark>
public Object Bottom { get; set; }
/// <summary>thmemRiver组件的宽度</summary>
public Object Width { get; set; }
/// <summary>thmemRiver组件的高度</summary>
/// <remark>
/// 注意:
/// 整个主题河流view的位置信息复用了单个时间轴的位置信息即lefttoprightbottom。
/// </remark>
public Object Height { get; set; }
/// <summary>坐标系统,主题河流用的是单个的时间轴</summary>
public String CoordinateSystem { get; set; }
/// <summary></summary>
/// <remark>图中与坐标轴正交的方向的边界间隙,设置该值是为了调整图的位置,使其尽量处于屏幕的正中间,避免处于屏幕的上方或下方。</remark>
public Double[] BoundaryGap { get; set; }
/// <summary>单个时间轴的index默认值为0因为只有单个轴</summary>
public Double? SingleAxisIndex { get; set; }
/// <summary>label 描述了主题河流中每个带状河流分支对应的文本标签的样式。</summary>
public Object Label { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的视觉引导线配置。
/// </remark>
public Object LabelLine { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 标签的统一布局配置。
/// 该配置项是在每个系列默认的标签布局基础上,统一调整标签的(x, y)位置,标签对齐等属性以实现想要的标签布局效果。
/// 该配置项也可以是一个有如下参数的回调函数
/// // 标签对应数据的 dataIndex
/// dataIndex: number
/// // 标签对应的数据类型,只在关系图中会有 node 和 edge 数据类型的区分
/// dataType?: string
/// // 标签对应的系列的 index
/// seriesIndex: number
/// // 标签显示的文本
/// text: string
/// // 默认的标签的包围盒,由系列默认的标签布局决定
/// labelRect: {x: number, y: number, width: number, height: number}
/// // 默认的标签水平对齐
/// align: 'left' | 'center' | 'right'
/// // 默认的标签垂直对齐
/// verticalAlign: 'top' | 'middle' | 'bottom'
/// // 标签所对应的数据图形的包围盒,可用于定位标签位置
/// rect: {x: number, y: number, width: number, height: number}
/// // 默认引导线的位置,目前只有饼图(pie)和漏斗图(funnel)有默认标签位置
/// // 如果没有该值则为 null
/// labelLinePoints?: number[][]
/// 示例:
/// 将标签显示在图形右侧 10px 的位置,并且垂直居中:
/// labelLayout(params) {
/// return {
/// x: params.rect.x + 10,
/// y: params.rect.y + params.rect.height / 2,
/// verticalAlign: 'middle',
/// align: 'left'
/// }
/// }
/// 根据图形的包围盒尺寸决定文本尺寸
/// labelLayout(params) {
/// return {
/// fontSize: Math.max(params.rect.width / 10, 5)
/// };
/// }
/// </remark>
public Object LabelLayout { get; set; }
/// <summary>主题河流中每个带状河流分支的样式</summary>
public Object ItemStyle { get; set; }
/// <summary>高亮状态的配置</summary>
public Object Emphasis { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 淡出状态的配置。
/// </remark>
public Object Blur { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中状态的配置。
/// </remark>
public Object Select { get; set; }
/// <summary></summary>
/// <remark>
/// 从 v5.0.0 开始支持
/// 选中模式的配置,表示是否支持多个选中,默认关闭,支持布尔值和字符串,字符串取值可选'single''multiple''series' 分别表示单选,多选以及选择整个系列。
/// 从 v5.3.0 开始支持 'series'。
/// </remark>
public Object SelectedMode { get; set; }
/// <summary></summary>
/// <remark>
/// data: [
/// ["2015/11/09",10,"DQ"],
/// ["2015/11/10",10,"DQ"],
/// ["2015/11/11",10,"DQ"],
/// ["2015/11/08",10,"SS"],
/// ["2015/11/09",10,"SS"],
/// ["2015/11/10",10,"SS"],
/// ["2015/11/11",10,"SS"],
/// ["2015/11/12",10,"SS"],
/// ["2015/11/13",10,"QG"],
/// ["2015/11/08",10,"QG"],
/// ["2015/11/11",10,"QG"],
/// ["2015/11/13",10,"QG"],
/// ]
/// 数据说明:
/// 如上所示主题河流的数据格式是二维数组的形式里层数组的每一项由事件或主题的时间属性、事件或主题在某个时间点的值以及事件或主题的名称组成。值得注意的是一定要提供一个具有完整时间段的事件或主题作为主干河流其他事件或主题以该主干河流为依据将缺省的时间点上的值补为0也就是说其他事件或主题的时间段是包含在主干河流内的如果超出布局会出错这么做的原因是在计算整个图的布局的时候要计算一条baseline以便将每个事情画成流带状。如上图中的"SS"这一事件就是一个主干河流,经过处理,我们会将"DQ"中缺省的三个时间点以["2015/11/08",0,"DQ"]["2015/11/12",0,"DQ"]"2015/11/13",0,"DQ"]的格式补齐,使其与主干河流对其。从中还可以看出,我们可以在完整时间段的任意位置缺省。
/// </remark>
public override Object[] Data { get; set; }
/// <summary>本系列特定的 tooltip 设定</summary>
public Object Tooltip { get; set; }
}

View File

@ -9,6 +9,9 @@
/// </remark>
public class SeriesTree : Series
{
/// <summary>实例化树图</summary>
public SeriesTree() => Type = "tree";
//public String Type { get; set; } = "tree";
///// <summary>组件 ID</summary>

View File

@ -23,6 +23,9 @@
/// </remark>
public class SeriesTreemap : Series
{
/// <summary>实例化矩形树图</summary>
public SeriesTreemap() => Type = "treemap";
//public String Type { get; set; } = "treemap";
///// <summary>组件 ID</summary>

View File

@ -4,7 +4,7 @@
public enum SeriesTypes
{
/// <summary>折线图</summary>
Line,
Line = 1,
/// <summary>柱状图</summary>
Bar,
@ -15,15 +15,66 @@ public enum SeriesTypes
/// <summary>散点图</summary>
Scatter,
/// <summary>关系图</summary>
Graph,
/// <summary>地图</summary>
Map,
/// <summary>K线图</summary>
Candlestick,
/// <summary>雷达图</summary>
Radar,
/// <summary>箱形图</summary>
Boxplot,
/// <summary>热力图</summary>
Heatmap,
/// <summary>关系图</summary>
Graph,
/// <summary>路径图</summary>
Lines,
/// <summary>树图</summary>
Tree,
/// <summary>层级数据</summary>
/// <summary>矩形树图</summary>
Treemap,
/// <summary>旭日图</summary>
Sunburst,
/// <summary>平行坐标系</summary>
Parallel,
/// <summary>桑基图</summary>
Sankey,
/// <summary>漏斗图</summary>
Funnel,
/// <summary>仪表盘</summary>
Gauge,
/// <summary>象形柱图</summary>
PictorialBar,
/// <summary>主题河流</summary>
ThemeRiver,
/// <summary>自定义系列</summary>
Custom,
/// <summary>三维折线图</summary>
Line3D,
/// <summary>三维飞线图</summary>
Lines3D,
/// <summary>三维柱状图</summary>
Bar3D,
/// <summary>特效散点图</summary>
EffectScatter,
}

View File

@ -28,6 +28,10 @@ public static class MiddlewareHelper
(u.Host.IsNullOrEmpty() || uri.Host.EqualIgnoreCase(u.Host)) &&
(u.Port == 0 || u.Port == uri.Port)) return false;
// 本地地址不允许跳转
if (uri.Host.EqualIgnoreCase("localhost", "127.0.0.1")) return false;
if (uri.Host.IsMatch("127.*")) return false;
using var span = DefaultTracer.Instance?.NewSpan("ForceRedirect", uri + "");
span?.AppendTag($"规则:{set.ForceRedirect}");