ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从一条 SQL 到一张面积图:DBeaver 自定义图表实现路径

从一条 SQL 到一张面积图:DBeaver 自定义图表实现路径 从一条 SQL 到一张面积图DBeaver 自定义图表实现路径【免费下载链接】dbeaverFree universal database tool and SQL client项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver这篇笔记做的事就一件给 DBeaver 这个免费通用数据库工具加上自定义图表——两张原生 UI 里没有现成入口的面积图和雷达图。走的路线不是接 Web 组件而是直接在 SWT Canvas 上画并沿现有渲染链路把 SQL 结果集一步步映射到绘制调用。读者画像有基本 Java/SWT 经验、会用 Maven但没接触过 OSGi 插件体系。DBeaver 的图表数据到底从哪来答案不神秘从结果集来。DBeaver 的图表能力放在 ui.charts 插件里核心是 BaseChartComposite.java——它包了一层 JFreeChart 的 SWT 控件。JFreeChart 是纯 Java 图表库API 层就是 Java2D可以理解成渲染层是 Java2D 的图表库这也是为什么 DBeaver 的图最终都是画在画布上的。数据链路一共四跳每一跳都有现成代码可以对读SELECT ...结果集行 ↓ Dataset序列 × 类别 的二维数据 ↓ Chart 对象数据 绘制规则 ↓ SWT CanvasPaint 事件触发重绘真正值得看的入口是BaseChartComposite.setChart(JFreeChart)图表组件只负责拿一个已经装好数据的 JFreeChart 对象缩放、复制图片、另存为这些右键菜单都在基类里实现好了扩展时不用重写。一个真实的消费方是 DashboardRendererDatabaseChart.java仪表盘渲染器执行配置好的 SQL把返回的行映射成序列再交给 DashboardChartComposite.java 显示。自定义图表要做的就是在这条链路上换掉或补上数据→Chart这一段。想挂进图表到底该找哪个扩展点⚠️ 这里有个容易忽略的点翻一下 plugin.xml 会发现charts 插件只声明了org.eclipse.ui.themes这一个扩展点10 个图表主题色的colorDefinition网上一些文章里提到的图表提供器扩展点在仓库里并不存在。别指望挂扩展点真实的接入方式是自己的新插件 OSGi 依赖 charts 插件继承或组合BaseChartComposite再以普通视图/命令的形式注册出来。OSGi 插件机制 ≈ Java 生态里的 npm插件运行时安装、按声明的依赖组装所以依赖某个插件只写在 MANIFEST 的 Require-Bundle 里一行 pom 声明依赖 charts 插件即可。上面这张是独立版应用的启动画面对应 product 目录下的打包配置。想让新插件进正式发行包需要在 product 文件里补一行插件 id——属于打包配置本文不展开。所有改动都发生在你本地克隆的副本或自建的扩展模块里上游仓库保持只读git clone https://gitcode.com/GitHub_Trending/db/dbeaver不接 Browser怎么在 Canvas 上画面积图理由先说清楚DBeaver 是 SWT 桌面应用引一个嵌入式浏览器渲染 JS 图表内存和启动时间都会涨还多一层脚本注入的调试成本。而项目里本来就自带 SWTPaintCanvas.java——一个把 Java2D 绘制桥接到 SWT GC 的画布等于官方已经在走 Canvas 原生渲染这条路。自绘面积图就是在这条路上再往前一步拿 GC 直接画多边形。下面这段做三件事把数据坐标换算成像素坐标注意 SWT 的 y 轴朝下要翻转、在底部补两个点把折线闭合成多边形、先填充再描边。数据数组是调用方从结果集里提前转好的这里不再涉及 SQL。void drawArea(GC gc, Rectangle b, double[] xs, double[] ys, double yMax) { int n xs.length; if (n 2) return; int[] px new int[n 2], py new int[n 2]; for (int i 0; i n; i) { px[i] b.x (int) ((xs[i] - xs[0]) / (xs[n - 1] - xs[0]) * b.width); py[i] b.y b.height - (int) (ys[i] / yMax * b.height); } px[n] px[n - 1]; py[n] b.y b.height; // 落到基线 px[n 1] px[0]; py[n 1] b.y b.height; gc.fillPolygon(px, py); // 填充区域 gc.drawPolyline(px, 0, n); // 顶部折线 }雷达图是同一思路的旋转版把每个维度当成极坐标上的一个顶点按角度摊开后再闭合成多边形。下面这段只画数据多边形网格环和轴线省略逻辑完全相同。void drawRadar(GC gc, Point c, int r, double[] values, double maxValue) { int k values.length; int[] gx new int[k], gy new int[k]; for (int i 0; i k; i) { double a Math.PI * 2 * i / k - Math.PI / 2; // 从正上方起算 double len r * values[i] / maxValue; gx[i] (int) (c.x Math.cos(a) * len); gy[i] (int) (c.y Math.sin(a) * len); } gc.fillPolygon(gx, gy, new Color(parent.getDisplay(), 44, 165, 233, 110)); gc.drawPolyline(gx, gy); }GCGraphics Context就是手里的笔Canvas 是那张纸Paint 事件里画完必须gc.dispose()这个稍后在 Demo 里会体现。颜色怎么取才不会被深色主题打脸 图表的颜色不该硬编码。charts 插件通过主题扩展点声明了 10 个颜色 id取色统一走 IDE 主题注册表项目里 BaseChartDrawingSupplier.java 就是按这个序列给 JFreeChart 供色的。自绘代码里同样应该这么取而不是把 RGB 写死在类里。下面这段从主题注册表按 id 取色。注册表可以理解为一份全 IDE 共享的色卡切换主题后取到的就是新值// 取 charts 插件主题序列里的第 1 个颜色 ITheme theme PlatformUI.getWorkbench() .getThemeManager().getCurrentTheme(); Color c1 theme.getColorRegistry() .getColor(org.jkiss.dbeaver.ui.data.chart.color.1);如果跳过这步会怎样颜色写死成亮色用户切到深色主题后你的图表会刺眼地跳出界面而旁边原生图表的颜色却一切正常。最小可运行 Demo 怎么组装三步建一个依赖 charts 插件的新插件模块放一个承载画布的组合控件注册一条命令或视图把它挂出来。画布侧的骨架就是下面这段它负责把前文的两个绘制方法接进 SWT 事件循环Paint 和 Resize 两个监听缺一不可——前者忘了gc.dispose()会泄漏句柄后者忘了窗口拉伸后画面不会跟着重画。Canvas canvas new Canvas(parent, SWT.NONE); canvas.setBackgroundParent(); canvas.addListener(SWT.Paint, e - { GC gc e.gc; gc.setAntialias(SWT.JUST); Rectangle b canvas.getClientArea(); drawArea(gc, b, xs, ys, yMax); drawRadar(gc, new Point(b.width / 2, b.height / 2), b.height / 3, radar, 1.0); gc.dispose(); }); canvas.addListener(SWT.Resize, e - canvas.redraw());✅ 跑通后右键菜单、缩放手势这些能力直接从BaseChartComposite继承来不用自己再写一遍。常见报错速查现象多半的原因Paint 回调里画一片空白Canvas 还没 layoutgetBounds()是 0先确认父容器已布局颜色 id 取出来是 nullMANIFEST 里没依赖 charts 插件主题注册表里查不到该 id折线锯齿严重忘了gc.setAntialias(SWT.JUST)多序列时数据错位结果集转xs/ys时没按序列下标对齐第 N 列混进了第 M 列你可能会遇到行数一多Paint 里同步换算坐标就开始掉帧。解法不在绘制算法而在于把结果集→数据数组的换算挪出 Paint 回调换成数据就绪时一次性算好。下一步可以试试把drawArea里的线性比例尺换成对数刻度看长尾分布的数据是否还读得下去或者把整幅图预渲染成离屏Image量一下 10 倍数据量下的刷新差异。一个留给自己的问题当序列多到 20 条以上是继续加图例还是该拆成小多图small multiples了【免费下载链接】dbeaverFree universal database tool and SQL client项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表