import {
AfterViewInit,
Component,
ElementRef,
Input,
OnInit,
ViewChild,
} from '@angular/core';
@Component({
selector: 'app-line-chart',
templateUrl: './line-chart.component.html',
styleUrls: ['./line-chart.component.css'],
})
export class ProductListComponent {
@ViewChild('elemCanvas') canvasValue: ElementRef | undefined;
@Input() color: string = '';
@Input() data: any = [];
width: number = 600;
height: number = 200;
padding: number = 40;
dpi_width: number = this.width * 2;
dpi_height: number = this.height * 2;
view_height: number = this.dpi_height - this.padding * 2;
view_width: number = this.dpi_width- this.padding * 2;
rows_count: number = 5;
ymin: number = 0;
ymax: number = 0;
xmin: number = 0;
xmax: number = 0;
value: any = 0;
yRatio: number = 0;
xRatio: number = 0;
DEBUG_MODE = true;//ПОСТАВИТЬ false чтобы убрать границы и значения
constructor() {
window.addEventListener('resize', () => {
this.chart();
});
}
ngOnInit() {
this.value = [this.ymin, this.ymax,this.xmin, this.xmax] = this.computeBoundaries(this.data);
this.yRatio = this.view_height / (this.ymax - this.ymin);
this.xRatio = this.view_width / (this.xmax - this.xmin);
}
ngAfterViewInit() {
this.chart();
}
chart(): void {
const elem = (this.canvasValue?.nativeElement as HTMLCanvasElement) || null;
if (elem) {
this.initChart(elem);
const ctx = elem.getContext('2d');
if (ctx) {
this.YaxiosDrawing(ctx);
this.XaxiosDrawing(ctx);
this.lineDrawing(ctx);
if(this.DEBUG_MODE)
this.innerBorder(ctx);
}
}
}
initChart(elem: any): void {
this.width = this.canvasValue?.nativeElement.offsetWidth;
this.dpi_width = this.width * 2;
elem.width = this.dpi_width;
elem.height = this.dpi_height;
}
innerBorder(ctx: any): void {
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(this.padding,this.padding);
ctx.lineTo(this.padding + this.view_width, this.padding);
ctx.lineTo(this.padding + this.view_width, this.padding + this.view_height);
ctx.lineTo(this.padding , this.padding + this.view_height);
ctx.closePath();
ctx.stroke();
}
YaxiosDrawing(ctx: any): void {
const step = this.view_height / (this.rows_count - 1); //отступ между каждой линией
const textStep = (this.ymax - this.ymin) / (this.rows_count - 1);
ctx.beginPath();
ctx.strokeStyle = '#bbb';
ctx.font = 'normal 20px Helvetica, sans-serif';
ctx.fillStyle = '#96a2aa';
for (let i = 0; i <= this.rows_count; i++) {
const y = step * i;
const text = this.ymin + Math.round(textStep * i);
ctx.fillText(text.toString(), 5, this.view_height + this.padding - y);
ctx.moveTo(0, this.view_height + this.padding - y);
ctx.lineTo(this.dpi_width, this.view_height + this.padding - y);
}
ctx.stroke();
ctx.closePath();
}
XaxiosDrawing(ctx: any): void {
const step = this.view_width / (this.rows_count - 1);
const textStep = (this.xmax - this.xmin) / (this.rows_count - 1);
ctx.beginPath();
ctx.strokeStyle = '#bbb';
ctx.font = 'normal 20px Helvetica, sans-serif';
ctx.fillStyle = '#96a2aa';
for (let i = 0; i <= this.rows_count; i++) {
const x = step * i;
const text = this.xmin + Math.round(textStep * i);
ctx.fillText(text.toString(),
this.padding + x - ctx.measureText(text).width/2,
this.view_height + this.padding + 25 );
}
ctx.stroke();
ctx.closePath();
}
lineDrawing(ctx: any): void {
ctx.beginPath();
ctx.lineWidth = 4;
ctx.strokeStyle = this.color;
for (const [x, y] of this.data) {
ctx.lineTo(
this.padding + x * this.xRatio - this.xmin*this.xRatio,
this.view_height + this.padding - y * this.yRatio + this.ymin* this.yRatio
);
if(this.DEBUG_MODE){
ctx.font = 'Arial 16px';
ctx.fillStyle = 'red';
ctx.fillText(
x + ',' + y,
this.padding + x * this.xRatio - this.xmin*this.xRatio - 100,
this.view_height + this.padding - y * this.yRatio + this.ymin* this.yRatio
);
}
}
ctx.stroke();
}
computeBoundaries(data: any) {
let min, max;
let minx = this.data[0][0],maxx = this.data[0][0];
for (const [x, y] of this.data) {
if (typeof min !== 'number') min = y;
if (typeof max !== 'number') max = y;
if (min > y) min = y;
if (max < y) max = y;
if(x < minx)
minx = x;
if(x > maxx)
maxx = x;
}
return [min, max, minx,maxx];
}
}
let str = "тинькоф";
let arr = CARDS.map(e=>e.items).flat().filter(e=>e.title.toLocaleLowerCase().includes(str.toLocaleLowerCase()) );
.slick-slide:not(.slick-active):after {
position: absolute;
display: block;
width: 100%;
height: 100%;
background: radial-gradient(rgba(255,255,255,1), rgba(255,255,255, .5));
content: '';
top: 0;
}
private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
if (e.Exception is WpfLocalizedException ex){
//ex.dicts //ваш объект к которому нужно обратится...
}
}
}
var res = await ytdl.RunVideoPlaylistDownload(
"https://www.youtube.com/playlist?list=PLPfak9ofGSn9sWgKrHrXrxQXXxwhCblaT",
start: 52, end: 76
);
.btn-menu span {
transition: all .1s linear .23s;
transition: all .1s linear;
canvas {
border: 1px solid #000;
width: 100%;
}
initChart(elem: any): void {
//elem.style.width = this.width + 'px';
//elem.style.height = this.height + 'px';
elem.width = this.dpi_width;
elem.height = this.dpi_height;
}
<DataGrid ItemsSource="{Binding GridItems}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"></DataGridTextColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding Date, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></DatePicker>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
public class MyItem{
public string Name { get; set; } = "myname";
public Func<DateTime?, bool> DateChecker = null;
public DateTime? _Date;
public DateTime? Date {
get => _Date;
set {
if (DateChecker != null && DateChecker.Invoke(value)){//При попытке установить дату вызваем метод который проверить сколько в коллекции у нас уже таких дат
_Date = value;//Устанавливает дату если метод DateChecker вернул true
}
}
}
}
public partial class MainWindow : Window
{
public ObservableCollection<MyItem> GridItems { get; set; }= new ObservableCollection<MyItem>(){};//Коллекция элементов
public bool DateCheckerMethod(DateTime? dt){//Метод который будет вызываться при попытке изменить дату
if (dt != null && GridItems.Count(item => item.Date != null && item.Date.Value.CompareTo(dt.Value) == 0) >= 7){
MessageBox.Show("Максимум 7 дат");
return false;
}
return true;
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
GridItems.CollectionChanged += (sender, args) => {//При добавлении в колелекцию нового элемента, присваиваем метод обработки дат
foreach (var myItem in args.NewItems.Cast<MyItem>())
myItem.DateChecker = DateCheckerMethod;
};
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date});
GridItems.Add(new MyItem() { _Date = DateTime.Now.Date.AddDays(1)});
}
}