Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 22.09.2012, 14:37
Интересующийся
Отправить личное сообщение для vadim.v Посмотреть профиль Найти все сообщения от vadim.v
 
Регистрация: 07.04.2012
Сообщений: 12

Расчет периодов и дат, логическая задача
Здравствуйте.

Мне поручили сделать frontend фичу,
а специалист по client-side в отпуске.
Прошу вашей помощи.

Есть вот такая фитча, сделана на jquery ui: slider.


Задача: динамически менять даты в поле выбора даты при изменении слайдера и наоборот, динамически менять положение слайдера при выборе даты.

Все бы просто, но как можно заметить периоды неравномерны, т.е. шаг разный.
Неделя - один шаг, неделя-месяц другой шаг.

Вся полоска - это период от 0 до 1000.
Я разбил её на несколько периодов с разным шагом.

Собственно вопрос, как лучше такое сделать/посчитать ?
Задача именно как вычислять положение слайдера на соостветсвие дате, вычислять дату соотвествующую положению слайдера.
Т.е. как менять даты и пложение полоски (технические вопросы) я знаю.

Последний раз редактировалось vadim.v, 22.09.2012 в 14:39.
Ответить с цитированием
  #2 (permalink)  
Старый 22.09.2012, 20:51
Интересующийся
Отправить личное сообщение для vadim.v Посмотреть профиль Найти все сообщения от vadim.v
 
Регистрация: 07.04.2012
Сообщений: 12

Задача решена, вот код

SliderFilterEvents = {

    intervalValueMinusMonth: 1,
    intervalValueMinusWeek: 227,
    intervalValueToDay: 380,
    intervalPlusWeek: 530,
    intervalPlusMonth: 775,
    intervalPlusHalfYear: 1000,

   /**
    * Callback функция вызываемая при перемещении слайдера ( выбор дат )
    * @param object event
    * @param object ui
    **/
    callbackSlideSlider: function(event, ui){
        var slidePoint1 = $("#slider").slider("values",0);
        var slidePoint2 = $("#slider").slider("values",1);

        var date = new Date();
        var daysInMonth = date.getDaysInMonth();

        SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalPlusMonth, 
SliderFilterEvents.intervalPlusHalfYear, (180-daysInMonth), daysInMonth-1);
        SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalPlusWeek, 
SliderFilterEvents.intervalPlusMonth, (daysInMonth-7), 7);
        SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalValueToDay, 
SliderFilterEvents.intervalPlusWeek, 7, 0);
        SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalValueMinusWeek, 
SliderFilterEvents.intervalValueToDay, 7, -7);
        SliderFilterEvents.calculationAndSetNumberDay(SliderFilterEvents.intervalValueMinusMonth, 
SliderFilterEvents.intervalValueMinusWeek, daysInMonth-7, (-daysInMonth));
    },
/**
     * Считает соотвествие расположения слайдера к дате и устанавливает дату
     * @param minPeriod минимальный период
     * @param maxPeriod максимальный период
     * @param days количество дней составляющих период
     * @param offset смещение в днях
     */
    calculationAndSetNumberDay: function(minPeriod, maxPeriod, days, offset){
        var period = maxPeriod-minPeriod;
        var oneDayPeriod = (period/days).toFixed(0);

        var offsetSeconds = offset*86400;

        var slidePoint1 = $("#slider").slider("values",0);
        var slidePoint2 = $("#slider").slider("values",1);

        if(slidePoint1 >= minPeriod && slidePoint1 <= maxPeriod){
            //550-slidePoint1(410)=190-140=50/27=1,8=ceil(1,8)=2
            var offsetInDays = ((period-(maxPeriod-slidePoint1))/oneDayPeriod).toFixed(0);
            var value = JSHelper.timestamp()+offsetSeconds+(86400*offsetInDays);
            //console.log(value, offsetSeconds, offsetInDays, (86400*offsetInDays), JSHelper.timestamp(), JSHelper.date('d.m.Y', value));
            $( "#date_start" ).val(JSHelper.date('d.m.Y', value));
        }

        if(slidePoint2 >= minPeriod && slidePoint2 <= maxPeriod){
            //550-slidePoint1(410)=190-140=50/27=1,8=ceil(1,8)=2
            var offsetInDays = ((period-(maxPeriod-slidePoint2))/oneDayPeriod).toFixed(0);
            $( "#date_end" ).val(JSHelper.date('d.m.Y', JSHelper.timestamp()+offsetSeconds+(86400*offsetInDays)));
        }
    },
/**
     * Выбрана дата, смещаем слайдер
     * @param string dateType [date_start, date_end] тип измененной даты
     **/
    callbackChangeDatе: function(dateType){

        /**
         * Посчитать сколько прошло дней от текущей даты до указанной
         * @param string data дата в формате d.m.Y
         **/
        function calculateDiffInDays(date){
            var intervalInDate = Math.floor((JSHelper.createTimestampByDate(date)-JSHelper.timestamp())/86400)+1;

            return intervalInDate;
        }

        /**
         * Переместить слайдер на нужное количество дней от текущей даты
         * @param integer slideIndex индекс слайдера
         * @param string days на какое количество дней смещать
         **/
        function slideMove(slideIndex, days){

            var date = new Date();
            var daysInMonth = date.getDaysInMonth();

            if(days <= 180 && days >= daysInMonth)
            {
                var newDays = (days-daysInMonth)+1;
                var position = calculateMoveInterval(SliderFilterEvents.intervalPlusHalfYear, SliderFilterEvents.intervalPlusMonth, 180-daysInMonth, newDays);

            }
            else if(days <= daysInMonth && days > 7)
            {
                var newDays = days-7;
                var position = calculateMoveInterval(SliderFilterEvents.intervalPlusMonth, SliderFilterEvents.intervalPlusWeek, daysInMonth-7, newDays);

            }
            else if(days <= 7 && days >= 1)
            {
                var position = calculateMoveInterval(SliderFilterEvents.intervalPlusWeek, SliderFilterEvents.intervalValueToDay, 7, days);
            }
            else if(days >= -7 && days < 1)
            {
                var position = calculateMoveInterval(SliderFilterEvents.intervalValueToDay, SliderFilterEvents.intervalValueMinusWeek, 7, days);
            }
            else if(days >= -daysInMonth)
            {
                //посчитать количество дней - 7
                var newDays = days+7;
                //var positionWeekly = calculateMoveInterval(SliderFilterEvents.intervalValueMinusWeek, SliderFilterEvents.intervalValueToDay, 7, 7)
                //сместить слайдер на оставшееся время
                var positionMonth = calculateMoveInterval(SliderFilterEvents.intervalValueMinusWeek, SliderFilterEvents.intervalValueMinusMonth, daysInMonth-7, newDays);

                var position = positionMonth;
            }


            SliderFilterEvents.updateSlidePosition(position, slideIndex)
        }

        /**
         * Вычислить новую позицию слайдера, исходя из переданных параметров
         * @param integer max_period максимальный период
         * @param integer min_period минимальный период
         * @param integer period количество дней, которое составляет указанный период
         * @param days количество дней на которое смещать
         * @return integer новая позиция слайдера
         **/
        function calculateMoveInterval(max_period, min_period, period, days){
            var interval = max_period-min_period;

            var oneDayPeriod = (interval/period).toFixed(0);
            var movePeriod = oneDayPeriod*days;

            return days > 0 ? min_period+movePeriod : max_period+movePeriod;
        }


        if(dateType == 'date_start')
        {
            var days = calculateDiffInDays($('#date_start').val());
            slideMove(0, days);
        }
        else if(dateType == 'date_end')
        {
            var days = calculateDiffInDays($('#date_end').val());
            slideMove(1, days);
        }
    },

/* other methods */
}
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск