使用Charts.js的两个不同的X轴并做出反应

时间:2020-07-12 16:33:49

标签: javascript reactjs charts chart.js

我正在尝试使用chart.js在React中为天气创建一个图表组件。我想要两个不同的x轴,其温度在图表上方,时间在图表下方。数据是正确的,我只想在x轴的顶部和底部使用两个不同的标签。我该怎么办?

import React from "react";
import { Line } from "react-chartjs-2";

class WeatherOverview extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      chartData: {
        labels: [
          "15:00",
          "18:00",
          "21:00",
          "00:00",
          "03:00",
          "06:00",
          "09:00",
          "12:00",
        ], //time
        datasets: [
          {
            data: [18, 19, 18, 16, 15, 15, 16, 17, 18], //temp
          },
        ],
      },
    };
  }
  render() {
    return (
      <div className="chart">
        <Line
          data={this.state.chartData}
          options={{
            scales: {
              yAxes: [
                {
                  gridLines: {
                    drawOnChartArea: false,
                  },
                  ticks: {
                    suggestedMin: 13, // lowest from data minus 2/3
                    display: false,
                  },
                },
              ],
              xAxes: [
                {
                  gridLines: {
                    drawOnChartArea: false,
                  },
                },
                { position: "top" },
              ],
            },
          }}
        />
      </div>
    );
  }
}

export default WeatherOverview;

我想要类似谷歌天气部件-

enter image description here

2 个答案:

答案 0 :(得分:0)

这是我的方法:

var chartData = {
    labels: ['15:00', '18:00', '21:00', '00:00', '03:00', '06:00', '09:00', '12:00'],
    datasets: [
        {
            fillColor: "#FFF5D7",
            strokeColor: "#FFCC01",
            data: [18, 19, 18, 16, 15, 15, 16, 17, 18]
        }
    ]
};

var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
    scaleOverride : true,
    scaleSteps : 10,
    scaleStepWidth : 3,
    scaleStartValue : 0,
    showTooltips: false,
    onAnimationComplete: function () {
        var ctx = this.chart.ctx;
        ctx.font = this.scale.font;
        ctx.fillStyle = this.scale.textColor
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";

        this.datasets.forEach(function (dataset) {
            dataset.points.forEach(function (points) {
                ctx.fillText(points.value, points.x, 20);
            });
        })
    }
});

https://jsfiddle.net/MartinGK/u4Lr8gzw/31/

也许会帮助您入门。

我建议继续阅读the documentation

答案 1 :(得分:0)

要将Google Weather示例与浮动在数据点上的值匹配,您真正需要的是chartjs-plugin-datalabels之类的插件。

通过npm安装它:

npm install chartjs-plugin-datalabels --save

导入:

import 'chartjs-plugin-datalabels';

并将其包含在您的options对象中:

plugins: {
   datalabels: {
      display: true
   }
}

这将在数据点顶部添加数据标签。有关如何自定义数据标签的更多信息,请参见documentation

我通过其他一些更改使您的图表看起来像Google天气预报图表。这是使用您的数据的完整示例:

Google Weather-like chart using Chart.js

我所做的一些更改包括:

  • 添加了datalabels插件
  • 相应地设置颜色
  • 在数据集上将pointRadius设置为0
  • 删除了多余的X轴
  • 在每个轴上分别设置drawBorder: falsetickMarkLength: 0
{
  type: 'line',
  data: {
    labels: ['15:00', '18:00', '21:00', '00:00', '03:00', '06:00', '09:00', '12:00'], //time
    datasets: [{
      data: [18, 19, 18, 16, 15, 15, 16, 17, 18], //temp
      backgroundColor: '#fff5cc',
      borderColor: '#fc0',
      pointRadius: 0,
    }],
  },
  options: {
    scales: {
      yAxes: [{
        gridLines: {
          drawOnChartArea: false,
          drawBorder: false,
          tickMarkLength: 0,
        },
        ticks: {
          suggestedMin: 13, // lowest from data minus 2/3
          display: false
        }
      }],
      xAxes: [{
        gridLines: {
          drawOnChartArea: false,
          drawBorder: false,
          tickMarkLength: 0,
        },
        ticks: {
          fontColor: '#bababa',
        }
      }]
    },
    legend: {
      display: false
    },
    layout: {
      padding: {
        top: 20
      }
    },
    plugins: {
      datalabels: {
        align: 'top',
        color: '#bababa',
        font: {
          weight: 'bold'
        },
        display: true,
      },
    },
  }
}