diff --git a/CHANGELOG.md b/CHANGELOG.md
index 29588113..2922f202 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -58,6 +58,7 @@
## master
+* (2022.09.22) 增加`SaveAsImage()`接口保存图表到图片
* (2022.09.21) 修复`InsertSerie()`接口不刷新图表的问题
* (2022.09.21) 优化`PolarChart`对`Line`热力图的支持
* (2022.09.20) 增加`PolarChart`对`Heatmap`热力图的支持
diff --git a/Editor/Charts/BaseChartEditor.cs b/Editor/Charts/BaseChartEditor.cs
index 617d12ef..fc9f39d7 100644
--- a/Editor/Charts/BaseChartEditor.cs
+++ b/Editor/Charts/BaseChartEditor.cs
@@ -16,6 +16,7 @@ namespace XCharts.Editor
public static readonly GUIContent btnAddComponent = new GUIContent("Add Main Component", "");
public static readonly GUIContent btnCovertXYAxis = new GUIContent("Covert XY Axis", "");
public static readonly GUIContent btnRebuildChartObject = new GUIContent("Rebuild Chart Object", "");
+ public static readonly GUIContent btnSaveAsImage = new GUIContent("Save As Image", "");
public static readonly GUIContent btnCheckWarning = new GUIContent("Check Warning", "");
public static readonly GUIContent btnHideWarning = new GUIContent("Hide Warning", "");
}
@@ -279,6 +280,10 @@ namespace XCharts.Editor
{
m_Chart.RebuildChartObject();
}
+ if (GUILayout.Button(Styles.btnSaveAsImage))
+ {
+ m_Chart.SaveAsImage();
+ }
if (m_CheckWarning)
{
EditorGUILayout.BeginHorizontal();
diff --git a/Plugins.meta b/Plugins.meta
new file mode 100644
index 00000000..a60003bb
--- /dev/null
+++ b/Plugins.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6558d1464a47441d18df18c4a403b2f2
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Plugins/Download.jslib b/Plugins/Download.jslib
new file mode 100644
index 00000000..cc5b8886
--- /dev/null
+++ b/Plugins/Download.jslib
@@ -0,0 +1,24 @@
+mergeInto(LibraryManager.library, {
+ Download: function (str, fn) {
+ var msg = UTF8ToString(str);
+ var fname = UTF8ToString(fn);
+ function fixBinary(bin) {
+ var length = bin.length;
+ var buf = new ArrayBuffer(length);
+ var arr = new Uint8Array(buf);
+ for (var i = 0; i < length; i++) {
+ arr[i] = bin.charCodeAt(i);
+ }
+ return buf;
+ }
+ var binary = fixBinary(atob(msg));
+ var data = new Blob([binary]);
+ var link = document.createElement('a');
+ link.download = fname;
+ link.href = URL.createObjectURL(data);
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ }
+});
+
diff --git a/Plugins/Download.jslib.meta b/Plugins/Download.jslib.meta
new file mode 100644
index 00000000..c2c8647a
--- /dev/null
+++ b/Plugins/Download.jslib.meta
@@ -0,0 +1,34 @@
+fileFormatVersion: 2
+guid: 821b9cd60f13648a396c76481da2191c
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Facebook: WebGL
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ WebGL: WebGL
+ second:
+ enabled: 1
+ settings: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Runtime/Internal/BaseChart.API.cs b/Runtime/Internal/BaseChart.API.cs
index 765355c1..68c279cc 100644
--- a/Runtime/Internal/BaseChart.API.cs
+++ b/Runtime/Internal/BaseChart.API.cs
@@ -588,5 +588,15 @@ namespace XCharts.Runtime
SerieHelper.GetItemColor(out color, out toColor, serie, null, m_Theme);
return color;
}
+
+ ///
+ /// 保存图表为图片。
+ ///
+ /// type of image: png, jpg, exr
+ /// save path
+ public void SaveAsImage(string imageType = "png", string savePath = "")
+ {
+ StartCoroutine(SaveAsImageSync(imageType, savePath));
+ }
}
}
\ No newline at end of file
diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs
index 23cbca1e..f9ea93c1 100644
--- a/Runtime/Internal/BaseChart.cs
+++ b/Runtime/Internal/BaseChart.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
@@ -741,5 +742,11 @@ namespace XCharts.Runtime
InitComponentHandlers();
InitSerieHandlers();
}
+
+ private IEnumerator SaveAsImageSync(string imageType, string path)
+ {
+ yield return new WaitForEndOfFrame();
+ ChartHelper.SaveAsImage(rectTransform, canvas, imageType, path);
+ }
}
}
\ No newline at end of file
diff --git a/Runtime/Internal/Utilities/ChartHelper.cs b/Runtime/Internal/Utilities/ChartHelper.cs
index be19f64a..63025ade 100644
--- a/Runtime/Internal/Utilities/ChartHelper.cs
+++ b/Runtime/Internal/Utilities/ChartHelper.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
@@ -896,5 +897,62 @@ namespace XCharts.Runtime
if (valueOrRate >= -maxRate && valueOrRate <= maxRate) return valueOrRate * total;
else return valueOrRate;
}
+
+ [DllImport("__Internal")]
+ private static extern void Download(string base64str, string fileName);
+
+ public static Texture2D SaveAsImage(RectTransform rectTransform, Canvas canvas, string imageType = "png", string path = "")
+ {
+ var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera;
+ var pos = RectTransformUtility.WorldToScreenPoint(cam, rectTransform.position);
+ var width = rectTransform.rect.width * canvas.scaleFactor;
+ var height = rectTransform.rect.height * canvas.scaleFactor;
+ var posX = pos.x + rectTransform.rect.xMin * canvas.scaleFactor;
+ var posY = pos.y + rectTransform.rect.yMin * canvas.scaleFactor;
+ var rect = new Rect(posX, posY, width, height);
+ var tex = new Texture2D((int) width, (int) height, TextureFormat.RGBA32, false);
+ tex.ReadPixels(rect, 0, 0);
+ tex.Apply();
+ byte[] bytes;
+ switch (imageType)
+ {
+ case "png":
+ bytes = tex.EncodeToPNG();
+ break;
+ case "jpg":
+ bytes = tex.EncodeToJPG();
+ break;
+ case "exr":
+ bytes = tex.EncodeToEXR();
+ break;
+ default:
+ Debug.LogError("SaveAsImage ERROR: not support image type:" + imageType);
+ return null;
+ }
+ var fileName = rectTransform.name + "." + imageType;
+#if UNITY_WEBGL
+ string base64str = Convert.ToBase64String(bytes);
+ Download(base64str, fileName);
+ Debug.Log("SaveAsImage: download by brower:" + fileName);
+ return tex;
+#endif
+ if (string.IsNullOrEmpty(path))
+ {
+ var dir = Application.persistentDataPath + "/SavedImage";
+#if UNITY_EDITOR
+ dir = Application.dataPath + "/../SavedImage";
+#else
+ dir = Application.persistentDataPath + "/SavedImage";
+#endif
+ if (!System.IO.Directory.Exists(dir))
+ {
+ System.IO.Directory.CreateDirectory(dir);
+ }
+ path = dir + "/" + fileName;
+ }
+ System.IO.File.WriteAllBytes(path, bytes);
+ Debug.Log("SaveAsImage:" + path);
+ return tex;
+ }
}
}
\ No newline at end of file