为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 React 在标签中设置 img?

如何使用 React 在标签中设置 img?

茅侃侃 2021-06-17 14:01:47
我正在使用react-chartist. 在标签上,我想在标签文本旁边添加图像。我尝试了我所有的想法,但都没有奏效。一切归来[object Object]。这个问题是否有好的解决方案?我也可以使用 just 添加标签css,但如果我可以在<Chartist />组件内部添加标签,那就容易多了。我尝试的简单代码示例(下面的代码沙盒演示):class Chart extends React.Component {  render() {    const labels = ["label 1", "label 2", "label 3"];    const images = [      "http://placekitten.com/100/100",      "http://placekitten.com/101/101",      "http://placekitten.com/102/102"    ];    const series = [[40, 30, 20]];    const labelsInsideReactFragment = labels.map((el, key) => (      <React.Fragment>        <img src={images[key]} /> {el}      </React.Fragment>    ));    const labelsViaGhIssue = labels.map((el, key) => {      return {        label: el,        image: images[key]      };    });    const labelsInsideDiv = labels.map((el, key) => (      <div>        <img src={images[key]} /> {el}      </div>    ));    const labelsOnlyImg = labels.map((el, key) => <img src={images[key]} />);    const data1 = {      labels,      series    };    const data2 = {      labels: labelsViaGhIssue,      series    };    const data3 = {      labels: labelsInsideDiv,      series    };    const data4 = {      labels: labelsInsideReactFragment,      series    };    const data5 = {      labels: labelsOnlyImg,      series    };    const options = {      height: "200px",      width: "500px"    };    return (      <div>        <ChartistGraph data={data1} options={options} type="Bar" />        <ChartistGraph data={data2} options={options} type="Bar" />        <ChartistGraph data={data3} options={options} type="Bar" />        <ChartistGraph data={data4} options={options} type="Bar" />        <ChartistGraph data={data5} options={options} type="Bar" />      </div>    );  }}演示:https : //codesandbox.io/s/chartist-8oeju我还在以下网站上找到了这个演示jsbin:https : //jsbin.com/gulokelide/edit? js, output 但React我猜它没有用。
查看完整描述

3 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

JSbin 示例使用了一个on("draw")不受支持的自定义函数react-chartist(并且它还手动计算标签位置,因此如果系列中的宽度或数据量发生变化,它将不会缩放)。也就是说,最简单的解决方案是创建您自己的Chartist实例并对其进行更改以满足您的需求。

工作示例(无论 中的宽度和/或项目数量如何,标签和图像都将缩放到中心series):

组件/图表


import React, { Component, cloneElement, Children } from "react";

import Chartist from "chartist";

import PropTypes from "prop-types";


class Chart extends Component {

  componentDidUpdate(prevProps) {

    if (this.props !== prevProps) this.updateChart(this.props);

  }


  componentWillUnmount() {

    if (this.chart) {

      try {

        this.chart.detach();

      } catch (err) {

        throw new Error("Internal chartist error", err);

      }

    }

  }


  componentDidMount = () => this.updateChart(this.props);


  updateChart = ({ data, listener, options, responsiveOptions, type }) => {

    let event;


    if (this.chartist) {

      this.chart.update(data, options, responsiveOptions);

    } else {

      this.chart = new Chartist[type](

        this.chart,

        data,

        options || {},

        responsiveOptions || []

      ).on("draw", context => {

        if (type === "Pie") return;

        if (context.type === "label" && context.axis.units.pos === "x") {

          if (context && context.text) {

            const group = new Chartist.Svg("g");

            const isBar = type === "Bar";

            const hasImage = context.text.image;

            const hasLabel = context.text.label;


            if (hasImage) {

              const x = isBar

                ? context.x + context.width / 2 - 15

                : context.x + 5;

              const y = isBar

                ? context.y + context.height / 2 - 10

                : context.y + 0;


              group.append(

                new Chartist.Svg("image", {

                  "xlink:href": context.text.image,

                  width: "30px",

                  height: "30px",

                  x,

                  y

                })

              );

            }


            if (hasLabel) {

              const x = isBar

                ? context.x + context.width / 2 + 5

                : context.x + 30;

              const y = hasImage

                ? context.y + context.height / 2 + 30

                : context.y + context.height / 2;


              group.append(

                new Chartist.Svg("text", {

                  width: "100px",

                  height: "40px",

                  x,

                  y,

                  "text-anchor": "middle",

                  "alignment-baseline": "hanging"

                }).text(context.text.label || "")

              );

            }


            context.element.replace(group);

          }

        }

      });


      if (listener) {

        for (event in listener) {

          if (listener.hasOwnProperty(event)) {

            this.chart.on(event, listener[event]);

          }

        }

      }

    }


    return this.chart;

  };


  render = () => {

    const { className, style, children, data, type } = this.props;

    const childrenWithProps =

      children &&

      Children.map(children, child =>

        cloneElement(child, {

          type,

          data

        })

      );

    return (

      <div

        className={`ct-chart ${className || ""}`}

        ref={ref => (this.chart = ref)}

        style={style}

      >

        {childrenWithProps}

      </div>

    );

  };

}


Chart.propTypes = {

  type: PropTypes.oneOf(["Line", "Bar", "Pie"]).isRequired,

  data: PropTypes.object.isRequired,

  className: PropTypes.string,

  options: PropTypes.object,

  responsiveOptions: PropTypes.array,

  style: PropTypes.object

};


export default Chart;



查看完整回答
反对 回复 2021-06-18
  • 3 回答
  • 0 关注
  • 288 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号