Задать вопрос
  • Как расставить значения по оси x на канвасе?

    twobomb
    @twobomb
    Вообщем всё плохо, пришлось переписать
    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];
      }
    }
    Ответ написан
    2 комментария
  • Как найти объекты во вложенных массивах?

    twobomb
    @twobomb
    let str = "тинькоф";
    let arr = CARDS.map(e=>e.items).flat().filter(e=>e.title.toLocaleLowerCase().includes(str.toLocaleLowerCase()) );
    Ответ написан
    3 комментария
  • Можно как то убрать эти артефакты в slick слайдере?

    twobomb
    @twobomb
    Удали из CSS
    .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;
    }
    Ответ написан
    1 комментарий
  • Как централизованно обрабатывать исключения в WPF?

    twobomb
    @twobomb
    А причём тут InnerException? e.Exception и является экземпляром класса вашего кастомного исключения.
    private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)   {
                if (e.Exception is WpfLocalizedException ex){
                      //ex.dicts //ваш объект к которому нужно обратится...
                }
              }
        }

    Ну я надеюсь WpfLocalizedException наследуется от Exception
    Ответ написан
    Комментировать
  • Какой язык выбрать для простой обучающей программы?

    twobomb
    @twobomb
    VBA нужно брать одназначно, нахрен этот питон, я бы его вообще не рассматривал.
    Помню делал в универе интерактивные презентанции для мультимедийных досок для преподов, а они мне автоматы ставили. Вам даже с экселя не нужно выходить чтобы программу написать.
    Ответ написан
    1 комментарий
  • Как скачать видео частями?

    twobomb
    @twobomb
    youtube-dl — библиотека для скачивания видео с YouTube
    Вот нашёл обертку под C#
    YoutubeDLSharp

    var res = await ytdl.RunVideoPlaylistDownload(
        "https://www.youtube.com/playlist?list=PLPfak9ofGSn9sWgKrHrXrxQXXxwhCblaT",
        start: 52, end: 76
    );
    Ответ написан
    Комментировать
  • Как найти границы объекта на фото?

    twobomb
    @twobomb
    Границы, границы чего? По поводу машинного обучения не подскажу, это наверно нужно иметь большую базу объектов и позиций их границ для обучения.
    Ну если без машинного, то например как вариант по примеру фотошопа.
    1. Берем изоражение.
    2. Обесцвечиваем
    3. Самый важный и сложный этап, настраиваем правильно уровни.
    4. Находим границы черного и белого, но в идеале еще перед этим этапом придумать алгоритм растушевки хотя можно это сделать и уже следующим шагом исключив большие скопления точек.

    Я думаю можно даже несколько раз прогнать этот алгоритм, на разных уровнях(шаг3), для нахождения как можно большего количества границ и в итоге совместить в одну карту границ. Ну это сидеть, пробовать играть с параметрами...
    Ну это как один из первых же вариантом который пришёл в голову. Если нужен какой-то более ускоспециализированный поиск, это нужно посидеть подумать, потому-что "границы объекта" слишком абстрактно, объектов на фото может быть много и чьи границы искать неясно и что считать границами...
    638475e948731019030245.png

    P.S. Мысли в слух, как вариант создать программу которая в полуавтомате поможет найти границы изображений, чтобы сформировать массив данных уже для обучения нейронки, которая в будущем будет делать это автоматически.
    Ответ написан
    5 комментариев
  • Как сделать первый элемент аккордеона открытым?

    twobomb
    @twobomb
    В конец
    programItems[0].dispatchEvent(new Event("click"));
    Ответ написан
    Комментировать
  • Как сделать красивое закрытие выдвигающегося меню?

    twobomb
    @twobomb
    Возможно нужно поменять в .btn-menu span {
    transition: all .1s linear .23s;
    на
    transition: all .1s linear;
    Ответ написан
    1 комментарий
  • Как сделать адаптивным график canvas?

    twobomb
    @twobomb
    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;
      }
    Ответ написан
    6 комментариев
  • Как при клике скрыть блок со значением 0?

    twobomb
    @twobomb
    Нихрена не понятно, что и зачем. Напишите внятно. Возможно вам нужно что-то такое
    $(".radio .input-container").click(function (e){
      $(".box-container .input-container[data-attr-quantity=0] .color").hide( );
    });
    Ответ написан
    Комментировать
  • Как написать программу на js, которая будет менять фон ячейки в сетке при нажатии на неё мышкой?

    twobomb
    @twobomb
    canvas.onclick = function (ev) {
        ctx.fillStyle = "#FF0000AA";
        if (
          ev.offsetX >= 100 &&
          ev.offsetX <= 300 &&
          ev.offsetY >= 100 &&
          ev.offsetY <= 280
        )
          ctx.fillRect(
            Math.floor(ev.offsetX / 20) * 20,
            Math.floor(ev.offsetY / 20) * 20,
            20,
            20
          );
      };
    Ответ написан
    Комментировать
  • WPF Datepicker, как реализовать запрет на выбор одной даты больше 7 раз?

    twobomb
    @twobomb
    Ну вы бы хоть код какой-нибудь приложили, ну можно например так.

    XAML
    <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)});
            }
        }
    Ответ написан
  • Как вывести элементы массива в разные блоки по ID?

    twobomb
    @twobomb
    Ну это же очевидно, что `${i.id}` передаёт такой id элемента, которого не существует на странице.
    Оно будет работать, но какой-то элемент пропускает, или может там пустой приходит...
    Ответ написан
    Комментировать
  • Почему не работает System.Text.Encoding? Ошибается на 1 символ?

    twobomb
    @twobomb
    Ну потому-что ваш генератор тупо генерирует рандомные числа от 0 до FFFF, а в UTF16 там есть определенные правила. Почитайте например в вики

    Я не вникал ну вики говорит что там есть диапазон для суррогатных пар тоесть символы которые кодируются двумя 16битными словами, тоесть 4 байтами. Крч как вариант или тупо добавить проверку в генератор чтобы если рандомное число входит в диапазон исключений D80016..DFFF16 то пропускать и генерировать другое. Или замарачиваться с этими парами, ну это будет сложнее.

    Принцип кодирования
    В UTF-16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от 0 до FFFF16). При этом можно кодировать символы Unicode в диапазонах 000016..D7FF16 и E00016..FFFF16. Исключенный отсюда диапазон D80016..DFFF16 используется как раз для кодирования так называемых суррогатных пар — символов, которые кодируются двумя 16-битными словами.

    Символы Unicode до FFFF16 включительно (исключая диапазон для суррогатов) записываются как есть 16-битным словом.

    Символы же в диапазоне 1000016..10FFFF16 (больше 16 бит) кодируются по следующей схеме:

    Из кода символа вычитается 1000016. В результате получится значение от нуля до FFFFF16, которое помещается в разрядную сетку 20 бит.
    Старшие 10 бит (число в диапазоне 000016..03FF16) суммируются с D80016, и результат идёт в ведущее (первое) слово, которое входит в диапазон D80016..DBFF16.
    Младшие 10 бит (тоже число в диапазоне 000016..03FF16) суммируются с DC0016, и результат идёт в последующее (второе) слово, которое входит в диапазон DC0016..DFFF16.
    Ответ написан
    Комментировать
  • Как сделать плавное перемещение по карте на JS после просчета алгоритма A*?

    twobomb
    @twobomb
    Тут у вас тут всё заточено именно на дёрганное перемещение.
    Конечно как всё это реализовано, особенно метод launchDelWay это уникально....

    P.S. Всё перемещение перенес в метод update
    Ответ написан
    2 комментария
  • Как сделать перерасчет стоимости аренды?

    twobomb
    @twobomb
    Я не математик, ну первое что пришло в голову выглядит так:
    z = понятие месяц (30 дней)
    c = текущий тариф (50р/мес)
    n = новый тариф (100р/мес)
    d = день месяца (7 день)
    формула z - d * c/n
    30 - 7 * 50/100 = 11.5 дней добавить в новом тарифе
    Надеюсь правильно
    Ответ написан
    3 комментария