我正在Yii2上构建一个显示图表的小部件。
我有定义的ChartsWidget类文件。
class ChartsWidget extends Widget
{
public $limit;
public $topten;
public $type;
public function init()
{
parent::init();
if ($this->limit === null) {
$this->limit = 10;
}
$this->topten = $this->GetTopTen();
if ($this->type === null) {
$this->type = "column";
}else{
$this->type=
}
}
private function GetTopTen()
{
$connection = Yii::$app->getDb();
$command = $connection->createCommand("SELECT colonias.nomasen AS name, count(rv.geom) AS conteo FROM colonias LEFT JOIN rv ON ST_Contains(colonias.geom, rv.geom) WHERE colonias.nomasen!='NINGUNO' GROUP BY colonias.nomasen ORDER BY conteo DESC LIMIT :limit")->bindValue(':limit', $this->limit);
$tops = $command->queryAll();
foreach ($tops as $top) {
$topten['names'][]=$top['name'];
$topten['conteos'][]= $this->ToInt($top['conteo']);
}
return $topten;
}
private function ToInt($valor)
{
return (int)$valor;
}
public function run()
{
return $this->render('charts', ['topten' => $this->topten, 'limit' => $this->limit, 'type' => $this->type]);
}
}
我有两个视图“type”,它是一个ActiveForm。我希望它是一个类型选择器。
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\select2\Select2;
?>
<div class="type-search" style="float: left; width: 48%;">
<?php
$form = ActiveForm::begin([
'action' => ['type'],
'method' => 'get',
]);
$data = ["column", "bar", "pie"];
echo '<label class="control-label">Tipo</label>';
echo Select2::widget([
'name' => 'state_10',
'data' => $data,
'options' => [
'placeholder' => 'Selecciona un tipo'
],
]);
?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
<?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
如何将下拉列表中的选定项目传递给ChartsWidget ???
我试过$query = Yii::$app->request->queryParams;
它不起作用。
显然,ChartsWidget没有像任何控制器那样的动作。
修改
我正在使用下拉列表,因为我希望用户选择图表类型,如条形图饼图等。
我正在这样的地图视图中调用小部件
<?= ChartsWidget::widget(['limit' => 12, 'type' => 'bar']) ?>
的视图
我可以使用上面的'type' => 'value'
访问类型。但我希望用户选择类型。
顺便说一句,我正在使用Kartik/select2
小部件来下拉列表。我使用2amigos
图表插件制作自己的小部件。
不要混淆
这可能有点令人困惑。我在寻找的是。如何将活动表单中的选定下拉数据传递给ChartsWidget
类。以及如何在ChartsWidget
类中获取该数据。
我希望你能提供帮助。感谢。
答案 0 :(得分:0)
您似乎需要使用此部分的javascript来更改应使用options
和methods
的{{1}}图表,以便在运行时更改chart.js
.update()
var myLineChart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
1}}如果需要不同的话,还要重新绘制图表和数据。
Here
是该部分的链接。
绘制图表的简单示例如下所示
bar
现在,如果我想从line
将图表类型更改为myLineChart.config.type='bar';
myLineChart.update();
,我可以使用
select2
以上2行需要绑定到按钮,或者在{case 1}}
的情况下使用原生HTML
和javascript
按钮点击更改图表的简单示例
$(document).ready(function() {
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
$("#change-bar").on('click', function() {
myChart.config.type = 'line';
myChart.update();
});
})
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<button id="change-bar">change graph</button>
<canvas id="myChart" width="400" height="400"></canvas>
&#13;
如果您想使用kartik/select2
更改图表,可以使用pluginEvents
下的事件
"select2:select" => "function() { }",
您的select2应如下所示
echo Select2::widget([
'name' => 'state_10',
'data' => $data,
'options' => [
'placeholder' => 'Selecciona un tipo'
],
'pluginEvents'=>[
"select2:select" => "function(e) {
myLineChart.config.type=$(this).val();
myLineChart.update(); }",
]
]);
以上要求变量myLineChart
在您尝试填充选择下拉列表时可用。
理想情况下,您应该将与窗口小部件中的select2相关的代码初始化为其中的一部分,或者将select元素的id传递给窗口小部件,并将更改事件绑定到窗口小部件中注册脚本的位置。
另一种解决方案是将下拉列表中的选定值作为查询字符串参数附加到URL
,然后使用新URL重新加载页面,然后将其分配给类选项$type
init()
使用Yii::$app->request->queryParams
,并将其传递到您正在调用图表小部件的视图文件中,如下所示
<?= ChartsWidget::widget(['limit' => 12, 'type' => $type]) ?>
您填充代码的视图在这种情况下将如下所示
$data = ["column", "bar", "pie"];
$baseUrl=\yii\helpers\Url::current(['type'=>null]);
echo \kartik\widgets\Select2::widget([
'name' => 'state_10',
'data' => $data,
'options' => [
'placeholder' => 'Selecciona un tipo'
],
'pluginEvents'=>[
"select2:select" => "function(e) { location='$baseUrl?type='+$(this).select2(\"data\")[0].text}",
]
]);
在ChartWidget
功能内的init()
课程中添加以下内容
if(isset(Yii::$app->request->queryParams['type'])){
$this->type=Yii::$app->request->queryParams['type'];
}
而不是在null
中检查$type
值时,在声明class属性时将默认类型更改为
public $type='column';
该课程的完整代码如下所示
namespace app\componets\charts;
use Yii;
use yii\base\Widget;
class ChartsWidget extends Widget {
public $limit;
public $topten;
public $type = 'column';
public function init() {
parent::init ();
if ( $this->limit === null ) {
$this->limit = 10;
}
$this->topten = $this->GetTopTen ();
if ( isset ( Yii::$app->request->queryParams['type'] ) ) {
$this->type = Yii::$app->request->queryParams['type'];
}
}
private function GetTopTen() {
$connection = Yii::$app->getDb ();
$command = $connection->createCommand ( "SELECT colonias.nomasen AS name, count(rv.geom) AS conteo FROM colonias LEFT JOIN rv ON ST_Contains(colonias.geom, rv.geom) WHERE colonias.nomasen!='NINGUNO' GROUP BY colonias.nomasen ORDER BY conteo DESC LIMIT :limit" )->bindValue ( ':limit' , $this->limit );
$tops = $command->queryAll ();
foreach ( $tops as $top ) {
$topten['names'][] = $top['name'];
$topten['conteos'][] = $this->ToInt ( $top['conteo'] );
}
return $topten;
}
private function ToInt( $valor ) {
return ( int ) $valor;
}
public function run() {
return $this->render ( 'charts' , [ 'topten' => $this->topten , 'limit' => $this->limit , 'type' => $this->type ] );
}
}
由于当前分配的数据是数组
$data = ["column", "bar", "pie"];
以及上面给出的代码我们正在使用select2-select
事件绑定$(this).val()
事件,它将传递整数值而不是实际字符串,您可以更改数组以保存名称值对
$data = ["column"=>"column", "bar"=>"bar", "pie"=>"pie"];
或更改javascript代码以检测所选文本而不是值
$(this).select2(\"data\")[0].text;