Last active
May 28, 2022 07:45
-
-
Save Cyril-Pop/e492a7b75560cb17f323c075e384166a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import clr | |
import sys | |
import re | |
import System | |
clr.AddReference('ProtoGeometry') | |
from Autodesk.DesignScript.Geometry import * | |
import Autodesk.DesignScript.Geometry as DS | |
#import Revit API | |
clr.AddReference('RevitAPI') | |
import Autodesk | |
from Autodesk.Revit.DB import * | |
import Autodesk.Revit.DB as DB | |
clr.AddReference('RevitServices') | |
import RevitServices | |
from RevitServices.Persistence import DocumentManager | |
from RevitServices.Transactions import TransactionManager | |
doc = DocumentManager.Instance.CurrentDBDocument | |
my_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) | |
reDir = System.IO.DirectoryInfo(re.__file__) | |
path_py3_lib = reDir.Parent.Parent.FullName | |
sys.path.append(path_py3_lib + r'\Lib\site-packages') | |
import pandas as pd | |
import numpy as np | |
from typing import Union | |
import webbrowser | |
import codecs | |
from bs4 import BeautifulSoup as bs | |
class WrapDFrame(): | |
dictUnitValue = {} | |
def __init__(self, data: Union[DB.ViewSchedule , pd.core.frame.DataFrame]): | |
self.lstError = [] | |
if isinstance(data, pd.DataFrame): | |
self._df = data | |
elif isinstance(data, pd.Series): | |
self._df = data.to_frame() | |
else: | |
self._df = self.__getDF_From_View(data) | |
# | |
def __getDF_From_View(self, data): | |
""" | |
convert Schedule to DataFrame (private method) | |
""" | |
viewschedule = data | |
outvalue = [] | |
if viewschedule.ViewType == ViewType.PanelSchedule: | |
tabledata = viewschedule.GetSectionData(SectionType.Body) | |
else: | |
tabledata = viewschedule.GetTableData().GetSectionData(SectionType.Body) | |
# | |
paraSchNames = [] | |
nbrCol = tabledata.NumberOfColumns | |
nbrRow = tabledata.NumberOfRows | |
for r in range(nbrRow): | |
if r == 0: | |
for c in range(nbrCol): | |
paraSchNames.append(viewschedule.GetCellText(SectionType.Body, r, c)) | |
else: | |
temp = [] | |
unit_header = [] | |
#get values by Rows | |
for c in range(nbrCol): | |
unitType = tabledata.GetCellSpec(r,c) | |
is_unitType = True if len(unitType.TypeId) > 0 else False | |
# | |
if tabledata.GetCellType(r,c) == CellType.Text or tabledata.GetCellType(r,c) == CellType.ParameterText: | |
valueCell = tabledata.GetCellText(r,c) | |
valueCell, unitstr = self.__to_Float(valueCell) if is_unitType else (valueCell, "") | |
temp.append(valueCell) | |
unit_header.append(unitstr) | |
# | |
elif tabledata.GetCellType(r,c) == CellType.Parameter: | |
try: | |
valueCell = viewschedule.GetParamValue(SectionType.Body, r , c ) | |
valueCell, unitstr = self.__to_Float(valueCell) if is_unitType else (valueCell, "") | |
temp.append(valueCell) | |
unit_header.append(unitstr) | |
except: | |
valueCell = viewschedule.GetCellText(SectionType.Body, r , c ) | |
valueCell, unitstr = self.__to_Float(valueCell) if is_unitType else (valueCell, "") | |
temp.append(valueCell) | |
unit_header.append(unitstr) | |
# | |
elif tabledata.GetCellType(r,c) == CellType.CalculatedValue: | |
valueCell = tabledata.GetCellCalculatedValue(r,c) | |
valueCell, unitstr = self.__to_Float(valueCell) if is_unitType else (valueCell, "") | |
temp.append(valueCell) | |
unit_header.append(unitstr) | |
if len(temp) >= 1: | |
# replace empty value by NaN | |
temp = [x if x != "" else np.nan for x in temp] | |
outvalue.append(temp) | |
df = pd.DataFrame(data = outvalue, columns= paraSchNames) | |
for nameCol, nameUnit in zip(df.columns, unit_header): | |
self.__class__.dictUnitValue[nameCol] = nameUnit | |
# remove blank line | |
df = df.drop(0, axis = 0) | |
return df | |
@property | |
def UnwrapDFrame(self): | |
""" | |
return the unwrap Panda DataFrame | |
""" | |
return self._df | |
def Append(self, *args, **kwargs): | |
""" | |
method to call the 'append' DataFrame method to concat 2 DataFrames | |
""" | |
if isinstance(args[0], WrapDFrame): | |
# uwrap fist item | |
args = list(args) | |
args[0] = args[0].UnwrapDFrame | |
args = tuple(args) | |
new_df = self.UnwrapDFrame.append(args, kwargs) | |
return WrapDFrame(new_df) | |
def ToHTML(self): | |
""" | |
convert DataFrame to Html and open it | |
""" | |
filename = my_path + '\\htmlDataFrame.html' | |
htmlDf = """\ | |
<html> | |
<head> | |
<style> | |
table, th, td {{font-size:10pt; border:1px solid black; border-collapse:collapse; text-align:left;}} | |
th, td {{padding: 5px;}} | |
tr:nth-child(even) {{background: #E0E0E0;}} | |
tr:hover {{background: silver; cursor: pointer;}} | |
</style> | |
</head> | |
<body> | |
{0} | |
</body> | |
</html> | |
""".format(self.UnwrapDFrame.to_html()) | |
# | |
# add unit in tooltip with bs4 | |
soup = bs(htmlDf, 'html.parser') | |
tables = soup.find_all('table') | |
for table in tables: | |
rows = table.find_all('tr') | |
row = rows[0] | |
cols = row.find_all('th') | |
for ele in cols: | |
if ele.string is not None: | |
unit = self.__class__.dictUnitValue.get(ele.string.strip()) | |
if unit is not None: | |
print("pass") | |
try: | |
ele["title"] = unit | |
except: | |
import traceback | |
self.lstError.append([ele.string, traceback.format_exc()]) | |
htmlDf = soup.prettify() | |
# | |
#with open(filename, 'w') as f: | |
with codecs.open(filename, "w", encoding="utf-8") as f: | |
f.write( htmlDf) | |
webbrowser.open_new_tab(filename) | |
def __to_Float(self, x): | |
""" | |
convert value cell to float and get suffix unit | |
""" | |
sgA = re.match(r'([+-]?\d*.?\d+)\s(.+)', x) | |
sgB = re.match(r'([+-]?\d*.?\d+)', x) | |
if sgA is not None: | |
return float(sgA.group(1).replace(',','.')), sgA.group(2) | |
elif sgB is not None: | |
return float(sgB.group(1).replace(',','.')), "" | |
else: | |
return x, "" | |
OUT = WrapDFrame |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment