用Highcharts動畫製作彩票輪

語言: CN / TW / HK

Highcharts是一款純JavaScript編寫的圖表庫,為你的Web網站、Web應用程式提供直觀、互動式圖表。當前支援折線、曲線、區域、區域曲線圖、柱形圖、條形圖、餅圖、散點圖、角度測量圖、區域排列圖、區域曲線排列圖、柱形排列圖、極座標圖等幾十種圖表型別。

點選下載Highcharts最新試用版

在本教程中,我們將向您展示如何使用Highcharts構建彩票輪。由於高度可定製的庫功能,這是可能的,您幾乎可以建立任何基於SVG的互動式視覺化,例如互動式拼圖或蛇遊戲。
下圖顯示了一個彩票輪和四個設定選項:

 

讓我們檢查程式碼,並瞭解如何建立這樣的演示。

該程式碼有四個主要部分:

  1. 建立圖表
  2. 旋轉動畫
  3. 選擇獲勝者
  4. 春季動畫
  5. 從春季動畫中選擇獲勝者

建立圖表

第一步是使用箭頭建立輪子。
車輪程式碼簡單明瞭。這只是一個基本的餅圖:

chart = Highcharts.chart('container', {
      chart: {
        animation: false,
        marginTop: 100,
        events: {
          ...
        },
        title: {
          text: 'Chance wheel'
        },
        series: [{
          type: 'pie',
          size: '100%',
          dataLabels: {
            distance: -20
          },
          data: [
            ['Pudding', 1],
            ['Cake', 1],
            ['Salad', 1],
            ['Potato', 1],
            ['Bread', 1]
          ],
          startAngle: 360 * Math.random()
        }]
      });

使用Highcharts時未提供開箱即用的箭頭,因此您必須從頭開始構建它。由於使用了renderer方法,您可以輕鬆地將任何自定義路徑新增到Highcharts程式碼。

triangle = chart.renderer.path([
    ['M', chart.chartWidth / 2 - 10, chart.plotTop - 5],
    ['L', chart.chartWidth / 2 + 10, chart.plotTop - 5],
    ['L', chart.chartWidth / 2, chart.plotTop + 10],
    ['Z']
  ])
  .attr({
    fill: 'black'
  })
  .add();

完成此部分後,就該移動到動畫部分了。

旋轉動畫

對於旋轉動畫,有兩個主要部分:

  • 事件處理程式
  • 圖表更新

主要事件來自單擊“旋轉”按鈕,這將觸發動畫。動畫具有更新圖表方法,可根據新的處理後的角度渲染圖表。在setInterval函式中,每次迭代都會呼叫update chart方法,這就是旋轉效果的原因:
button.addEventListener('click', e => {....

// Create the arrow at the top.
t = setInterval(() => { // Animation loop
      if (!physics.isActive) {
        startAngle += diff;
        if (startAngle > 360) {
          startAngle -= 360;
        }
        diff *= 0.98;
        chart.series[0].update({
          startAngle
        });

藉助此巧妙公式中的diff變數,車輪每次旋轉後速度都會降低。現在,車輪能夠旋轉並停止。讓我們看看如何選擇一個贏家。diff *= 0.98; 

選擇獲勝者

輪子停止運動後,findWinner如果箭頭位置在切片起始角度和閾值之內,則以下方法將遍歷資料集或切片並進行處理winThreshold。如果存在匹配項,則findWinner返回切片的索引以獲取標籤並顯示獲勝者。

const findWinner = (data) => {
  const sliceSize = 360 / data.length;
  const winThreshold = 360 - sliceSize;
  let sliceBeginning;
  for (let i in data) {
    sliceBeginning = radToDeg(data[i].shapeArgs.start) + 90;
    if (sliceBeginning > 360) {
      ...
    }
  }
  return -1;
}

到目前為止,該演示包含所有彩票輪元件(請參見下面的演示):

但是,我們還沒有完成。讓我們玩得開心,新增一些虛構的物理運動🙂

春季動畫

產生人造物理學運動的最重要變數是力,阻力,當前角度,目標角度,強度和閾值。讓我們將它們全部收集在一個物體物理下:

let physics = {
  force: 0,
  angleVel: 0,
  angle: 0,
  prevAngle: 0, // only used to calculate winner
  strength: 0.003 + strengthSlider.value / 10000, // tweakable
  drag: 0.98 + dragSlider.value / 1000, // tweakable
  threshold: 2 + lengthSlider.value / 10, // tweakable
  targ: 0,
  isActive: false
};

從春季動畫中選擇獲勝者

本教程的最後一步是選擇獲勝者。隨著方向盤左右移動,我們會讀取每個方向改變的臨時獲勝者。如果連續兩次選擇獲勝者的索引,則肯定選擇了獲勝者(請參見下面的程式碼):

if (physics.prevAngle >= physics.angle && currentWinner < 0) {
  currentWinner = findWinner(chart.series[0].data);
  foundPossibleWinner = true;
} else if (
  physics.prevAngle <= physics.angle &&
  foundPossibleWinner
) {
  const nextWinner = findWinner(chart.series[0].data);
  if (currentWinner == nextWinner) {
    chart.setTitle({
      text: 'The winner is ' +
        chart.series[0].data[currentWinner].name + '!'
    });
    foundPossibleWinner = false;
    button.disabled = false;
  } else {
    currentWinner = -1;
    foundPossibleWinner = false;
  }
}

 


APS幫助提升企業生產效率,真正實現生產計劃視覺化呈現與控制,快速有效響應不同場景的生產計劃,提高準時交貨能力,提高產能和資源利用率

想要購買Highcharts正版授權,或瞭解更多產品資訊請點選【諮詢線上客服】