对于高图系列,请在click事件中使用带参数的symfony路由

时间:2017-10-27 13:02:24

标签: javascript php symfony highcharts

我使用ObHighchartsBundle在我的Symfony项目中制作图表。

我现在在仪表板上成功创建了一个图表,其中包含与给定数据(相同)链接的系列;

enter image description here

我想要完成的是使每个数据系列(订单状态)成为应用了过滤器的订单列表的链接,这样您只能看到每个位置的结果和点击的状态。

例如;如果我点击位置1的计划订单(蓝色最右边),我想打开只显示位置1的计划订单的订单列表。

这是我的代码,用于对此输出正确排序数据;

$data = $em->getRepository(Order::class)
    ->getOrdersByStatusAndLocation();

$orderStatuses = [];
$locations = [];
foreach ($data as $row) {
    if (!in_array($row['name'], $locations)) {
        $locations[] = $row['name'];
    }

    $orderStatuses[$row['status']][$row['name']] = $row['number_of_orders'];
}

$result = [];
foreach ($orderStatuses as $status => $value) {
    $row = [
        'name' => $status,
        'data' => array_fill(0, count($locations), 0)
    ];

    foreach ($value as $location => $numOfOrders) {
        $row['data'][array_search($location, $locations)] = $numOfOrders;
    }

    $result[] = $row;
}

我的$result的var_dump()就像这样;

array (size=6)
  0 => 
    array (size=2)
      'name' => string 'planned' (length=7)
      'data' => 
        array (size=2)
          0 => int 2
          1 => int 0
  1 => 
    array (size=2)
      'name' => string 'completed' (length=9)
      'data' => 
        array (size=2)
          0 => int 6
          1 => int 1
  2 => 
    array (size=2)
      'name' => string 'denied' (length=6)
      'data' => 
        array (size=2)
          0 => int 9
          1 => int 0
  3 => 
    array (size=2)
      'name' => string 'terminated' (length=10)
      'data' => 
        array (size=2)
          0 => int 4
          1 => int 0
  4 => 
    array (size=2)
      'name' => string 'created' (length=7)
      'data' => 
        array (size=2)
          0 => int 1
          1 => int 0
  5 => 
    array (size=2)
      'name' => string 'canceled' (length=8)
      'data' => 
        array (size=2)
          0 => int 4
          1 => int 0

我的$locations看起来像这样:

array (size=2)
  0 => string 'Location 1' (length=10)
  1 => string 'Location 2' (length=10)

对于我在每个系列上的点击事件,我创建了这个网址;

$orderListAbsoluteUrl = $this->generateUrl(
    'porder_index',
    [],
    UrlGeneratorInterface::ABSOLUTE_URL
);

$onClickFunc = new Expr("function () {
    location.href = '". $orderListAbsoluteUrl ."'
}");

我在我的图表对象中使用此$result$onClickFunc变量,就像这样;

$plotOptions = [
    'stacking' => 'normal',
    'cursor' => 'pointer',
    'point' => [
        'events' => [
            'click' => $onClickFunc
        ]
    ]
];

$ob = new Highchart();
$ob->chart->renderTo('barchart');  // The #id of the div where to render the chart
$ob->chart->type('bar');
$ob->plotOptions->series($plotOptions);
$ob->title->text('Orders per Location');
$ob->credits->enabled(false); // remove highcharts.com credits link
$ob->xAxis->title(['text'  => 'Locations']);
$ob->xAxis->categories($locations);
$ob->yAxis->title(['text'  => 'Orders']);
$ob->yAxis->allowDecimals(false);
$ob->series($result);

唯一剩下的就是在链接中添加过滤器。

现在,我正在使用Sonata作为后端,因此过滤器已经可用。所以我想我只需要修改我的$result sa位来添加过滤器的值,然后在我的$orderListAbsoluteUrl中添加该部分数组作为第二个参数,但我可以'我想一下$result的外观。

如果你从JavaScript部分的第46行看,我根据this fiddle有一个想法。

我知道我的网址的过滤器参数应该如下所示;

$filters = [
    'status' => ['type' => null, 'value' => 'XXXXXX'],
    'location' => ['type' => null, 'value' => 'YYYYYY'],
];

这样我的网址就像这样:

$orderListAbsoluteUrl = $this->generateUrl(
    'porder_index',
    ['filter' => $filters],
    UrlGeneratorInterface::ABSOLUTE_URL
);

我希望我的问题很清楚,并且有人可以帮我解决我的情况。我会很感激。提前谢谢。

1 个答案:

答案 0 :(得分:2)

我认为您可以使用哈希作为数据点,而不只是一个数字,因此您可以在其中设置URL并稍后在点击事件中使用它。

首先在创建结果数组时为每个过滤器创建URL。

$orderStatuses[$row['status']][$row['name']] = [
    // "y" as the axis point for HighCharts to use
    'y'     => $row['number_of_orders'],
    'url'   => $urlGenerator->generate(
        'porder_index',
        [
            'filters' => [
                'status' => ['type' => null, 'value' => $row['status']],
                'location' => ['type' => null, 'value' => $row['name']],
            ]
        ],
        UrlGeneratorInterface::ABSOLUTE_URL
    )
;

这最终会导致您获得类似于以下内容的数组。

array (size=6)
  0 => 
    array (size=2)
      'name' => string 'planned' (length=7)
      'data' => 
        array (size=2)
          0 =>
            array (size=2)
              'y' => int 2
              'url' => string 'https://....?filters..' (length=X)
          1 =>
            array (size=2)
              'y' => int 0
              'url' => string 'https://....?filters..' (length=X)
  //... 

然后在你的plotOptions.series.point.events.click方法中,您可以使用该url,因为它现在是传递给函数的point / this的属性。

$plotOptions = [
    'stacking' => 'normal',
    'cursor' => 'pointer',
    'point' => [
        'events' => [
            'click' => new Expr("function () {
                location.href = this.url;
            }")
        ]
    ]
];
带有系列数据的HighChart演示之一的编辑版本的

Here is a fiddle稍有改动。当您单击时它会警告url属性,但您可以在此时执行任何操作。

这样做的好处而不是尝试在前端创建网址是因为当你进行任何路由更改时,你不必确保前端和后端同步,你只需要确保Symfony正在生成正确的数据。

注意如果ObHighCharts没有将数据点数组转换为对象,可能会出现问题,但我无法确定。