arcgis JavaScript api实现同时展示多个撒点气泡

实现的效果如下图

代码如下

createCIMWatertQuality(data: any) {

// 饼图样式配置(可根据需求调整)

const pieConfig = {

outerRadius: 3.5, // 外半径(适配背景框大小)

innerRadius: 2, // 内半径(环状空白部分)

centerX: 3.5, // 饼图中心X(背景框中心)

centerY: 6.5, // 饼图中心Y(上移1个单位,避开标题)

defaultColors: [

// 默认扇区颜色(可通过data.colors覆盖)

255, 255, 102, 255\], // 浅黄 \[0, 255, 255, 255\], // 浅蓝 \[255, 102, 102, 200\], // 浅红 \[102, 255, 102, 200\], // 浅绿 \[255, 102, 255, 200\] // 浅紫

};

const getRingSectorPath = (startAngle: number, endAngle: number) => {

const points = [];

const step = (endAngle - startAngle) / 30; // 分段数(越多越平滑)

复制代码
  // 1. 绘制外圆弧(从startAngle到endAngle)
  for (let angle = startAngle; angle < endAngle; angle += step) {
    const x = pieConfig.centerX + pieConfig.outerRadius * Math.cos(angle);
    const y = pieConfig.centerY + pieConfig.outerRadius * Math.sin(angle);
    points.push([x, y]);
  }
  points.push([
    pieConfig.centerX + pieConfig.outerRadius * Math.cos(endAngle),
    pieConfig.centerY + pieConfig.outerRadius * Math.sin(endAngle)
  ]);

  // 2. 绘制内圆弧(反向,从endAngle到startAngle)
  for (let angle = endAngle; angle > startAngle; angle -= step) {
    const x = pieConfig.centerX + pieConfig.innerRadius * Math.cos(angle);
    const y = pieConfig.centerY + pieConfig.innerRadius * Math.sin(angle);
    points.push([x, y]);
  }
  // 强制添加起始角度的点,确保内圆弧精确闭合
  points.push([
    pieConfig.centerX + pieConfig.innerRadius * Math.cos(startAngle),
    pieConfig.centerY + pieConfig.innerRadius * Math.sin(startAngle)
  ]);

  // 3. 闭合路径(回到外圆弧起点)
  points.push([
    pieConfig.centerX + pieConfig.outerRadius * Math.cos(startAngle),
    pieConfig.centerY + pieConfig.outerRadius * Math.sin(startAngle)
  ]);
  return points;
};
const generatePieGraphics = () => {
  const graphics = [];
  const values = data.value || [12, 22];
  const total = values.reduce((sum: number, item: any) => sum + (item.value || 0), 0);
  // 无有效数据时,绘制一个灰色空环
  if (total === 0) {
    graphics.push({
      type: "CIMMarkerGraphic",
      geometry: {
        rings: [getRingSectorPath(0, 2 * Math.PI)] // 完整圆环
      },
      symbol: {
        type: "CIMPolygonSymbol",
        symbolLayers: [
          { type: "CIMSolidFill", enable: true, color: [150, 150, 150, 100] } // 灰色半透明
        ]
      }
    });
    return graphics;
  }
  // 有数据时,计算每个扇区的角度并生成图形
  let startAngle = 0; // 起始角度(0弧度=右侧)
  const colors = data.colors || pieConfig.defaultColors;
  values.forEach((item: any, index: number) => {
    if (item.value <= 0) return; // 跳过0值
    const ratio = item.value / total;
    const endAngle = startAngle + ratio * 2 * Math.PI; // 结束角度
    const color = colors[index] || colors[index % colors.length]; // 取颜色(循环使用)
    let title = "优III类:";
    if (item.type === 0) {
      title = "劣V类:";
    }
    graphics.push({
      type: "CIMMarkerGraphic",
      geometry: {
        rings: [getRingSectorPath(startAngle, endAngle)]
      },
      symbol: {
        type: "CIMPolygonSymbol",
        symbolLayers: [
          { type: "CIMSolidStroke", enable: true, color: [255, 255, 255, 200], width: 0.2 }, // 扇区边框
          { type: "CIMSolidFill", enable: true, color: color }, // 扇区填充色
          {
            type: "CIMVectorMarker",
            enable: true,
            offsetX: -6,
            offsetY: 22,
            size: 180,
            frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
            markerGraphics: [
              {
                type: "CIMMarkerGraphic",
                geometry: {
                  x: 0,
                  y: 0
                },
                symbol: {
                  type: "CIMPolygonSymbol",
                  symbolLayers: [
                    {
                      type: "CIMVectorMarker",
                      enable: true,
                      size: 12,
                      colorLocked: true,
                      anchorPointUnits: "Relative",
                      frame: { xmin: 0, ymin: 0, xmax: 14, ymax: 14 },
                      markerGraphics: [
                        {
                          type: "CIMMarkerGraphic",
                          geometry: { x: 65, y: -10 + index * -25 },
                          symbol: {
                            type: "CIMTextSymbol",
                            fontFamilyName: "Arial",
                            fontStyleName: "Bold",
                            height: 12,
                            horizontalAlignment: "Center",
                            symbol: {
                              type: "CIMPolygonSymbol",
                              symbolLayers: [{ type: "CIMSolidFill", color: color }]
                            },
                            verticalAlignment: "Top"
                          },
                          textString: `${item.value}`
                        },
                        {
                          type: "CIMMarkerGraphic",
                          geometry: { x: 35, y: -10 + index * -25 },
                          symbol: {
                            type: "CIMTextSymbol",
                            fontFamilyName: "Arial",
                            fontStyleName: "Bold",
                            height: 12,
                            horizontalAlignment: "Center",
                            symbol: {
                              type: "CIMPolygonSymbol",
                              symbolLayers: [{ type: "CIMSolidFill", color: [255, 255, 255, 255] }]
                            },
                            verticalAlignment: "Top"
                          },
                          textString: `${title}`
                        }
                      ],
                      scaleSymbolsProportionally: true,
                      respectFrame: true
                    }
                  ]
                }
              }
            ]
          }
        ]
      }
    });

    startAngle = endAngle; 
  });

  return graphics;
};
const symbol = new CIMSymbol({
  data: {
    type: "CIMSymbolReference",
    symbol: {
      type: "CIMPointSymbol",
      symbolLayers: [
        // 3. 新增:环状饼图图层
        {
          type: "CIMVectorMarker",
          enable: true,
          size: 108,
          frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
          markerGraphics: generatePieGraphics() 
        },
        {
          type: "CIMVectorMarker",
          enable: true,
          offsetX: -45,
          offsetY: 40,
          size: 78,
          frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
          markerGraphics: [
            {
              type: "CIMMarkerGraphic",
              geometry: {
                x: 0,
                y: 0
              },
              symbol: {
                type: "CIMPolygonSymbol",
                symbolLayers: [
                  {
                    type: "CIMVectorMarker",
                    enable: true,
                    size: 12,
                    colorLocked: true,
                    anchorPointUnits: "Relative",
                    frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
                    markerGraphics: [
                      {
                        type: "CIMMarkerGraphic",
                        geometry: { x: 15, y: 0 },
                        symbol: {
                          type: "CIMTextSymbol",
                          fontStyleName: "Bold",
                          height: 14,
                          horizontalAlignment: "Center",
                          symbol: {
                            type: "CIMPolygonSymbol",
                            symbolLayers: [{ type: "CIMSolidFill", color: [255, 255, 255, 255] }]
                          },
                          verticalAlignment: "Top",
                          textString: data.name || "未命名监测点"
                        },
                        textString: data.name || "未命名监测点"
                      }
                    ],
                    scaleSymbolsProportionally: true,
                    respectFrame: true
                  }
                ]
              }
            }
          ]
        },
        {
          type: "CIMPictureMarker",
          enable: true,
          anchorPoint: {
            x: 0,
            y: 0
          },
          size: 78,
          scaleX: 1,
          tintColor: [255, 255, 255, 255],
          url: boxImg
        }
      ]
    }
  }
});
return symbol;

}

实现柱状图如下图效果

代码如下:

createCIMsymbol(barData1: any) {

const bgBox = {

xMin: 1, // 背景框左边界

xMax: 12, // 背景框右边界

yMin: 4, // 背景框上边界

yMax: 4.5, // 背景框下边界

width: 10, // 背景框宽度

height: 3.5 // 背景框高度

};

const safeBarBox = {

...bgBox,

yMax: 7.6 - 0.5

};

const barConfig = {

width: 1.5, // 单根柱子宽度

spacing: 0.4, // 组内柱子间距

maxHeight: safeBarBox.height + 1,

baseX: bgBox.xMin + 0.5,

baseY: 0

};

const allValues = [...barData1.value.map(item => item.value)];

const maxValue = Math.max(...allValues, 1);

const heightRatio = barConfig.maxHeight / maxValue;

复制代码
const buildBarGroup = (data: any[], groupOffsetX: number) => {
  const groupTotalWidth = data.length * (barConfig.width + barConfig.spacing) - barConfig.spacing;
  const maxAllowX = bgBox.xMax - 0.5;
  const groupEndX = groupOffsetX + groupTotalWidth;

  if (groupEndX > maxAllowX) {
    const excessRatio = (maxAllowX - groupOffsetX) / groupTotalWidth;
    barConfig.width = barConfig.width * excessRatio; // 按比例缩小宽度
    const newGroupTotalWidth = data.length * (barConfig.width + barConfig.spacing) - barConfig.spacing;
    if (newGroupTotalWidth > maxAllowX - groupOffsetX) {
      barConfig.width = (maxAllowX - groupOffsetX - (data.length - 1) * barConfig.spacing) / data.length;
    }
  }

  let layers: any[] = [];
  data.forEach((item, index) => {
    const barX = groupOffsetX + index * (barConfig.width + barConfig.spacing);
    const barHeight = Math.min(item.value * heightRatio, barConfig.maxHeight);

    const barTopY = safeBarBox.yMin + 0.5; // 顶部留边距
    const barBottomY = barTopY + barHeight;
    const finalBarBottomY = barBottomY;

    const barGeometry = {
      rings: [
        [
          [barX, barTopY], // 左上(Y小,靠上)
          [barX + barConfig.width, barTopY], // 右上
          [barX + barConfig.width, finalBarBottomY], // 右下
          [barX, finalBarBottomY], // 左下
          [barX, barTopY] // 闭合
        ]
      ]
    };
    let color = [53, 243, 243, 255];
    let borderColor = [184, 254, 254, 255];
    if (index === 0) {
      borderColor = [255, 249, 226, 255];
      color = [255, 209, 49, 255];
    }
    layers.push({
      type: "CIMVectorMarker",
      enable: true,
      size: 180,
      frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
      markerGraphics: [
        {
          type: "CIMMarkerGraphic",
          geometry: barGeometry,
          symbol: {
            type: "CIMPolygonSymbol",
            symbolLayers: [
              { type: "CIMSolidStroke", color: borderColor, width: 1, capStyle: "Round", joinStyle: "Round" },
              { type: "CIMSolidFill", color: color, capStyle: "Round", joinStyle: "Round" },
              {
                type: "CIMVectorMarker",
                enable: true,
                offsetX: -6,
                offsetY: 45,
                size: 80,
                frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
                markerGraphics: [
                  {
                    type: "CIMMarkerGraphic",
                    geometry: {
                      x: 0,
                      y: 0
                    },
                    symbol: {
                      type: "CIMPolygonSymbol",
                      symbolLayers: [
                        {
                          type: "CIMVectorMarker",
                          enable: true,
                          size: 12,
                          colorLocked: true,
                          anchorPointUnits: "Relative",
                          frame: { xmin: 0, ymin: 0, xmax: 14, ymax: 14 },
                          markerGraphics: [
                            {
                              type: "CIMMarkerGraphic",
                              geometry: { x: 73, y: -40 + index * -25 },
                              symbol: {
                                type: "CIMTextSymbol",
                                fontFamilyName: "Arial",
                                fontStyleName: "Bold",
                                height: 12,
                                horizontalAlignment: "Center",
                                symbol: {
                                  type: "CIMPolygonSymbol",
                                  symbolLayers: [{ type: "CIMSolidFill", color: color }]
                                },
                                verticalAlignment: "Top"
                              },
                              textString: `${item.value}%`
                            },
                            {
                              type: "CIMMarkerGraphic",
                              geometry: { x: 22, y: -40 + index * -25 },
                              symbol: {
                                type: "CIMTextSymbol",
                                fontFamilyName: "Arial",
                                fontStyleName: "Bold",
                                height: 12,
                                horizontalAlignment: "Center",
                                symbol: {
                                  type: "CIMPolygonSymbol",
                                  symbolLayers: [{ type: "CIMSolidFill", color: [255, 255, 255, 255] }]
                                },
                                verticalAlignment: "Top"
                              },
                              textString: `当前水面率:`
                            }
                          ],
                          scaleSymbolsProportionally: true,
                          respectFrame: true
                        }
                      ]
                    }
                  }
                ]
              }
            ]
          }
        }
      ]
    });
  });
  return layers;
};
barConfig.baseX = bgBox.xMin + 0.5; // 固定靠左(背景框左边界+0.5留边)

const barLayers = [...buildBarGroup(barData1.value, barConfig.baseX)];

const symbol = new CIMSymbol({
  data: {
    type: "CIMSymbolReference",
    symbol: {
      type: "CIMPointSymbol",
      symbolLayers: [
        // 柱形图图层(包含文字)
        ...barLayers,
        // 标题
        {
          type: "CIMVectorMarker",
          enable: true,
          offsetX: -7.5,
          offsetY: 28,
          size: 80,
          frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
          markerGraphics: [
            {
              type: "CIMMarkerGraphic",
              geometry: {
                x: 0,
                y: 0
              },
              symbol: {
                type: "CIMPolygonSymbol",
                symbolLayers: [
                  {
                    type: "CIMVectorMarker",
                    enable: true,
                    size: 12,
                    colorLocked: true,
                    anchorPointUnits: "Relative",
                    frame: { xmin: 0, ymin: 0, xmax: 16, ymax: 16 },
                    markerGraphics: [
                      {
                        type: "CIMMarkerGraphic",
                        geometry: { x: 0, y: 0 },
                        symbol: {
                          type: "CIMTextSymbol",
                          fontFamilyName: "Arial",
                          fontStyleName: "Bold",
                          height: 14,
                          horizontalAlignment: "Center",
                          offsetX: -70,
                          offsetY: 15,
                          symbol: {
                            type: "CIMPolygonSymbol",
                            symbolLayers: [{ type: "CIMSolidFill", color: [255, 255, 255, 255] }]
                          },
                          verticalAlignment: "Top"
                        },
                        textString: barData1.name
                      }
                    ],
                    scaleSymbolsProportionally: true,
                    respectFrame: true
                  }
                  // {
                  //   type: "CIMSolidFill",
                  //   color: [0, 163, 244, 255 * 0.6]
                  // }
                ]
              }
            }
          ]
        },
        // 基础多边形背景层
        {
          type: "CIMPictureMarker",
          enable: true,
          anchorPoint: {
            x: 0,
            y: 0
          },
          size: 80,
          scaleX: 1,
          tintColor: [255, 255, 255, 255],
          url: boxImg3
        }
      ]
    }
  }
});
return symbol;

}

相关推荐
柏林以东_2 小时前
线程安全的数据集合
java·开发语言·安全
fengfuyao9852 小时前
基于MATLAB的螺旋锥齿轮齿面接触分析(TCA)实现
开发语言·matlab
sweden_dove2 小时前
《python编程练习题》中的第二部分内容(19-36)和第三部分内容(37-54)
开发语言·python
谢尔登2 小时前
Vue3架构设计——调度系统
前端·javascript·vue.js
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于JAVA的宠物医院管理系统的设计为例,包含答辩的问题和答案
java·开发语言
小龙报2 小时前
【C语言进阶数据结构与算法】LeetCode27 && LeetCode88顺序表练习:1.移除元素 2.合并两个有序数组
c语言·开发语言·数据结构·c++·算法·链表·visual studio
skywalk81632 小时前
FreeBSD下安装rustup、cargo和uv
开发语言·python·rust·cargo
枫叶丹42 小时前
Oracle迁移实战:破解兼容性难题与高成本挑战
开发语言·数据库·oracle