mklink /j C:\android-sdk "C:\Program Files (x86)\Android\android-sdk"
<AotAssemblies>true</AotAssemblies> <EnableLLVM>true</EnableLLVM>
mklink /j C:\android-sdk "C:\Program Files (x86)\Android\android-sdk"
<AotAssemblies>true</AotAssemblies> <EnableLLVM>true</EnableLLVM>
این نرم افزار با کدهای HTML و با پسوند اجرایی hta تولید شده است که به صورت یک Application میتواند اجرا شود.
برای انجام این کار از ActiveXObjectها استفاده مینماید.
برای تبدیل اطلاعات موجود در sheetهای مختلف اکسل به فایل csv، مشابه نام هریک از sheetهای اکسل یک فایل csv متنی ایجاد میکند.
public AddUserStatus Add(User user) { if (ExistsByEmail(user.Email)) return AddUserStatus.EmailExist; if (ExistsByUserName(user.UserName)) return AddUserStatus.UserNameExist; _users.Add(user); return AddUserStatus.AddingUserSuccessfully; }
using System.Linq; using System.Web.Mvc; using Iris.Datalayer.Context; namespace Iris.Web.Controllers { public class MigrationController : Controller { public ActionResult RemoveDuplicateUsers() { var db = new IrisDbContext(); var lstDuplicateUserGroup = db.Users .GroupBy(u => u.UserName) .Where(g => g.Count() > 1) .ToList(); foreach (var duplicateUserGroup in lstDuplicateUserGroup) { foreach (var user in duplicateUserGroup.Skip(1).Where(user => user.UserMetaData != null)) { db.UserMetaDatas.Remove(user.UserMetaData); } db.Users.RemoveRange(duplicateUserGroup.Skip(1)); } db.SaveChanges(); return new EmptyResult(); } } }
مقایسه ساختار جداول دیتابیس کاربران IRIS با ASP.NET Identity
ساختار جداول ASP.NET Identity به شکل زیر است:
ساختار جداول سیستم کنونی هم بدین شکل است:
همان طور که مشخص است در هر دو سیستم، بین ساختار جداول و رابطهی بین آنها شباهتها و تفاوت هایی وجود دارد. سیستم Identity دو جدول بیشتر از IRIS دارد و برای جداولی که در سیستم کنونی وجود ندارند نیاز به انجام کاری نیست و به هنگام پیاده سازی Identity، این جداول به صورت خودکار به دیتابیس اضافه خواهند شد.
دو جدول مشترک در این دو سیستم، جداول Users و Roles هستندکه نحوهی ارتباطشان با یکدیگر متفاوت است. در Iris بین User و Role رابطهی یک به چند وجود دارد ولی در Identity، رابطهی بین این دو جدول چند به چند است و جدول واسط بین آنها نیز UserRoles نام دارد.
از آن جایی که من قصد دارم در سیستم جدید هم رابطهی بین کاربر و نقش چند به چند باشد، به پیش فرضهای Identity کاری ندارم. به رابطهی کنونی یک به چند کاربر و نقشش نیز دست نمیگذارم تا در انتها با یک کوئری از دیتابیس، اطلاعات نقشهای کاربران را به جدول جدیدش منتقل کنم.
جدولی که در هر دو سیستم مشترک است و هستهی آنها را تشکیل میدهد، جدول Users است. اگر دقت کنید میبینید که این جدول در هر دو سیستم، دارای یک سری فیلد مشترک است که دقیقا هم نام هستند مثل Id، UserName و Email؛ پس این فیلدها از نظر کاربرد در هر دو سیستم یکسان هستند و مشکلی ایجاد نمیکنند.
یک سری فیلد هم در جدول User در سیستم IRIS هست که در Identity نیست و بلعکس. با این فیلدها نیز کاری نداریم چون در هر دو سیستم کار مخصوص به خود را انجام میدهند و تداخلی در کار یکدیگر ایجاد نمیکنند.
اما فیلدی که برای ذخیره سازی پسورد در هر دو سیستم استفاده میشود دارای نامهای متفاوتی است. در Iris این فیلد Password نام دارد و در Identity نامش PasswordHash است.
برای اینکه در سیستم کنونی، نام فیلد Password جدول User را به PasswordHash تغییر دهیم قدمهای زیر را بر میداریم:
وارد پروژهی DomainClasses شده و کلاس User را باز کنید. سپس نام خاصیت Password را به PasswordHash تغییر دهید. پس از این تغییر بلافاصله یک گزینه زیر آن نمایان میشود که میخواهد در تمام جاهایی که از این نام استفاده شده است را به نام جدید تغییر دهد؛ آن را انتخاب کرده تا همه جا Password به PasswordHash تغییر کند.
برای این که این تغییر نام بر روی دیتابیس نیز اعمال شود باید از Migration استفاده کرد. در اینجا من از مهاجرت دستی که بر اساس کد هست استفاده میکنم تا هم بتوانم کدهای مهاجرت را پیش از اعمال بررسی و هم تاریخچهای از تغییرات را ثبت کنم.
برای این کار، Package Manager Console را باز کرده و از نوار بالایی آن، پروژه پیش فرض را بر روی DataLayer قرار دهید. سپس در کنسول، دستور زیر را وارد کنید:
Add-Migration Rename_PasswordToPasswordHash_User
اگر وارد پوشه Migrations پروژه DataLayer خود شوید، باید کلاسی با نامی شبیه به 201510090808056_Rename_PasswordToPasswordHash_User ببینید. اگر آن را باز کنید کدهای زیر را خواهید دید:
public partial class Rename_PasswordToPasswordHash_User : DbMigration { public override void Up() { AddColumn("dbo.Users", "PasswordHash", c => c.String(nullable: false, maxLength: 200)); DropColumn("dbo.Users", "Password"); } public override void Down() { AddColumn("dbo.Users", "Password", c => c.String(nullable: false, maxLength: 200)); DropColumn("dbo.Users", "PasswordHash"); } }
بدیهی هست که این کدها عمل حذف ستون Password را انجام میدهند که سبب از دست رفتن اطلاعات میشود. کدهای فوق را به شکل زیر ویرایش کنید تا تنها سبب تغییر نام ستون Password به PasswordHash شود.
public partial class Rename_PasswordToPasswordHash_User : DbMigration { public override void Up() { RenameColumn("dbo.Users", "Password", "PasswordHash"); } public override void Down() { RenameColumn("dbo.Users", "PasswordHash", "Password"); } }
سپس باز در کنسول دستور Update-Database را وارد کنید تا تغییرات بر روی دیتابیس اعمال شود.
دلیل اینکه این قسمت را مفصل بیان کردم این بود که میخواستم در مهاجرت از سیستم اعتبارسنجی خودتان به ASP.NET Identity دید بهتری داشته باشید.
تا به این جای کار فقط پایگاه داده سیستم کنونی را برای مهاجرت آماده کردیم و هنوز ASP.NET Identity را وارد پروژه نکردیم. در بخشهای بعدی Identity را نصب کرده و تغییرات لازم را هم انجام میدهیم.
سلام؛ ممنون بابت پاسختون. این طوری به forgeryToken نگاه نکرده بودم.
در صفحه برای Delete و ثبت اطلاعات و یا حتی فیلترکردن اطلاعات و هرجا که کاربر اطلاعاتی وارد میکند از AntiForgeryToken استفاده کردم و حذف و ورود اطلاعات و فیلتر کلا در یک صفحه اما هرکدام در تگ Form مجزایی ارسال و دریافت میشود و در هر تگ Form یک ForgeryToken گذاشتم.
برای اونها چه کار کنم؟ اصلا کار بنده درست بوده؟ من هرکجا کاربر اطلاعاتی وارد کرده از Token استفاده کردم ولی مشکل اینجاست که با توجه به طراحی کل اونها نیازه که در یک صفحه باشه.
می تونم یک AntiForgeryToken کلی داشته باشم و با جاوا اسکریپت اون و بخونم و به Form.Serilaise() اضافه کنم. اما میخواستم راه بهینه اون و بپرسم.
PS> "" | Get-Member
TypeName: System.String Name MemberType Definition ---- ---------- ---------- Clone Method System.Object Clone(), System.Object ICloneable.Clone() CompareTo Method int CompareTo(System.Object value), int CompareTo(strin… Contains Method bool Contains(string value), bool Contains(string value… CopyTo Method void CopyTo(int sourceIndex, char[] destination, int de… EndsWith Method bool EndsWith(string value), bool EndsWith(string value… EnumerateRunes Method System.Text.StringRuneEnumerator EnumerateRunes() Equals Method bool Equals(System.Object obj), bool Equals(string valu… GetEnumerator Method System.CharEnumerator GetEnumerator(), System.Collectio… GetHashCode Method int GetHashCode(), int GetHashCode(System.StringCompari… GetPinnableReference Method System.Char&, System.Private.CoreLib, Version=6.0.0.0, … GetType Method type GetType() GetTypeCode Method System.TypeCode GetTypeCode(), System.TypeCode IConvert… IndexOf Method int IndexOf(char value), int IndexOf(char value, int st… IndexOfAny Method int IndexOfAny(char[] anyOf), int IndexOfAny(char[] any… Insert Method string Insert(int startIndex, string value) IsNormalized Method bool IsNormalized(), bool IsNormalized(System.Text.Norm… LastIndexOf Method int LastIndexOf(string value, int startIndex), int Last… LastIndexOfAny Method int LastIndexOfAny(char[] anyOf), int LastIndexOfAny(ch… Normalize Method string Normalize(), string Normalize(System.Text.Normal… PadLeft Method string PadLeft(int totalWidth), string PadLeft(int tota… PadRight Method string PadRight(int totalWidth), string PadRight(int to… Remove Method string Remove(int startIndex, int count), string Remove… Replace Method string Replace(string oldValue, string newValue, bool i… ReplaceLineEndings Method string ReplaceLineEndings(), string ReplaceLineEndings(… Split Method string[] Split(char separator, System.StringSplitOption… StartsWith Method bool StartsWith(string value), bool StartsWith(string v… Substring Method string Substring(int startIndex), string Substring(int … ToBoolean Method bool IConvertible.ToBoolean(System.IFormatProvider prov… ToByte Method byte IConvertible.ToByte(System.IFormatProvider provide… ToChar Method char IConvertible.ToChar(System.IFormatProvider provide… ToCharArray Method char[] ToCharArray(), char[] ToCharArray(int startIndex… ToDateTime Method datetime IConvertible.ToDateTime(System.IFormatProvider… ToDecimal Method decimal IConvertible.ToDecimal(System.IFormatProvider p… ToDouble Method double IConvertible.ToDouble(System.IFormatProvider pro… ToInt16 Method short IConvertible.ToInt16(System.IFormatProvider provi… ToInt32 Method int IConvertible.ToInt32(System.IFormatProvider provide… ToInt64 Method long IConvertible.ToInt64(System.IFormatProvider provid… ToLower Method string ToLower(), string ToLower(cultureinfo culture) ToLowerInvariant Method string ToLowerInvariant() ToSByte Method sbyte IConvertible.ToSByte(System.IFormatProvider provi… ToSingle Method float IConvertible.ToSingle(System.IFormatProvider prov… ToString Method string ToString(), string ToString(System.IFormatProvid… ToType Method System.Object IConvertible.ToType(type conversionType, … ToUInt16 Method ushort IConvertible.ToUInt16(System.IFormatProvider pro… ToUInt32 Method uint IConvertible.ToUInt32(System.IFormatProvider provi… ToUInt64 Method ulong IConvertible.ToUInt64(System.IFormatProvider prov… ToUpper Method string ToUpper(), string ToUpper(cultureinfo culture) ToUpperInvariant Method string ToUpperInvariant() Trim Method string Trim(), string Trim(char trimChar), string Trim(… TrimEnd Method string TrimEnd(), string TrimEnd(char trimChar), string… TrimStart Method string TrimStart(), string TrimStart(char trimChar), st… TryCopyTo Method bool TryCopyTo(System.Span[char] destination) Chars ParameterizedProperty char Chars(int index) {get;} Length Property int Length {get;}
$stringVariable = "Hello World" $letter = 'A' $isEnabled = $false $age = 33 $height = 76 $doubleVar = 54321.21 $singleVar = 76549.11 $longVar = 2382.22 $dateVar = "July 24, 1986" $arrayVar = "A", "B", "C" $hashtableVar = @{ Name = "Sirwan"; Age = 33; }
[string]$stringVariable = "Hello World" [char]$letter = 'A' [bool]$isEnabled = $false [int]$age = 33 [decimal]$height = 76 [double]$doubleVar = 54321.21 [single]$singleVar = 76549.11 [long]$longVar = 2382.22 [DateTime]$dateVar = "July 24, 1986" [array]$arrayVar = "A", "B", "C" [hashtable]$hashtableVar = @{ Name = "Sirwan"; Age = 33; }
$global:stringVariable = "Hello World" // Or [string]$global:stringVariable = "Hello World"
$guess = 20 switch ($guess) { {$_ -eq 20} { Write-Host "You guessed right!" } {$_ -gt 20} { Write-Host "You guessed too high!" } {$_ -lt 20} { Write-Host "You guessed too low!" } default { Write-Host "You didn't guess a number!" } } $guess = 20 if ($guess -eq 20) { Write-Host "You guessed right!" } elseif ($guess -gt 20) { Write-Host "You guessed too high!" } elseif ($guess -lt 20) { Write-Host "You guessed too low!" } else { Write-Host "You didn't guess a number!" }
$message = (Test-Path $path) ? "Path exists" : "Path not found"
[int]$num = 10 for ($i = 1; $i -le $num; $i++) { Write-Host "`n" for ($j = 1; $j -le $num; $j++) { Write-Host -NoNewline -ForegroundColor Green ($i * $j).ToString().PadLeft(6) } } Write-Host "`n`n" [int]$counter = 1 while ($counter -le 10) { Write-Host "Hello World" $counter++ } do { Write-Host "Hello World" $counter++ } while ($counter -le 10) foreach ($i in 1..10) { Write-Host "Hello World" } $items = "Hello", "World" $items | ForEach-Object { Write-Host $_ }
$array = @()
$myArray = [Object[]]::new(10) $byteArray = [Byte[]]::new(100) $ipAddresses = [IPAddress[]]::new(5) $mylist = [System.Collections.Generic.List[int]]::new()
using namespace System.Collections.Generic $mylist = [List[int]]::new()
$numbers = 1..10 $alphabet = "a".."z" foreach ($item in 1..10) { Write-Host "Hello World" }
$numbers = 1..10 $numbers Write-Output "".PadRight(10, "-") $numbers[1..2 + 2..4]
$colours = [System.Collections.ArrayList]@("Red", "Green", "Blue") $colours.Add("Yellow") $colours.Remove("Red")
using namespace System.Collections.Generic $mylist = [List[int]]::new() Measure-Command { 1..100000 | ForEach-Object { $mylist.Add($_) } } Measure-Command { $mylist.Where({ $_ -gt 10000 }) } Measure-Command { $mylist.Contains(10000) }
$sensors = @{ tempreture = "Temperature" humidity = "Humidity" pressure = "Pressure" light = "Light" noise = "Noise" co2 = "CO2" battery = "Battery" min_temp = "Min Temp" max_temp = "Max Temp" }
PS> Get-Command -ParameterType Hashtable CommandType Name Version Source ----------- ---- ------- ------ Function TabExpansion2 Cmdlet Add-Member 7.0.0.0 Microsoft.Powe… Cmdlet ConvertTo-Html 7.0.0.0 Microsoft.Powe… Cmdlet Get-Job 7.2.7.500 Microsoft.Powe… Cmdlet Invoke-Command 7.2.7.500 Microsoft.Powe… Cmdlet Invoke-RestMethod 7.0.0.0 Microsoft.Powe… Cmdlet Invoke-WebRequest 7.0.0.0 Microsoft.Powe… Cmdlet New-Object 7.0.0.0 Microsoft.Powe… Cmdlet New-PSRoleCapabilityFile 7.2.7.500 Microsoft.Powe… Cmdlet New-PSSession 7.2.7.500 Microsoft.Powe… Cmdlet Remove-Job 7.2.7.500 Microsoft.Powe… Cmdlet Select-Xml 7.0.0.0 Microsoft.Powe… Cmdlet Set-PSReadLineOption 2.1.0 PSReadLine Cmdlet Stop-Job 7.2.7.500 Microsoft.Powe… Cmdlet Wait-Job 7.2.7.500 Microsoft.Powe…
function Write-HelloWorld { Write-Host "Hello World" }
PS> Get-Command -CommandType Function
function Write-HelloWorld { Write-Host "First Argument: $($args[0])" Write-Host "Second Argument: $($args[1])" Write-Host "Third Argument: $($args[2])" Write-Host "Fourth Argument: $($args[3])" }
function Write-HelloWorld( [string]$first, [string]$second, [string]$third, [string]$fourth ) { Write-Host "First Argument: $($first)" Write-Host "Second Argument: $($second)" Write-Host "Third Argument: $($third)" Write-Host "Fourth Argument: $($fourth)" }
Get-Command -ParameterType Hashtable | Out-ConsoleGridview
البته به صورت پیشفرض نصب نیست و باید از طریق PowerShell Gallery آن را نصب کنید:
Install-Module -Name Microsoft.PowerShell.ConsoleGuiTools
در این مرحله قصد داریم برای فرم زیر Unit Test طراحی کنیم. پروژه به صورت زیر است:
کاملا واضح است که در این فرم دو عدد به عنوان ورودی دریافت میشود و بعد از کلیک بر روی CalculateSum نتیجه در textbox سوم نمایش داده میشود. برای تست عملکرد صحیح فرم بالا ایتدا به Solution مورد نظر از منوی test Project یک Coded UI Test Project اضافه میکنیم. به دلیل اینکه این قبلا در این Solution پروژه تست از نوع Coded UI Test نبود بلافاصله یک پنجره نمایش داده میشود. مطمئن شوید گزینه اول انتخاب شده و بعد بر روی Ok کلیک کنید.(گزینه اول به معنی است که قصد داریم عملیات مورد نظر بر روی UI را رکورد کنیم و گزینه دوم به معنی است که قصد داریم از عملیات رکورد شده قبلی استفاده کنیم). یک کلاس به نام CodeUITest1 به همراه یک متد تست به نام CodedUITestMethod1 ساخته میشود. اولین چیزی که جلب توجه میکند این است که این کلاس به جای TestClassAttribute دارای نشان CodeUITestAttrbiute است. در گوشه سمت راست Vs.Net خود یک پنجره کوچک به نام UI Map Test Builder مانند شکل زیر خواهید دید.دکمه قرمز رنگ به نام Record Button است و عملیات تست را رکورد خواهد کرد. دکمه دایره ای به رنگ مشکی برای تعیین Assertion به کار میرود. و در نهایت گزینه آخر کدهای مورد نظر مراحل قبل را به صورت خودکار تولید خواهد کرد.
#روش کار
روش کار به این صورت است که ابتدا شما مراحل تست خود را شبیه سازی خواهید کرد و بعد از آن Test Builder مراحل تست شما را به صورت کامل به صورت کدهای قابل فهم تولید خواهد کرد. (دقیقا شبیه به ایجاد UnitTest به روش Arrange/Act/Assert است با این تفاوت که این مراحل توسط UI Map رکورد شده و نیازی به کد نویسی ندارد). در پایان باید یک Data Driven Coded UI Test طراحی کنید تا بتوانید از این مراحل رکورد استفاده نمایید.
#چگونگی شبیه سازی :
پروژه را اجرا نمایید. زمانی که فرم مورد نظر ظاهر شد بر روی گزینه Record در TestBuilder کلیک کنید. عملیات ذخیره سازی شروع شده است. در نتیجه به فرم مربوطه رفته و در Textbox اول مقدار 10 و در textbox دوم مقدار 5 را وارد نمایید. با کلیک بر روی دکمه CalculateSum مقدار 15 نمایش داده خواهد شد. از برنامه خارج شوید و بعد بر روی گزینه Generate Code در TestBuilder کلیک کنید با از کلیدهای ترکیبی Alt + G استفاده نمایید.(اگر در این مرحله، از برنامه خارج نشده باشید با خطا مواجه خواهید شد.) در پنجره نمایش داده شده یک نام به متد اختصاص دهید. عملیات تولید کد شروع خواهد شد. بعد کدی مشابه زیر را در متد مربوطه مشاهده خواهید کرد.
[TestMethod] public void CodedUITestMethod1() { this.UIMap.CalculateSum(); this.UIMap.txtSecondValueMustBe10(); }
public void CodedUITestMethod1 ()
{
#region Variable Declarations
WinEdit uITxtFirstNumberEdit = this.UIدوعددصحیحواردنماییدWindow.UITxtFirstNumberWindow.UITxtFirstNumberEdit;
WinEdit uITxtSecondNumberEdit = this.UIدوعددصحیحواردنماییدWindow.UITxtSecondNumberWindow.UITxtSecondNumberEdit;
WinButton uICalculateSumButton = this.UIدوعددصحیحواردنماییدWindow.UICalculateSumWindow.UICalculateSumButton;
#endregion
// Type '10' in 'txtFirstNumber' text box
uITxtFirstNumberEdit.Text = this.CalculateSumParams.UITxtFirstNumberEditText;
// Type '{Tab}' in 'txtFirstNumber' text box
Keyboard.SendKeys(uITxtFirstNumberEdit, this.CalculateSumParams.UITxtFirstNumberEditSendKeys, ModifierKeys.None);
// Type '10' in 'txtSecondNumber' text box
uITxtSecondNumberEdit.Text = this.CalculateSumParams.UITxtSecondNumberEditText;
// Click 'Calculate Sum' button
Mouse.Click(uICalculateSumButton, new Point(83, 12));
// Type '10' in 'txtFirstNumber' text box
uITxtFirstNumberEdit.Text = this.CalculateSumParams.UITxtFirstNumberEditText1;
// Type '{Tab}' in 'txtFirstNumber' text box
Keyboard.SendKeys(uITxtFirstNumberEdit, this.CalculateSumParams.UITxtFirstNumberEditSendKeys1, ModifierKeys.None);
// Type '10' in 'txtSecondNumber' text box
uITxtSecondNumberEdit.Text = this.CalculateSumParams.UITxtSecondNumberEditText1;
// Type '{Tab}' in 'txtSecondNumber' text box
Keyboard.SendKeys(uITxtSecondNumberEdit, this.CalculateSumParams.UITxtSecondNumberEditSendKeys, ModifierKeys.None);
// Click 'Calculate Sum' button
Mouse.Click(uICalculateSumButton, new Point(49, 11));
// Type '10' in 'txtFirstNumber' text box
uITxtFirstNumberEdit.Text = this.CalculateSumParams.UITxtFirstNumberEditText2;
// Type '{Tab}' in 'txtFirstNumber' text box
Keyboard.SendKeys(uITxtFirstNumberEdit, this.CalculateSumParams.UITxtFirstNumberEditSendKeys2, ModifierKeys.None);
// Type '5' in 'txtSecondNumber' text box
uITxtSecondNumberEdit.Text = this.CalculateSumParams.UITxtSecondNumberEditText2;
// Type '{Tab}' in 'txtSecondNumber' text box
Keyboard.SendKeys(uITxtSecondNumberEdit, this.CalculateSumParams.UITxtSecondNumberEditSendKeys1, ModifierKeys.None);
// Click 'Calculate Sum' button
Mouse.Click(uICalculateSumButton, new Point(74, 16));
}
به محض اتمام عملیات drag&drop منوی زیر ظاهر خواهد شد:
از گزینه Add Assertion استفاده کنید و برای کنترل مورد نظر یک assert بنویسید. در شکل زیر یک assert برای textbox دوم نوشتم به صورتی که مقدار آن باید با 5 برابر باشد.public void txtSecondValueMustBe10() { #region Variable Declarations WinEdit uITxtSecondNumberEdit = this.UIدوعددصحیحواردنماییدWindow.UITxtSecondNumberWindow.UITxtSecondNumberEdit; #endregion // Verify that the 'ControlType' property of 'txtSecondNumber' text box equals '10' Assert.AreEqual(this.txtSecondValueMustBe10ExpectedValues.UITxtSecondNumberEditControlType, uITxtSecondNumberEdit.ControlType.ToString()); }
در قسمت قبلی درباره ایجاد نمودار سازمانی تحت وب صحبت کردیم .حال اگر بخواهیم آن را با رنگهای مختلف ایجاد کنیم مانند شکل ذیل :
بدین صورت باید عمل کنیم:
نمودار در داخل canvas رسم شده است. برای اینکه پس زمینه (background) و حاشیههای آن (borders) را رنگ آمیزی کنیم، باید تابع رنگ آمیزی را قبل از تابع رسم نمودار صدا بزنیم. میتوانید از کدهای ذیل استفاده نمائید:
// ایجاد یک پس زمینه رنگی: var c = document.getElementById("c_canvas"); var cxt = c.getContext("2d"); var gradient = cxt.createLinearGradient(0, 0, 800, 320) gradient.addColorStop(0, 'Red'); gradient.addColorStop(.5, 'Yellow'); gradient.addColorStop(1, 'Green'); cxt.fillStyle = gradient; cxt.fillRect(0, 0, 800, 320); cxt.save(); // این سه خط را فعال کرده تا انتقال نمودار چارت سازمانی را مشاهده نمائید. //cxt.scale(-1.1, 1.1); //cxt.translate(-700,-50); //cxt.rotate(0.2); var o = new orgChart(); o.addNode(1, '', '', 'Root node'); o.addNode(2, 1, 'u', 'u-node 1'); o.addNode(3, 1, 'u', 'u-node 2'); o.addNode(4, 1, 'u', 'u-node 3'); o.addNode(5, 1, 'l', 'l-node 1'); o.addNode(6, 1, 'l', 'l-node 2'); o.addNode(7, 1, 'r', 'r-node 1'); o.addNode(8, 1, 'r', 'r-node 2'); o.addNode(9, 1, 'r', 'r-node 3'); o.addNode('', '', '', 'Root 2'); o.addNode('', 'Root 2', 'r', 'using'); o.addNode('', 'Root 2', 'r', 'text as id'); o.drawChart('c_canvas', 'center'); cxt.restore();
نکته : اگر بخواهید رنگ پس زمینه canvas را کامل پر کند (Fill) باید رسم نمودار را دوبار انجام دهید، در ابتدا تعریف یک canvas با امکان پرشونده در صفحه ، و بعد رسم پس زمینه و بعد رسم دوباره canvas .
شاخهها میتوانند رنگهای متفاوتی داشته باشند. امکان تعریف رنگ شاخهها بهمراه صدا زدن تابع addNode وجود دارد. اگر رنگی تعریف نشود ، از رنگ پیشفرض استفاده خواهد شد. رنگهای کنونی را با صدا زدن تابع setColor میتوان عوض کرد و تا زمان صدا زدن تابع setColor بعدی از آنها استفاده خواهد شد. همه خطهایی که شاخهها را به هم متصل میکنند فقط یک رنگ مشابه میتوانند داشته باشند.
پارامترهای تابع setColor :
یک پارامتر خالی رنگ ، تنظیمات کنونی را تغییر نخواهد داد. کد زیر را ویرایش نموده و دوباره صفحه خود را بازخوانی نمائید.
var o = new orgChart(); o.setColor('#99CC99', '#CCFFCC', '#000000', '#FF0000'); o.addNode(0, '', '', 'Root node'); o.setColor('#CCCC66', '#FFFF99'); o.addNode(11, 0, 'u', 'u-node 1'); o.setColor('#000000', '#FFFF99'); o.addNode(12, 0, 'u', 'black border'); o.addNode(13, 0, 'u', 'bold black border', 1); o.setColor('#CC4950', '#FF7C80'); o.addNode(21, 0, 'l', 'l-node 1'); o.addNode(22, 0, 'l', 'l-node 2', 0, 'BLACK', 'RED', 'BLUE'); o.addNode(23, 0, 'l', 'l-node 3'); o.setColor('#CC9966', '#FFCC99'); o.addNode(31, 0, 'r', 'r-node 1'); o.drawChart('c_colors', 'center');