入れ子ドーナツ・チャートの作成
注: これはCharts with Widgets Galleryの例の一部です。
まず、QChartView インスタンスを作成し、アンチエイリアスを有効にします。次にQChartView インスタンスからQChart オブジェクトを取得します。凡例は無効化され、チャートのタイトルが設定されます。最後の行は、チャートのアニメーションを有効にする。
auto chartView = new QChartView(this); chartView->setRenderHint(QPainter::Antialiasing); QChart *chart = chartView->chart(); chart->legend()->setVisible(false); chart->setTitle("Nested Donuts (Hover over segments to explode them)"); chart->setAnimationOptions(QChart::AllAnimations); chart->layout()->setContentsMargins(0, 0, 0, 0);
ドーナツ・チャートの定義に使われる3つの変数が定義されている。minSizeは最小のドーナツの内側の相対サイズ、maxSizeは最大のドーナツの外側の相対サイズです。
次のコードのブロックは、個々のドーナツとそのスライスを定義します。まず、新しいQPieSeries オブジェクトが作成されます。各ドーナツのスライス数はランダムである。内部のforループがランダムな値と同じラベルでスライスを作成する。次に、スライスのラベルが見えるように設定され、色が白に設定されます。この例をより面白くするために、スライスのホバー信号がウィジェットのスロットに接続されます。最後に、スライスがドーナツに追加されます。ドーナツのサイズは、ドーナツの入れ子になるように調整される。それから、ドーナツがウィジェットのドーナツ・リストとチャートに追加されます。
for (int i = 0; i < donutCount; i++) { auto donut = new QPieSeries; int sliceCount = 3 + QRandomGenerator::global()->bounded(3); for (int j = 0; j < sliceCount; j++) { qreal value = 100 + QRandomGenerator::global()->bounded(100); auto slice = new QPieSlice(QString("%1").arg(value), value); slice->setLabelVisible(true); slice->setLabelColor(Qt::white); slice->setLabelPosition(QPieSlice::LabelInsideTangential); connect(slice, &QPieSlice::hovered, this, &NestedDonutsWidget::explodeSlice); donut->append(slice); donut->setHoleSize(minSize + i * (maxSize - minSize) / donutCount); donut->setPieSize(minSize + (i + 1) * (maxSize - minSize) / donutCount); } m_donuts.append(donut); chartView->chart()->addSeries(donut); }
最後に、ウィジェットはアプリケーションで使われるレイアウトに配置されます。
auto mainLayout = new QGridLayout; mainLayout->addWidget(chartView, 1, 1); setLayout(mainLayout);
この例をより面白くするために、ドーナツは1.25秒ごとにランダムに回転します。
m_updateTimer = new QTimer(this); connect(m_updateTimer, &QTimer::timeout, this, &NestedDonutsWidget::updateRotation); m_updateTimer->start(1250);
ウィジェットのupdatedRotationスロットを以下に定義します。これは、すべてのドーナツを調べて、現在の回転をランダムな値で変更します。
void NestedDonutsWidget::updateRotation() { for (int i = 0; i < m_donuts.count(); i++) { QPieSeries *donut = m_donuts.at(i); qreal phaseShift = -50 + QRandomGenerator::global()->bounded(100); donut->setPieStartAngle(donut->pieStartAngle() + phaseShift); donut->setPieEndAngle(donut->pieEndAngle() + phaseShift); } }
先に述べたexplodeSliceスロットのコードを以下に示します。スライスがexplodeに設定されたら、ドーナツの回転を制御するタイマーを止める。その後、スライスの開始角度と終了角度をスライスから取得します。選択されたスライスを強調するために、選択されたスライスを含むドーナツから外側にある他のドーナツの開始角度と終了角度をすべて変更し、強調されたスライスの道を「ふさがない」ようにします。スライスが選択されなくなったら、元の状態に戻ります。
void NestedDonutsWidget::explodeSlice(bool exploded) { auto slice = qobject_cast<QPieSlice *>(sender()); if (exploded) { m_updateTimer->stop(); qreal sliceStartAngle = slice->startAngle(); qreal sliceEndAngle = slice->startAngle() + slice->angleSpan(); QPieSeries *donut = slice->series(); qreal seriesIndex = m_donuts.indexOf(donut); for (int i = seriesIndex + 1; i < m_donuts.count(); i++) { m_donuts.at(i)->setPieStartAngle(sliceEndAngle); m_donuts.at(i)->setPieEndAngle(360 + sliceStartAngle); } } else { for (int i = 0; i < m_donuts.count(); i++) { m_donuts.at(i)->setPieStartAngle(0); m_donuts.at(i)->setPieEndAngle(360); } m_updateTimer->start(); } slice->setExploded(exploded); }
©2024 The Qt Company Ltd. 本文書に含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。