Hi,
here is the full version with input colors (Dynamo Colors)
import clr
import sys
import System
from System.IO import StringReader, FileStream, FileMode, MemoryStream, File, Path
from System.Collections.Generic import List
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
clr.AddReference("LiveChartsCore")
clr.AddReference("LiveChartsCore.SkiaSharpView")
clr.AddReference("LiveChartsCore.SkiaSharpView.WPF")
clr.AddReference('SkiaSharp')
import LiveChartsCore
from LiveChartsCore import *
from LiveChartsCore.SkiaSharpView import *
from LiveChartsCore.SkiaSharpView import PieSeries
from LiveChartsCore.SkiaSharpView.WPF import *
from SkiaSharp import SKColors, SKColor, SKColorF
from LiveChartsCore.SkiaSharpView.VisualElements import LabelVisual
from LiveChartsCore.SkiaSharpView.Painting import SolidColorPaint
clr.AddReference("System.Xml")
clr.AddReference("PresentationFramework")
clr.AddReference("System.Xml")
clr.AddReference("PresentationCore")
clr.AddReference("System.Windows")
import System.Windows.Controls
from System.Windows.Controls import *
import System.Windows.Controls.Primitives
from System.IO import StringReader
from System.Xml import XmlReader
from System.Windows import LogicalTreeHelper
from System.Windows.Markup import XamlReader, XamlWriter
from System.Windows import Window, Application
from System.Windows.Media.Imaging import RenderTargetBitmap, PngBitmapEncoder, BitmapFrame
import traceback
import time
# https://v0.lvcharts.com/App/examples/v1/Wpf/Pie%20or%20Doughnut
class MainWindow(Window):
LAYOUT2 = '''
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
Title="LiveCharts"
Width="404"
Height="500">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<UserControl Grid.Row="0" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="500">
<Grid>
<lvc:PieChart Name="Chart" LegendPosition="Bottom" />
</Grid>
</UserControl>
<!-- Add the Save Chart button at the bottom -->
<Button Grid.Row="1" Name="SaveButton" Content="Push on a draft view" Height="30" Margin="10"/>
</Grid>
</Window>'''
def __init__(self, title, keys, values, ds_colors):
super().__init__()
self.title = title
self._keys = keys
self._values = values
self._ds_colors = ds_colors
self.img_stream = None
xr = XmlReader.Create(StringReader(MainWindow.LAYOUT2))
self.winLoad = XamlReader.Load(xr)
# initialize a SeriesCollection and bind it to the PieChart
self.seriesCollection = List[ISeries]()
# populate the PieChart with data
for key, value, ds_color in zip(keys, values, ds_colors):
pie_series = PieSeries[float]()
pie_series.Values = [value]
pie_series.Name = key
# convert dynamo color to hex color
hex_color = "#{:02X}{:02X}{:02X}".format(ds_color.Red, ds_color.Green, ds_color.Blue)
sk_color = SKColor.Parse(hex_color)
pie_series.Fill = SolidColorPaint(sk_color)
self.seriesCollection.Add(pie_series)
self.InitializeComponent()
def InitializeComponent(self):
#
try:
self.SaveButton = LogicalTreeHelper.FindLogicalNode(self.winLoad, "SaveButton")
self.SaveButton.Click += self.save_button_clicked
#
self.Chart = LogicalTreeHelper.FindLogicalNode(self.winLoad, "Chart")
self.Chart.Series = self.seriesCollection
# set the title using LabelVisual
lb_title = LabelVisual()
lb_title.Text=self.title
lb_title.TextSize=20
lb_title.Paint=SolidColorPaint(SKColors.Black)
self.Chart.Title = lb_title
except Exception as ex:
print(str(ex))
def save_button_clicked(self, sender, args):
"""Event handler for the Save Chart button click"""
try:
self.save_chart_to_memory()
self.winLoad.Close()
except Exception as e:
print(f"Error saving chart as image: {e}")
def save_chart_to_memory(self):
try:
# use RenderTargetBitmap to capture the visual content of the chart
dpi = 300
size = self.Chart.RenderSize
width = int(size.Width * dpi / 96)
height = int(size.Height * dpi / 96)
render_bitmap = RenderTargetBitmap(width, height, dpi, dpi, System.Windows.Media.PixelFormats.Pbgra32)
# Render the chart's visual tree to the RenderTargetBitmap
render_bitmap.Render(self.Chart)
# Prepare to save the rendered bitmap to a file
encoder = PngBitmapEncoder()
frames = List[BitmapFrame](encoder.Frames)
frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(render_bitmap))
encoder.Frames = frames
# save image to memoryStream
self.img_stream = MemoryStream()
encoder.Save(self.img_stream)
# reset the memory stream position to the beginning
self.img_stream.Seek(0, System.IO.SeekOrigin.Begin)
print(f"Chart successfully saved to memomry")
except Exception as e:
print(f"Error saving chart as image: {e}")
def create_draft_view(view_name):
filter_Name = System.Predicate[System.Object](lambda x : x.ViewFamily == ViewFamily.Drafting )
view_family_type = List[Element](FilteredElementCollector(doc).OfClass(ViewFamilyType).ToElements()).Find(filter_Name)
#
drafting_view = ViewDrafting.Create(doc, view_family_type.Id)
try:
drafting_view.Name = view_name
except:
drafting_view.Name = f"{view_name}_{int(time.time())}"
return drafting_view
def create_image_on_draft_view(img_stream, view_name):
TransactionManager.Instance.EnsureInTransaction(doc)
#
dft_view = create_draft_view(view_name)
#
temp_file_path = Path.GetTempFileName()
temp_file_path_png = Path.ChangeExtension(temp_file_path, ".png")
with File.OpenWrite(temp_file_path_png) as temp_file_stream:
img_stream.CopyTo(temp_file_stream)
#
image_options = ImageTypeOptions(temp_file_path_png, False, ImageTypeSource.Import)
placement_options = ImagePlacementOptions()
placement_options.PlacementPoint = BoxPlacement.Center
placement_options.Location = XYZ.Zero
#
image_type = ImageType.Create(doc, image_options)
image_instance = ImageInstance.Create(doc, dft_view, image_type.Id, placement_options)
#
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.ForceCloseTransaction()
uidoc.RequestViewChange(dft_view)
return image_instance
my_window = MainWindow(IN[0], IN[1], IN[2], IN[3])
my_window.winLoad.ShowDialog()
if my_window.img_stream is not None:
OUT = create_image_on_draft_view(my_window.img_stream, my_window.title)