【问题标题】:Vue Chart.js - simple dot/line on bar chartVue Chart.js - 条形图上的简单点/线
【发布时间】:2018-12-06 07:21:20
【问题描述】:

我需要在我的bar 图表上添加一条简单的点/垂直线,该图表具有动态 X 值,0 表示 Y 值。我需要的预览(红点):

绿色值是动态的。

预览我目前的状态:

其中 3.30 应该是点的 X 坐标 - [3.30, 0]。

我在图表中使用Vue chart,我尝试使用barscatter 创建一个mixed,但scatter 需要type: 'linear',因为它是xAxis,它不适合我需要bar 图表。

所以我尝试使用chartjs-plugin-annotation,它是接受“坐标”的box 类型,但这里的问题是X必须是X 轴上的固定值(@ 987654339@ 对象)。如果我把 X 轴设为 [3,0] 就可以了,但是如果有一个十进制数,比如 [3.5, 0] 就不行了。


  // data
  options: {
    responsive: true,
    maintainAspectRatio: false,
    legend: {
      display: false
    },
    scales: {
      yAxes: [{
        ticks: {
          min: 0,
          max: 1,
          stepSize: 0.1
        }
      }]
    }
  }

  // computed 
  labels: [1, 2, 3, 4, 5, 6], // fixed value, there are always 6 bars
  datasets: [
    {
      label: 'Values',
      backgroundColor: '#f89098',
      data: this.tableInputValues // array of decimal values
    }
  ]

所以,我的问题是如何在 Chart.js 条形图上放置一个“简单”点或垂直线,其中该点具有 X 轴的动态值 -> [动态值,0]。

仅供参考 - 关于Expected value

【问题讨论】:

  • 你能创作小提琴吗?
  • @KrzysztofAtłasik 这是example。所以现在假设想在 xAxis 上有一个点,或者 xAxes 值是动态的垂直线(如 3.9 或 2.75)。
  • @Vucko,你好,你能描述一下你的问题吗,比如x轴和y轴用来描述什么数据?快照中的示例,x 轴用于描述值,y 轴用于频率(0.0 到 1.0),但在您的小提琴中,x 轴与您的问题无关。以及您要显示的 x 轴上的点所描述的数据是什么?我认为您可以使用混合类型的type: 'buddle' 来解决您的问题,但我希望详细说明。

标签: vue.js charts vuejs2 vue-chartjs


【解决方案1】:

据我了解 Vue Chart 使用画布(如 Demo page 所示)。
所以,我的建议是在你的 DOM 中检索代表图表的画布节点并动态写入所需的点。例如:

var c = document.getElementById("bar-chart");   //hereby assuming canvas named "bar-chart"
var ctx = c.getContext("2d");
ctx.fillStyle = "#ff0000";                     //red color for the dot
ctx.beginPath();
let yPosition = c.height - 5;                 //fixed y position
let xPosition = 35;                          //that's the dynamic expected value
ctx.arc(xPosition, yPosition, 2.5, 0, 2 * Math.PI);
ctx.fill();

Here 你可以找到一个演示,展示如何使用 Vue 实现这一目标。在这种情况下,您需要将代码包装在 afterDraw 挂钩中以在画布上绘制一个点。这个钩子需要作为插件附加到图表组件上,所以像这样:

...
mounted () { 
   //adding the plugin to draw the red dot
   this.addPlugin({
    id: 'chart-plugin',
    afterDraw: function (chart) {
       var c = chart.canvas;   
       var ctx = c.getContext("2d");
       ctx.fillStyle = "#ff0000";                     
       ctx.beginPath();
       let xPosition = 742; //x positioning to be calculated according to your needs
       let yPosition = c.height - 28;                                       
       ctx.arc(xPosition, yPosition, 3, 0, 2 * Math.PI);
       ctx.fill();
    }
  });

  //actual chart rendering
  this.renderChart({ 
    ...
  });
}
...

为了完整起见,here 您可以找到 Chart.js 插件 API 的所有可用钩子的列表。

【讨论】:

  • 如果您修改 Vue 解决方案的答案,我将不胜感激。谢谢
  • @Vucko 给你。
  • Tnx 用于更新,我会在测试时通知您。
  • @Vucko 欢迎您。 vue-chart 插件的示例在这里:codepen.io/anon/pen/oJXVRx
  • 不错! Tnx 的帮助。干杯!
【解决方案2】:

这是我的解决方案https://jsfiddle.net/huynhsamha/e54djwxp/

这是结果的截图

在我的解决方案中,我使用type="line",x 轴和y 轴都使用type="linear"。我还将属性options 添加到<chart>,以便在ChartJS 中使用options

<div id="vue">
  <chart type="line" :data="data" :options="options"></chart>
</div>

options 会设置 x 轴和 y 轴来渲染数据点和期望值:

      options: {
        scales: {
            xAxes: [{
            type: 'linear',
            ticks: {
                min: 1,
                max: 6,
                stepSize: 1
            }
          }],
           yAxes: [{
            type: 'linear',
            ticks: {
                min: 0,
                max: 1,
                stepSize: 0.1
            }
            }]
        }
      }

data 将有 2 个datasets。第一个是数据点,使用line,第二个是期望值,使用bubble

      data: {
        datasets: [{
            label: 'Frequency Data',
            data: dataPoints.map(({ val, freq }) => ({
                x: val,
              y: freq
            })),
            backgroundColor: 'rgba(72, 202, 59, 0.4)',
            borderColor: 'rgba(72, 202, 59, 1)'
        }, {
            label: 'Expected Value',
            type: 'bubble',
            data: [{ 
                x: expectedValue, 
              y: 0, 
              r: 8 // radius
            }],
            backgroundColor: 'rgba(255, 68, 0, 0.4)',
            borderColor: 'rgba(255, 68, 0, 1)'
        }]
        },

datasets 中,我们有dataPointsexpectedValue,它们将从API 中获取以获取您的数据点。我还模拟了数据点的简单 API:

// simulate the API to get data points
const retrieveData = () => [
    { val: 1, freq: 0.15 },
    { val: 2, freq: 0.25 },
    { val: 3, freq: 0.3 },
    { val: 4, freq: 0.2 },
    { val: 5, freq: 0.1 },
    { val: 6, freq: 0.45 }
]


// fetch your data here, return array of JSON { val, freg }
const dataPoints = retrieveData() || [];

// calculate expected value = sum( val * freq ) each i in dataPoints
const expectedValue = dataPoints.reduce((cur, { val, freq }) => cur + val * freq, 0).toFixed(4);

你可以运行 sn-p 或在 fiddle 上运行 https://jsfiddle.net/huynhsamha/e54djwxp/92/

&lt;script async src="//jsfiddle.net/huynhsamha/e54djwxp/92/embed/js,html,css,result/dark/"&gt;&lt;/script&gt;

【讨论】:

  • Tnx 的答案,非常好的解决方案。
  • 这是什么包?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
相关资源
最近更新 更多