⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zoomscrolldemo.php

📁 一个绝对棒的报表绘图软件
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php
require_once("../lib/phpchartdir.php");

#/
#/ We need to handle 3 types of request:
#/ - initial request for the full web page
#/ - partial update (AJAX chart update) to update the chart without reloading the page
#/ - full page update for old browsers that does not support partial updates
#/

# The total date range of all data.
$startDate = null;
$endDate = null;

# The date range of the data that we zoomed into (visible on the chart).
$viewPortStartDate = null;
$viewPortEndDate = null;

#/ <summary>
#/ Handles the initial request
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function createFirstChart(&$viewer) {

    global $startDate, $endDate, $viewPortStartDate, $viewPortEndDate;

    # Initialize the Javascript ChartViewer
    $viewer->setMouseUsage(MouseUsageScroll);

    # In this demo, we allow scrolling the chart for the last 5 years
    list($unused, $unused, $unused, $d, $m, $y, $unused, $unused, $unused) = localtime();

    # The localtime month format is from 0 - 11, while the year is offsetted by 1900. We adjust them
    # to human used format.
    $m = $m + 1;
    $y = $y + 1900;

    $endDate = chartTime($y, $m, $d);

    # We roll back 5 years for the start date. Note that if the end date is Feb 29 (leap year only
    # date), we need to change it to Feb 28 in the start year
    if (($m == 2) && ($d == 29)) {
        $d = 28;
    }
    $startDate = chartTime($y - 5, $m, $d);

    # Initially set the view port to show data for the first year
    $viewPortStartDate = chartTime($y - 1, $m, $d);
    $viewPortEndDate = $endDate;

    # We store the scroll range as custom Javascript ChartViewer attributes, so the range can be
    # retrieved later in partial or full update requests
    $viewer->setCustomAttr("startDate", $startDate);
    $viewer->setCustomAttr("endDate", $endDate);

    # In this demo, we set the maximum zoom-in to 10 days
    $viewer->setZoomInWidthLimit(10 * 86400 / ($endDate - $startDate));

    # Draw the chart
    drawChart($viewer);
}


#/ <summary>
#/ Handles partial update (AJAX chart update)
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function processPartialUpdate(&$viewer) {

    global $startDate, $endDate, $viewPortStartDate, $viewPortEndDate;

    # Retrieve the overall date range from custom Javascript ChartViewer attributes.
    $startDate = $viewer->getCustomAttr("startDate");
    $endDate = $viewer->getCustomAttr("endDate");

    # Now we need to determine the visible date range selected by the user. There are two
    # possibilities. The user may use the zoom/scroll features of the Javascript ChartViewer to
    # select the range, or s/he may use the start date / end date select boxes to select the date
    # range.

    if ($viewer->isViewPortChangedEvent()) {
        # Is a view port change event from the Javascript ChartViewer, so we should get the selected
        # date range from the ChartViewer view port settings.
        $duration = $endDate - $startDate;
        $viewPortStartDate = $startDate + (int)(0.5 + $viewer->getViewPortLeft() * $duration);
        $viewPortEndDate = $viewPortStartDate + (int)(0.5 + $viewer->getViewPortWidth() * $duration)
            ;
    } else {
        # The user has changed the selected range by using the start date / end date select boxes.
        # We need to retrieve the selected dates from those boxes. For partial updates, the select
        # box values are sent in as Javascript ChartViewer custom attributes.
        $startYear = (int)($viewer->getCustomAttr("StartYear"));
        $startMonth = (int)($viewer->getCustomAttr("StartMonth"));
        $startDay = (int)($viewer->getCustomAttr("StartDay"));
        $endYear = (int)($viewer->getCustomAttr("EndYear"));
        $endMonth = (int)($viewer->getCustomAttr("EndMonth"));
        $endDay = (int)($viewer->getCustomAttr("EndDay"));

        # Note that for browsers that do not support Javascript, there is no validation on the
        # client side. So it is possible for the day to exceed the valid range for a month (eg. Nov
        # 31, but Nov only has 30 days). So we set the date by adding the days difference to the 1
        # day of a month. For example, Nov 31 will be treated as Nov 1 + 30 days = Dec 1.
        $viewPortStartDate = chartTime($startYear, $startMonth, 1) + ($startDay - 1) * 86400;
        $viewPortEndDate = chartTime($endYear, $endMonth, 1) + ($endDay - 1) * 86400;
    }

    # Draw the chart
    drawChart($viewer);

    #
    # We need to communicate the new start date / end date back to the select boxes on the browser
    # side.
    #

    # The getChartYMD function retrives the date as an 8 digit decimal number yyyymmdd.
    $startYMD = getChartYMD($viewPortStartDate);
    $endYMD = getChartYMD($viewPortEndDate);

    # Send year, month, day components to the start date / end date select boxes through Javascript
    # ChartViewer custom attributes.
    $viewer->setCustomAttr("StartYear", (int)($startYMD / 10000));
    $viewer->setCustomAttr("StartMonth", (int)($startYMD / 100) % 100);
    $viewer->setCustomAttr("StartDay", $startYMD % 100);
    $viewer->setCustomAttr("EndYear", (int)($endYMD / 10000));
    $viewer->setCustomAttr("EndMonth", (int)($endYMD / 100) % 100);
    $viewer->setCustomAttr("EndDay", $endYMD % 100);
}


#/ <summary>
#/ Handles full update
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function processFullUpdate(&$viewer) {
    # A full chart update is essentially the same as a partial chart update. The main difference is
    # that in a full chart update, the start date / end date select boxes are in Form Post
    # variables, while in partial chart update, they are in Javascript ChartViewer custom
    # attributes.
    #
    # So a simple implementation of the full chart update is to copy the Form Post values to the
    # Javascript ChartViewer custom attributes, and then call the partial chart update.

    # Controls to copy
    $ctrls = array("StartYear", "StartMonth", "StartDay", "EndYear", "EndMonth", "EndDay");

    # Copy control values to Javascript ChartViewer custom attributes
    for($i = 0; $i < count($ctrls); ++$i) {
        $viewer->setCustomAttr($ctrls[$i], $_REQUEST[$ctrls[$i]]);
    }

    # Now can use partial chart update
    processPartialUpdate($viewer);
}


#/ <summary>
#/ Draw the chart
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function drawChart(&$viewer) {

    global $startDate, $endDate, $viewPortStartDate, $viewPortEndDate;

    #
    # Validate and adjust the view port dates.
    #

    # Verify if the view port dates are within limits
    $totalDuration = $endDate - $startDate;
    $minDuration = $viewer->getZoomInWidthLimit() * $totalDuration;
    if ($viewPortStartDate < $startDate) {
        $viewPortStartDate = $startDate;
    }
    if ($endDate - $viewPortStartDate < $minDuration) {
        $viewPortStartDate = $endDate - $minDuration;
    }
    if ($viewPortEndDate > $endDate) {
        $viewPortEndDate = $endDate;
    }
    if ($viewPortEndDate - $viewPortStartDate < $minDuration) {
        $viewPortEndDate = $viewPortStartDate + $minDuration;
    }

    # Adjust the view port to reflect the selected date range
    $viewer->setViewPortWidth(($viewPortEndDate - $viewPortStartDate) / $totalDuration);
    $viewer->setViewPortLeft(($viewPortStartDate - $startDate) / $totalDuration);

    #
    # Now we have the date range, we can get the necessary data. In this demo, we just use a random
    # number generator. In practice, you may get the data from a database or XML or by other means.
    # (See "Using Data Sources with ChartDirector" in the ChartDirector documentation if you need
    # some sample code on how to read data from database to array variables.)
    #

    # Just a random number generator to generate the data - emulates a table of numbers from
    # startDate to endDate
    $r = new RanTable(127, 4, (int)(0.5 + $totalDuration / 86400) + 1);
    $r->setDateCol(0, $startDate, 86400);
    $r->setCol(1, 150, -10, 10);
    $r->setCol(2, 200, -10, 10);
    $r->setCol(3, 250, -10, 10);

    # Emulate selecting the date range viewPortStartDate to viewPortEndDate. Note that we add one
    # day margin on both ends. It is because we are using daily data, but the view port can cover
    # partial days. For example, the view port end date can be at 3:00am Feb 1, 2006. In this case,
    # we need the data point at Feb 2, 2006.
    $r->selectDate(0, $viewPortStartDate - 86400, $viewPortEndDate + 86400);

    # Emulate getting the random data from the table
    $timeStamps = $r->getCol(0);
    $dataSeriesA = $r->getCol(1);
    $dataSeriesB = $r->getCol(2);
    $dataSeriesC = $r->getCol(3);

    if (count($timeStamps) >= 520) {
        #
        # Zoomable chart with high zooming ratios often need to plot many thousands of points when
        # fully zoomed out. However, it is usually not needed to plot more data points than the
        # pixel resolution of the chart. Plotting too many points may cause the points and the lines
        # to overlap on the same pixel. So rather than increasing resolution, this reduces the
        # clarity of the chart. It is better to aggregate the data first if there are too many
        # points.
        #
        # In our current example, the chart plot area only has 520 pixels in width and is using a 2
        # pixel line width. So if there are more than 520 data points, we aggregate the data using
        # the ChartDirector aggregation utility method.
        #
        # If in your real application, you do not have too many data points, you may remove the
        # following code altogether.
        #

        # Set up an aggregator to aggregate the data based on regular sized slots
        $m = new ArrayMath($timeStamps);
        $m->selectRegularSpacing(count($timeStamps) / 260);

        # For the timestamps, take the first timestamp on each slot
        $timeStamps = $m->aggregate($timeStamps, AggregateFirst);

        # For the data values, take the averages
        $dataSeriesA = $m->aggregate($dataSeriesA, AggregateAvg);
        $dataSeriesB = $m->aggregate($dataSeriesB, AggregateAvg);
        $dataSeriesC = $m->aggregate($dataSeriesC, AggregateAvg);
    }

    #
    # Now we have obtained the data, we can plot the chart.
    #

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -