here is a vue3 single file component (SFC) in composition mode written by typescript.
here is a snippet of simplified code.
There are 2 sets of [y, 0, x, 1] points data, plot lineData1 as smooth line, and plot lineData2 as symbols.
In template, the DOM tree is defined. In script, the 1st step is to import definitions, the 2nd step is to define the sample data, the 3rd step is to define the d3.scale for x and y, the 4th step is to plot the smooth line, the 5th step is to plot the symbols with transform.
I save the code as a .vue file which is a vue3 SFC, and integrate it into a vue3 project.
<template>
<div>
<svg xmlns="http://www.w3.org/2000/svg" ref="svgElement" class="center-plot-graph">
<g ref="lineElement" class="lineElements">
<path class="splineElement" />
<g class="symbolElement" />
</g>
</svg>
</div>
</template>
<script setup lang="ts">
import {
select,
Selection,
scaleLinear,
ScaleLinear,
symbol,
symbolCircle,
line,
Line,
curveLinear,
ValueFn,
BaseType,
} from "d3";
// import * as d3 from "d3"
import { ref, Ref, inject, onMounted } from "vue";
type Vector1d = Array<number>;
type Vector2d = Array<Vector1d>;
const svgElement: Ref<SVGSVGElement | null> = ref<SVGSVGElement | null>(null);
const lineElement: Ref<SVGGElement | null> = ref<SVGGElement | null>(null);
let lineData1: Vector2d = [
[10.5, 0, -26.5, 1],
[10.515418023668452, 0, -25.98615240945993, 0.9999999999999999],
[10.54673612522916, 0, -25.4242010779106, 0.9999999999999998],
[10.599262000092798, 0, -24.79828284532514, 0.9999999999999998],
[10.682246533999162, 0, -24.080779736377877, 0.9999999999999999],
[10.814880527142483, 0, -23.214463145842437, 0.9999999999999998],
[11.054647461420542, 0, -22.028119146822945, 0.9999999999999999],
[11.671811400028488, 0, -19.86283988201097, 0.9999999999999998],
[12.613086386434938, 0, -17.545566003251505, 0.9999999999999999],
[13.813926262485333, 0, -15.363942341711933, 1],
[15.263842352648265, 0, -13.35830776532418, 1.0000000000000004],
[16.93791350677736, 0, -11.540160490114632, 1.0000000000000007],
[18.800820600423645, 0, -9.900220288676735, 1.0000000000000004],
[20.817015127495804, 0, -8.428748556487237, 1.0000000000000004],
[22.9509485819025, 0, -7.116006689022895, 1.0000000000000002],
[25.16710035838422, 0, -5.9522535772986, 1],
[27.437849524060642, 0, -4.927039014178517, 0.9999999999999999],
[29.7542920863866, 0, -4.028232704145715, 0.9999999999999999],
[32.11023490194244, 0, -3.243461017781614, 0.9999999999999998],
[34.499484827308535, 0, -2.56035032566763, 0.9999999999999997],
[36.91584871906518, 0, -1.9665269983851892, 0.9999999999999996],
[39.35328336132695, 0, -1.4504051633262336, 0.9999999999999997],
[41.8071311282343, 0, -1.0076791848683684, 0.9999999999999999],
[44.273483525476955, 0, -0.6379795521514762, 1],
[46.499497521985354, 0, -0.3675404908536285, 0.9999999999999998],
[47.70003443876498, 0, -0.24619654497075863, 1],
[48.571814387462624, 0, -0.16874721429387524, 0.9999999999999999],
[49.292111379398605, 0, -0.11149361650523448, 1],
[49.91998747855483, 0, -0.06654412557289584, 1],
[50.483859148305946, 0, -0.03010369508701564, 1.0000000000000002],
[51, 0, 0, 1],
];
let lineData2: Vector2d = [
[10.5, 0, -26.5, 1],
[10.573820291076342, 0, -22.314239546778368, 0.9999999999999995],
[13.359019071367536, 0, -13.451591871333579, 1.0000000000000007],
[24.504724058628779, 0, -5.452588866468975, 1.0000000000000003],
[37.471579656269877, 0, -1.4571818281579628, 0.9999999999999992],
[46.497084577993259, 0, -0.24908378543712748, 1.0000000000000003],
[51, 0, 0, 1],
];
let xScale: ScaleLinear<number, number, never> = scaleLinear()
.domain([-26, 0])
.range([10, 920]);
let yScale: ScaleLinear<number, number, never> = scaleLinear()
.domain([10, 52])
.range([10, 950]);
// let rootNode: Selection<SVGSVGElement, Vector2d, null, undefined> = select<SVGSVGElement, Vector2d>(svgElement.value as SVGSVGElement)
let splineElement: Selection<SVGPathElement, Vector2d, null, undefined> =
select(lineElement.value as SVGGElement)
.select<SVGPathElement>(".splineElement")
.datum<Vector2d>(lineData1)
.attr(
"d",
(
d: Vector2d,
i: number,
a: Array<SVGPathElement> | ArrayLike<SVGPathElement>
) => {
return line<Vector1d>()
.x((di: Vector1d, ii: number, ao: Vector2d) => xScale(di[2]))
.y((di: Vector1d, ii: number, ao: Vector2d) => yScale(di[0]))
.curve(curveLinear)(d);
}
)
.style("stroke", "black")
.style("fill", "none");
let SymbolTransform: ValueFn<SVGPathElement | BaseType, Vector1d, string> =
function (
d: Vector1d,
i: number,
a: Array<BaseType | SVGPathElement> | ArrayLike<BaseType | SVGPathElement>
): string {
const x = xScale(d[2]);
const y = yScale(d[0]);
return `translate(${x},${y})`;
};
let symbolNode: Selection<SVGPathElement, Vector1d, SVGGElement, Vector2d> =
select(lineElement.value as SVGGElement)
.select<SVGPathElement>(".symbolElement")
.selectAll<SVGPathElement, Vector1d>("path")
.data<Vector1d>(lineData2)
.join("path")
.attr("d", symbol<Vector1d>(symbolCircle, 20))
.style("stroke", "red")
.style("fill", "none")
.attr("transform", SymbolTransform);
</script>
<style scoped lang="less">
.center-plot-graph {
position: absolute;
width: 936px;
height: 960px;
}
</style>
the dependencies are:
"dependencies": {
"d3": "^7.9.0",
"lodash-es": "^4.17.21",
"vue": "^3.4.21"
},
"devDependencies": {
"@types/d3": "^7.4.3",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.12.7",
"@vitejs/plugin-vue": "^5.0.4",
"eslint": "^9.1.1",
"eslint-plugin-vue": "^9.25.0",
"less": "^4.2.0",
"typescript": "^5.4.5",
"vite": "^5.2.10",
"vite-plugin-top-level-await": "^1.4.1",
"vitest": "^1.5.2",
"vue-tsc": "^2.0.6"
}
it’s very easy to reproduce the bug:
- create a new project
npm init vite@latest
- copy the dependencies to package.json, then run
npm install
- create a new .vue file, copy the code into the file and save
- import and insert the .vue file into app.vue file
- compile and test
npm run dev
the command would tell you an address, access that address by your browser.
Then you will see: the plot doesn’t appear. Click F12 in the browser and check the elements, you will find there is nothing in or
I guess the problem is in the line generator and symbol generator, maybe type definition is not correct.
I tried to debug line by line, but d3 doesn’t allow me to check what happens inside attr(“d”, (d, i, a)=>{})
can anybody help me?