@esic-lab/data-core-ui 0.0.72 → 0.0.74

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -645,9 +645,10 @@ type Props = {
645
645
  yLabel?: string;
646
646
  xLabel?: string;
647
647
  modeLabel?: "line" | "45";
648
+ layout?: "vertical" | "horizontal";
648
649
  colorPalette?: string[];
649
650
  };
650
- declare const BarChart: ({ data, height, margin, yLabel, xLabel, modeLabel, colorPalette, }: Props) => react_jsx_runtime.JSX.Element;
651
+ declare const BarChart: ({ data, height, margin, yLabel, xLabel, modeLabel, colorPalette, layout, }: Props) => react_jsx_runtime.JSX.Element;
651
652
 
652
653
  interface PieChartProps {
653
654
  title?: string;
package/dist/index.d.ts CHANGED
@@ -645,9 +645,10 @@ type Props = {
645
645
  yLabel?: string;
646
646
  xLabel?: string;
647
647
  modeLabel?: "line" | "45";
648
+ layout?: "vertical" | "horizontal";
648
649
  colorPalette?: string[];
649
650
  };
650
- declare const BarChart: ({ data, height, margin, yLabel, xLabel, modeLabel, colorPalette, }: Props) => react_jsx_runtime.JSX.Element;
651
+ declare const BarChart: ({ data, height, margin, yLabel, xLabel, modeLabel, colorPalette, layout, }: Props) => react_jsx_runtime.JSX.Element;
651
652
 
652
653
  interface PieChartProps {
653
654
  title?: string;
package/dist/index.js CHANGED
@@ -4702,7 +4702,8 @@ var BarChart = ({
4702
4702
  yLabel,
4703
4703
  xLabel,
4704
4704
  modeLabel,
4705
- colorPalette = defaultColorPalette
4705
+ colorPalette = defaultColorPalette,
4706
+ layout
4706
4707
  }) => {
4707
4708
  const svgRef = (0, import_react21.useRef)(null);
4708
4709
  const gRef = (0, import_react21.useRef)(null);
@@ -4710,6 +4711,24 @@ var BarChart = ({
4710
4711
  const yAxisRef = (0, import_react21.useRef)(null);
4711
4712
  const containerRef = (0, import_react21.useRef)(null);
4712
4713
  const widthRef = (0, import_react21.useRef)(0);
4714
+ function ellipsizeTickText(selection, maxWidth) {
4715
+ selection.each(function() {
4716
+ const textEl = this;
4717
+ const full = (textEl.textContent ?? "").trim();
4718
+ textEl.textContent = full;
4719
+ if (textEl.getComputedTextLength() <= maxWidth) return;
4720
+ let lo = 0;
4721
+ let hi = full.length;
4722
+ const suffix = "\u2026";
4723
+ while (lo < hi) {
4724
+ const mid = Math.ceil((lo + hi) / 2);
4725
+ textEl.textContent = full.slice(0, mid) + suffix;
4726
+ if (textEl.getComputedTextLength() <= maxWidth) lo = mid;
4727
+ else hi = mid - 1;
4728
+ }
4729
+ textEl.textContent = full.slice(0, lo) + suffix;
4730
+ });
4731
+ }
4713
4732
  (0, import_react21.useEffect)(() => {
4714
4733
  if (!containerRef.current) return;
4715
4734
  const ro = new ResizeObserver((entries) => {
@@ -4723,7 +4742,10 @@ var BarChart = ({
4723
4742
  const xDomain = (0, import_react21.useMemo)(() => data.map((d) => d.x), [data]);
4724
4743
  const yDomain = (0, import_react21.useMemo)(() => {
4725
4744
  const maxY = d3.max(data, (d) => d.y);
4726
- return [0, (maxY !== void 0 ? maxY : 0) + (maxY !== void 0 ? maxY : 0) * 0.1];
4745
+ return [
4746
+ 0,
4747
+ (maxY !== void 0 ? maxY : 0) + (maxY !== void 0 ? maxY : 0) * 0.1
4748
+ ];
4727
4749
  }, [data]);
4728
4750
  const render = () => {
4729
4751
  const svg = d3.select(svgRef.current);
@@ -4734,80 +4756,128 @@ var BarChart = ({
4734
4756
  const innerW = width - margin.left - margin.right;
4735
4757
  const innerH = height - margin.top - margin.bottom;
4736
4758
  svg.attr("width", width).attr("height", height);
4737
- const x = d3.scaleBand().domain(xDomain).range([0, innerW]).padding(0.2);
4738
- const y = d3.scaleLinear().domain(yDomain).nice().range([innerH, 0]);
4739
- const xAxis = d3.axisBottom(x).tickSizeOuter(0).tickSize(0).tickFormat((d) => d);
4740
- const yAxis = d3.axisLeft(y).ticks(5).tickFormat(d3.format("~s"));
4741
- const grid = d3.axisLeft(y).ticks(5).tickSize(-innerW).scale(y);
4742
- const gridG = svg.append("g").attr("class", "grid").attr("transform", `translate(${margin.left}, ${margin.top})`).call(grid).style("font-size", "14px");
4743
- gridG.selectAll("path").remove();
4744
- const barsG = svg.append("g").attr("class", "bars");
4745
- svg.selectAll(".grid").data([0]).join("g").attr("class", "grid").attr("transform", `translate(${margin.left}, ${margin.top})`).call(grid).style("font-size", "14px").call((g2) => g2.selectAll("path").remove()).call(
4746
- (g2) => g2.selectAll("line").style("stroke", "gray").style("stroke-opacity", 0.1)
4747
- // keep faint
4748
- );
4749
- svg.select(".grid").lower();
4750
- xAxisG.attr("transform", `translate(${margin.left},${height - margin.bottom})`).call(xAxis).selectAll("text").style("text-anchor", "middle").attr("dy", "1.5em").attr("fill", "currentColor").style("font-size", "14px").style("font-family", "Arial, sans-serif");
4751
- const labels = xAxisG.selectAll("text").attr("fill", "currentColor").style("font-size", "14px").style("font-family", "Arial, sans-serif");
4752
- if (modeLabel === "45") {
4753
- labels.attr("transform", "rotate(-45)").style("overflow", "visible").style("text-anchor", "end").attr("dx", "-0.8em").attr("dy", "0.15em");
4754
- } else if (modeLabel === "line") {
4755
- labels.attr("transform", "rotate(0)").style("text-anchor", "middle").attr("dx", "0").attr("dy", "1.5em");
4759
+ const isHorizontal = layout === "horizontal";
4760
+ g.attr("transform", `translate(${margin.left},${margin.top})`);
4761
+ const xBand = d3.scaleBand().domain(xDomain).padding(0.2);
4762
+ const yBand = d3.scaleBand().domain(xDomain).padding(0.2);
4763
+ const xLin = d3.scaleLinear().domain(yDomain).nice();
4764
+ const yLin = d3.scaleLinear().domain(yDomain).nice();
4765
+ if (!isHorizontal) {
4766
+ xBand.range([0, innerW]);
4767
+ yLin.range([innerH, 0]);
4756
4768
  } else {
4757
- labels.style("text-anchor", "middle").attr("dy", "1.5em");
4769
+ yBand.range([0, innerH]);
4770
+ xLin.range([0, innerW]);
4758
4771
  }
4772
+ const xAxis = !isHorizontal ? d3.axisBottom(xBand).tickSizeOuter(0).tickSize(0) : d3.axisBottom(xLin).ticks(5).tickFormat(d3.format("~s"));
4773
+ const yAxis = !isHorizontal ? d3.axisLeft(yLin).ticks(5).tickFormat(d3.format("~s")) : d3.axisLeft(yBand).tickSizeOuter(0).tickSize(0);
4774
+ xAxisG.attr("transform", `translate(${margin.left},${margin.top + innerH})`).call(xAxis);
4775
+ yAxisG.attr("transform", `translate(${margin.left},${margin.top})`).call(yAxis);
4776
+ const xTickTexts = xAxisG.selectAll("text").attr("fill", "currentColor").style("font-size", "14px").style("font-family", "Kanit, sans-serif");
4777
+ if (!isHorizontal) {
4778
+ if (modeLabel === "45") {
4779
+ xTickTexts.attr("transform", "rotate(-45)").style("text-anchor", "end").attr("dx", "-0.8em").attr("dy", "0.15em");
4780
+ } else {
4781
+ xTickTexts.attr("transform", "rotate(0)").style("text-anchor", "middle").attr("dx", "0").attr("dy", "1.5em");
4782
+ }
4783
+ } else {
4784
+ xTickTexts.attr("transform", "rotate(0)").style("text-anchor", "middle");
4785
+ }
4786
+ const maxLabelWidth = isHorizontal ? 120 : Math.max(40, (xBand.bandwidth?.() ?? 0) - 8);
4787
+ ellipsizeTickText(xTickTexts, maxLabelWidth);
4788
+ const grid = !isHorizontal ? d3.axisLeft(yLin).ticks(5).tickSize(-innerW).tickFormat(() => "") : d3.axisBottom(xLin).ticks(5).tickSize(-innerH).tickFormat(() => "");
4789
+ const gridG = svg.selectAll("g.grid").data([null]).join("g").attr("class", "grid").attr(
4790
+ "transform",
4791
+ !isHorizontal ? `translate(${margin.left},${margin.top})` : `translate(${margin.left},${margin.top + innerH})`
4792
+ ).call(grid);
4793
+ gridG.selectAll("path").remove();
4794
+ gridG.selectAll("line").style("stroke", "gray").style("stroke-opacity", 0.1);
4795
+ svg.select("g.grid").lower();
4759
4796
  yAxisG.selectAll(".y-axis-label").data(yLabel ? [yLabel] : []).join(
4760
- (enter) => enter.append("text").attr("class", "y-axis-label").attr("fill", "currentColor").attr("x", -margin.left + 8).attr("y", -margin.top + 20).attr("text-anchor", "start").style("font-size", "14px").style("font-family", "Arial").text((d) => d),
4797
+ (enter) => enter.append("text").attr("class", "y-axis-label").attr("fill", "currentColor").attr(
4798
+ "x",
4799
+ !isHorizontal ? 0 : innerWidth - margin.right - margin.left + 20
4800
+ ).attr(
4801
+ "y",
4802
+ !isHorizontal ? -10 : innerHeight / 2 + margin.bottom + margin.top + 20
4803
+ ).attr("text-anchor", "middle").style("font-size", "18px").style("font-family", "Kanit, sans-serif").text((d) => d),
4761
4804
  (update) => update.text((d) => d)
4762
4805
  );
4763
- xAxisG.selectAll(".x-axis-label").data(xLabel ? [xLabel] : []).join(
4764
- (enter) => enter.append("text").attr("class", "x-axis-label").attr("fill", "currentColor").attr("x", width).attr("y", height - margin.bottom).attr("text-anchor", "middle").style("font-size", "14px").style("font-family", "Arial").text((d) => d),
4765
- (update) => update.text((d) => d).attr("x", width)
4806
+ yAxisG.selectAll(".x-axis-label").data(xLabel ? [xLabel] : []).join(
4807
+ (enter) => enter.append("text").attr("class", "x-axis-label").attr("fill", "currentColor").attr(
4808
+ "x",
4809
+ !isHorizontal ? innerWidth - margin.right - margin.left + 20 : 0
4810
+ ).attr(
4811
+ "y",
4812
+ !isHorizontal ? -10 : -(innerHeight / 2) - margin.bottom - margin.top - 20
4813
+ ).attr("text-anchor", "middle").style("font-size", "18px").style("font-family", "Kanit, sans-serif").text((d) => d),
4814
+ (update) => update.text((d) => d).attr(
4815
+ "x",
4816
+ !isHorizontal ? innerWidth - margin.right - margin.left : 0
4817
+ ).attr(
4818
+ "y",
4819
+ !isHorizontal ? innerHeight / 2 - margin.top : -(innerHeight / 2) - margin.bottom - margin.top - 20
4820
+ )
4766
4821
  );
4767
- const t = d3.transition().duration(400);
4822
+ const t = svg.transition().duration(400);
4768
4823
  const bars = g.selectAll("rect.bar").data(data, (d) => d.x);
4769
4824
  bars.join(
4770
- // (enter) =>
4771
- // enter
4772
- // .append("rect")
4773
- // .attr("class", "bar")
4774
- // .attr("x", (d) => margin.left)
4775
- // .attr("width", x.bandwidth())
4776
- // .attr("y", () => margin.top + y(0))
4777
- // .attr("height", () => innerH - y(0))
4778
- // .attr("rx", 5) // rounded corners
4779
- // .attr("ry", 5) // rounded corners
4780
- // .style("fill", (d, i) => colorPalette[i % colorPalette.length]) // Apply color based on index
4781
- // .append("title")
4782
- // .text((d) => `${d.x}: ${d.y}`)
4783
- // .merge(bars) // merge the existing bars after joining
4784
- // .attr("width", x.bandwidth())
4785
- // .attr("y", (d) => y(d.y))
4786
- // .attr("height", (d) => innerH - y(d.y))
4787
- // .call((enter) => enter.raise()), // Bring the new bars to the front
4788
4825
  (enter) => {
4789
- const rects = enter.append("rect").attr("class", "bar").attr("x", (d) => margin.left).attr("width", x.bandwidth()).attr("y", () => margin.top + y(0)).attr("height", () => innerH - y(0)).attr("rx", 5).attr("ry", 5).style("fill", (d, i) => colorPalette[i % colorPalette.length]);
4790
- rects.append("title").text((d) => `${d.x}: ${d.y}`);
4791
- return rects.merge(bars).attr("width", x.bandwidth()).attr("y", (d) => y(d.y)).attr("height", (d) => innerH - y(d.y)).call((g2) => g2.raise());
4826
+ const e = enter.append("rect").attr("class", "bar").attr("rx", 5).attr("ry", 5).style("fill", (d, i) => colorPalette[i % colorPalette.length]);
4827
+ if (!isHorizontal) {
4828
+ e.attr("x", (d) => xBand(d.x) ?? 0).attr("width", xBand.bandwidth()).attr("y", yLin(0)).attr("height", innerH - yLin(0));
4829
+ } else {
4830
+ e.attr("x", 0).attr("width", 0).attr("y", (d) => yBand(d.x) ?? 0).attr("height", yBand.bandwidth());
4831
+ }
4832
+ e.append("title").text((d) => `${d.x}: ${d.y}`);
4833
+ return e.transition(t).attr("x", (d) => !isHorizontal ? xBand(d.x) ?? 0 : 0).attr("y", (d) => !isHorizontal ? yLin(d.y) : yBand(d.x) ?? 0).attr("width", (d) => !isHorizontal ? xBand.bandwidth() : xLin(d.y)).attr(
4834
+ "height",
4835
+ (d) => !isHorizontal ? innerH - yLin(d.y) : yBand.bandwidth()
4836
+ );
4792
4837
  },
4793
- (update) => update.call((update2) => update2.raise()).transition(t).attr("x", (d) => x(d.x) ?? 0).attr("width", x.bandwidth()).attr("y", (d) => y(d.y)).attr("height", (d) => innerH - y(d.y)).style("fill", (d, i) => colorPalette[i % colorPalette.length]),
4794
- // Update color on update
4795
- (exit) => exit.transition(t).attr("y", margin.top + y(0)).attr("height", innerH - y(0)).remove()
4838
+ (update) => update.call((u) => u.raise()).transition(t).attr("x", (d) => !isHorizontal ? xBand(d.x) ?? 0 : 0).attr("y", (d) => !isHorizontal ? yLin(d.y) : yBand(d.x) ?? 0).attr("width", (d) => !isHorizontal ? xBand.bandwidth() : xLin(d.y)).attr(
4839
+ "height",
4840
+ (d) => !isHorizontal ? innerH - yLin(d.y) : yBand.bandwidth()
4841
+ ).style("fill", (d, i) => colorPalette[i % colorPalette.length]),
4842
+ (exit) => exit.transition(t).attr("width", !isHorizontal ? xBand.bandwidth() : 0).attr("height", !isHorizontal ? innerH - yLin(0) : yBand.bandwidth()).remove()
4796
4843
  );
4797
- g.selectAll("text.bar-label").data(data).join(
4798
- (enter) => enter.append("text").attr("class", "bar-label").attr("x", (d) => (x(d.x) ?? 0) + x.bandwidth() / 2).attr("y", (d) => y(d.y) - 6).attr("text-anchor", "middle").style("font-size", "50px").style("font-weight", "bold").style("font-family", "Arial, sans-serif").style("fill", (d, i) => colorPalette[i % colorPalette.length]).style("overflow", "visible").text((d) => d.y),
4799
- (update) => update.transition(t).attr("x", (d) => (x(d.x) ?? 0) + x.bandwidth() / 2).attr("y", (d) => y(d.y) - 6).text((d) => d.y),
4844
+ const labels = g.selectAll("text.bar-label").data(data, (d) => d.x);
4845
+ labels.join(
4846
+ (enter) => enter.append("text").attr("class", "bar-label").style("font-weight", "bold").style("font-family", "Kanit, sans-serif").style("font-size", "80px").style("fill", (d, i) => colorPalette[i % colorPalette.length]).attr("text-anchor", !isHorizontal ? "middle" : "start").attr(
4847
+ "x",
4848
+ (d) => !isHorizontal ? (xBand(d.x) ?? 0) + xBand.bandwidth() / 2 : xLin(d.y) + 6
4849
+ ).attr(
4850
+ "y",
4851
+ (d) => !isHorizontal ? yLin(d.y) - 6 : (yBand(d.x) ?? 0) + yBand.bandwidth() / 2 + 4
4852
+ ).text((d) => d.y),
4853
+ (update) => update.transition(t).attr("text-anchor", !isHorizontal ? "middle" : "start").attr(
4854
+ "x",
4855
+ (d) => !isHorizontal ? (xBand(d.x) ?? 0) + xBand.bandwidth() / 2 : xLin(d.y) + 6
4856
+ ).attr(
4857
+ "y",
4858
+ (d) => !isHorizontal ? yLin(d.y) - 6 : (yBand(d.x) ?? 0) + yBand.bandwidth() / 2 + 24
4859
+ ).text((d) => d.y),
4800
4860
  (exit) => exit.remove()
4801
4861
  );
4802
4862
  };
4803
4863
  (0, import_react21.useEffect)(() => {
4804
4864
  render();
4805
4865
  }, [data, height, margin, modeLabel, xDomain.toString(), yDomain.toString()]);
4806
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { ref: containerRef, style: { width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("svg", { ref: svgRef, role: "img", "aria-label": "Bar chart", style: { display: "block", width: "100%", height }, children: [
4807
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { ref: gRef, transform: `translate(${margin.left},${margin.top})` }),
4808
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { ref: xAxisRef }),
4809
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { ref: yAxisRef })
4810
- ] }) });
4866
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { ref: containerRef, style: { width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4867
+ "svg",
4868
+ {
4869
+ ref: svgRef,
4870
+ role: "img",
4871
+ "aria-label": "Bar chart",
4872
+ style: { display: "block", width: "100%", height },
4873
+ children: [
4874
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("title", { children: "Bar chart" }),
4875
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { ref: gRef, transform: `translate(${margin.left},${margin.top})` }),
4876
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { ref: xAxisRef }),
4877
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { ref: yAxisRef })
4878
+ ]
4879
+ }
4880
+ ) });
4811
4881
  };
4812
4882
 
4813
4883
  // src/Chart/PieChart/PieChart.tsx
package/dist/index.mjs CHANGED
@@ -4636,7 +4636,8 @@ var BarChart = ({
4636
4636
  yLabel,
4637
4637
  xLabel,
4638
4638
  modeLabel,
4639
- colorPalette = defaultColorPalette
4639
+ colorPalette = defaultColorPalette,
4640
+ layout
4640
4641
  }) => {
4641
4642
  const svgRef = useRef8(null);
4642
4643
  const gRef = useRef8(null);
@@ -4644,6 +4645,24 @@ var BarChart = ({
4644
4645
  const yAxisRef = useRef8(null);
4645
4646
  const containerRef = useRef8(null);
4646
4647
  const widthRef = useRef8(0);
4648
+ function ellipsizeTickText(selection, maxWidth) {
4649
+ selection.each(function() {
4650
+ const textEl = this;
4651
+ const full = (textEl.textContent ?? "").trim();
4652
+ textEl.textContent = full;
4653
+ if (textEl.getComputedTextLength() <= maxWidth) return;
4654
+ let lo = 0;
4655
+ let hi = full.length;
4656
+ const suffix = "\u2026";
4657
+ while (lo < hi) {
4658
+ const mid = Math.ceil((lo + hi) / 2);
4659
+ textEl.textContent = full.slice(0, mid) + suffix;
4660
+ if (textEl.getComputedTextLength() <= maxWidth) lo = mid;
4661
+ else hi = mid - 1;
4662
+ }
4663
+ textEl.textContent = full.slice(0, lo) + suffix;
4664
+ });
4665
+ }
4647
4666
  useEffect9(() => {
4648
4667
  if (!containerRef.current) return;
4649
4668
  const ro = new ResizeObserver((entries) => {
@@ -4657,7 +4676,10 @@ var BarChart = ({
4657
4676
  const xDomain = useMemo2(() => data.map((d) => d.x), [data]);
4658
4677
  const yDomain = useMemo2(() => {
4659
4678
  const maxY = d3.max(data, (d) => d.y);
4660
- return [0, (maxY !== void 0 ? maxY : 0) + (maxY !== void 0 ? maxY : 0) * 0.1];
4679
+ return [
4680
+ 0,
4681
+ (maxY !== void 0 ? maxY : 0) + (maxY !== void 0 ? maxY : 0) * 0.1
4682
+ ];
4661
4683
  }, [data]);
4662
4684
  const render = () => {
4663
4685
  const svg = d3.select(svgRef.current);
@@ -4668,80 +4690,128 @@ var BarChart = ({
4668
4690
  const innerW = width - margin.left - margin.right;
4669
4691
  const innerH = height - margin.top - margin.bottom;
4670
4692
  svg.attr("width", width).attr("height", height);
4671
- const x = d3.scaleBand().domain(xDomain).range([0, innerW]).padding(0.2);
4672
- const y = d3.scaleLinear().domain(yDomain).nice().range([innerH, 0]);
4673
- const xAxis = d3.axisBottom(x).tickSizeOuter(0).tickSize(0).tickFormat((d) => d);
4674
- const yAxis = d3.axisLeft(y).ticks(5).tickFormat(d3.format("~s"));
4675
- const grid = d3.axisLeft(y).ticks(5).tickSize(-innerW).scale(y);
4676
- const gridG = svg.append("g").attr("class", "grid").attr("transform", `translate(${margin.left}, ${margin.top})`).call(grid).style("font-size", "14px");
4677
- gridG.selectAll("path").remove();
4678
- const barsG = svg.append("g").attr("class", "bars");
4679
- svg.selectAll(".grid").data([0]).join("g").attr("class", "grid").attr("transform", `translate(${margin.left}, ${margin.top})`).call(grid).style("font-size", "14px").call((g2) => g2.selectAll("path").remove()).call(
4680
- (g2) => g2.selectAll("line").style("stroke", "gray").style("stroke-opacity", 0.1)
4681
- // keep faint
4682
- );
4683
- svg.select(".grid").lower();
4684
- xAxisG.attr("transform", `translate(${margin.left},${height - margin.bottom})`).call(xAxis).selectAll("text").style("text-anchor", "middle").attr("dy", "1.5em").attr("fill", "currentColor").style("font-size", "14px").style("font-family", "Arial, sans-serif");
4685
- const labels = xAxisG.selectAll("text").attr("fill", "currentColor").style("font-size", "14px").style("font-family", "Arial, sans-serif");
4686
- if (modeLabel === "45") {
4687
- labels.attr("transform", "rotate(-45)").style("overflow", "visible").style("text-anchor", "end").attr("dx", "-0.8em").attr("dy", "0.15em");
4688
- } else if (modeLabel === "line") {
4689
- labels.attr("transform", "rotate(0)").style("text-anchor", "middle").attr("dx", "0").attr("dy", "1.5em");
4693
+ const isHorizontal = layout === "horizontal";
4694
+ g.attr("transform", `translate(${margin.left},${margin.top})`);
4695
+ const xBand = d3.scaleBand().domain(xDomain).padding(0.2);
4696
+ const yBand = d3.scaleBand().domain(xDomain).padding(0.2);
4697
+ const xLin = d3.scaleLinear().domain(yDomain).nice();
4698
+ const yLin = d3.scaleLinear().domain(yDomain).nice();
4699
+ if (!isHorizontal) {
4700
+ xBand.range([0, innerW]);
4701
+ yLin.range([innerH, 0]);
4690
4702
  } else {
4691
- labels.style("text-anchor", "middle").attr("dy", "1.5em");
4703
+ yBand.range([0, innerH]);
4704
+ xLin.range([0, innerW]);
4692
4705
  }
4706
+ const xAxis = !isHorizontal ? d3.axisBottom(xBand).tickSizeOuter(0).tickSize(0) : d3.axisBottom(xLin).ticks(5).tickFormat(d3.format("~s"));
4707
+ const yAxis = !isHorizontal ? d3.axisLeft(yLin).ticks(5).tickFormat(d3.format("~s")) : d3.axisLeft(yBand).tickSizeOuter(0).tickSize(0);
4708
+ xAxisG.attr("transform", `translate(${margin.left},${margin.top + innerH})`).call(xAxis);
4709
+ yAxisG.attr("transform", `translate(${margin.left},${margin.top})`).call(yAxis);
4710
+ const xTickTexts = xAxisG.selectAll("text").attr("fill", "currentColor").style("font-size", "14px").style("font-family", "Kanit, sans-serif");
4711
+ if (!isHorizontal) {
4712
+ if (modeLabel === "45") {
4713
+ xTickTexts.attr("transform", "rotate(-45)").style("text-anchor", "end").attr("dx", "-0.8em").attr("dy", "0.15em");
4714
+ } else {
4715
+ xTickTexts.attr("transform", "rotate(0)").style("text-anchor", "middle").attr("dx", "0").attr("dy", "1.5em");
4716
+ }
4717
+ } else {
4718
+ xTickTexts.attr("transform", "rotate(0)").style("text-anchor", "middle");
4719
+ }
4720
+ const maxLabelWidth = isHorizontal ? 120 : Math.max(40, (xBand.bandwidth?.() ?? 0) - 8);
4721
+ ellipsizeTickText(xTickTexts, maxLabelWidth);
4722
+ const grid = !isHorizontal ? d3.axisLeft(yLin).ticks(5).tickSize(-innerW).tickFormat(() => "") : d3.axisBottom(xLin).ticks(5).tickSize(-innerH).tickFormat(() => "");
4723
+ const gridG = svg.selectAll("g.grid").data([null]).join("g").attr("class", "grid").attr(
4724
+ "transform",
4725
+ !isHorizontal ? `translate(${margin.left},${margin.top})` : `translate(${margin.left},${margin.top + innerH})`
4726
+ ).call(grid);
4727
+ gridG.selectAll("path").remove();
4728
+ gridG.selectAll("line").style("stroke", "gray").style("stroke-opacity", 0.1);
4729
+ svg.select("g.grid").lower();
4693
4730
  yAxisG.selectAll(".y-axis-label").data(yLabel ? [yLabel] : []).join(
4694
- (enter) => enter.append("text").attr("class", "y-axis-label").attr("fill", "currentColor").attr("x", -margin.left + 8).attr("y", -margin.top + 20).attr("text-anchor", "start").style("font-size", "14px").style("font-family", "Arial").text((d) => d),
4731
+ (enter) => enter.append("text").attr("class", "y-axis-label").attr("fill", "currentColor").attr(
4732
+ "x",
4733
+ !isHorizontal ? 0 : innerWidth - margin.right - margin.left + 20
4734
+ ).attr(
4735
+ "y",
4736
+ !isHorizontal ? -10 : innerHeight / 2 + margin.bottom + margin.top + 20
4737
+ ).attr("text-anchor", "middle").style("font-size", "18px").style("font-family", "Kanit, sans-serif").text((d) => d),
4695
4738
  (update) => update.text((d) => d)
4696
4739
  );
4697
- xAxisG.selectAll(".x-axis-label").data(xLabel ? [xLabel] : []).join(
4698
- (enter) => enter.append("text").attr("class", "x-axis-label").attr("fill", "currentColor").attr("x", width).attr("y", height - margin.bottom).attr("text-anchor", "middle").style("font-size", "14px").style("font-family", "Arial").text((d) => d),
4699
- (update) => update.text((d) => d).attr("x", width)
4740
+ yAxisG.selectAll(".x-axis-label").data(xLabel ? [xLabel] : []).join(
4741
+ (enter) => enter.append("text").attr("class", "x-axis-label").attr("fill", "currentColor").attr(
4742
+ "x",
4743
+ !isHorizontal ? innerWidth - margin.right - margin.left + 20 : 0
4744
+ ).attr(
4745
+ "y",
4746
+ !isHorizontal ? -10 : -(innerHeight / 2) - margin.bottom - margin.top - 20
4747
+ ).attr("text-anchor", "middle").style("font-size", "18px").style("font-family", "Kanit, sans-serif").text((d) => d),
4748
+ (update) => update.text((d) => d).attr(
4749
+ "x",
4750
+ !isHorizontal ? innerWidth - margin.right - margin.left : 0
4751
+ ).attr(
4752
+ "y",
4753
+ !isHorizontal ? innerHeight / 2 - margin.top : -(innerHeight / 2) - margin.bottom - margin.top - 20
4754
+ )
4700
4755
  );
4701
- const t = d3.transition().duration(400);
4756
+ const t = svg.transition().duration(400);
4702
4757
  const bars = g.selectAll("rect.bar").data(data, (d) => d.x);
4703
4758
  bars.join(
4704
- // (enter) =>
4705
- // enter
4706
- // .append("rect")
4707
- // .attr("class", "bar")
4708
- // .attr("x", (d) => margin.left)
4709
- // .attr("width", x.bandwidth())
4710
- // .attr("y", () => margin.top + y(0))
4711
- // .attr("height", () => innerH - y(0))
4712
- // .attr("rx", 5) // rounded corners
4713
- // .attr("ry", 5) // rounded corners
4714
- // .style("fill", (d, i) => colorPalette[i % colorPalette.length]) // Apply color based on index
4715
- // .append("title")
4716
- // .text((d) => `${d.x}: ${d.y}`)
4717
- // .merge(bars) // merge the existing bars after joining
4718
- // .attr("width", x.bandwidth())
4719
- // .attr("y", (d) => y(d.y))
4720
- // .attr("height", (d) => innerH - y(d.y))
4721
- // .call((enter) => enter.raise()), // Bring the new bars to the front
4722
4759
  (enter) => {
4723
- const rects = enter.append("rect").attr("class", "bar").attr("x", (d) => margin.left).attr("width", x.bandwidth()).attr("y", () => margin.top + y(0)).attr("height", () => innerH - y(0)).attr("rx", 5).attr("ry", 5).style("fill", (d, i) => colorPalette[i % colorPalette.length]);
4724
- rects.append("title").text((d) => `${d.x}: ${d.y}`);
4725
- return rects.merge(bars).attr("width", x.bandwidth()).attr("y", (d) => y(d.y)).attr("height", (d) => innerH - y(d.y)).call((g2) => g2.raise());
4760
+ const e = enter.append("rect").attr("class", "bar").attr("rx", 5).attr("ry", 5).style("fill", (d, i) => colorPalette[i % colorPalette.length]);
4761
+ if (!isHorizontal) {
4762
+ e.attr("x", (d) => xBand(d.x) ?? 0).attr("width", xBand.bandwidth()).attr("y", yLin(0)).attr("height", innerH - yLin(0));
4763
+ } else {
4764
+ e.attr("x", 0).attr("width", 0).attr("y", (d) => yBand(d.x) ?? 0).attr("height", yBand.bandwidth());
4765
+ }
4766
+ e.append("title").text((d) => `${d.x}: ${d.y}`);
4767
+ return e.transition(t).attr("x", (d) => !isHorizontal ? xBand(d.x) ?? 0 : 0).attr("y", (d) => !isHorizontal ? yLin(d.y) : yBand(d.x) ?? 0).attr("width", (d) => !isHorizontal ? xBand.bandwidth() : xLin(d.y)).attr(
4768
+ "height",
4769
+ (d) => !isHorizontal ? innerH - yLin(d.y) : yBand.bandwidth()
4770
+ );
4726
4771
  },
4727
- (update) => update.call((update2) => update2.raise()).transition(t).attr("x", (d) => x(d.x) ?? 0).attr("width", x.bandwidth()).attr("y", (d) => y(d.y)).attr("height", (d) => innerH - y(d.y)).style("fill", (d, i) => colorPalette[i % colorPalette.length]),
4728
- // Update color on update
4729
- (exit) => exit.transition(t).attr("y", margin.top + y(0)).attr("height", innerH - y(0)).remove()
4772
+ (update) => update.call((u) => u.raise()).transition(t).attr("x", (d) => !isHorizontal ? xBand(d.x) ?? 0 : 0).attr("y", (d) => !isHorizontal ? yLin(d.y) : yBand(d.x) ?? 0).attr("width", (d) => !isHorizontal ? xBand.bandwidth() : xLin(d.y)).attr(
4773
+ "height",
4774
+ (d) => !isHorizontal ? innerH - yLin(d.y) : yBand.bandwidth()
4775
+ ).style("fill", (d, i) => colorPalette[i % colorPalette.length]),
4776
+ (exit) => exit.transition(t).attr("width", !isHorizontal ? xBand.bandwidth() : 0).attr("height", !isHorizontal ? innerH - yLin(0) : yBand.bandwidth()).remove()
4730
4777
  );
4731
- g.selectAll("text.bar-label").data(data).join(
4732
- (enter) => enter.append("text").attr("class", "bar-label").attr("x", (d) => (x(d.x) ?? 0) + x.bandwidth() / 2).attr("y", (d) => y(d.y) - 6).attr("text-anchor", "middle").style("font-size", "50px").style("font-weight", "bold").style("font-family", "Arial, sans-serif").style("fill", (d, i) => colorPalette[i % colorPalette.length]).style("overflow", "visible").text((d) => d.y),
4733
- (update) => update.transition(t).attr("x", (d) => (x(d.x) ?? 0) + x.bandwidth() / 2).attr("y", (d) => y(d.y) - 6).text((d) => d.y),
4778
+ const labels = g.selectAll("text.bar-label").data(data, (d) => d.x);
4779
+ labels.join(
4780
+ (enter) => enter.append("text").attr("class", "bar-label").style("font-weight", "bold").style("font-family", "Kanit, sans-serif").style("font-size", "80px").style("fill", (d, i) => colorPalette[i % colorPalette.length]).attr("text-anchor", !isHorizontal ? "middle" : "start").attr(
4781
+ "x",
4782
+ (d) => !isHorizontal ? (xBand(d.x) ?? 0) + xBand.bandwidth() / 2 : xLin(d.y) + 6
4783
+ ).attr(
4784
+ "y",
4785
+ (d) => !isHorizontal ? yLin(d.y) - 6 : (yBand(d.x) ?? 0) + yBand.bandwidth() / 2 + 4
4786
+ ).text((d) => d.y),
4787
+ (update) => update.transition(t).attr("text-anchor", !isHorizontal ? "middle" : "start").attr(
4788
+ "x",
4789
+ (d) => !isHorizontal ? (xBand(d.x) ?? 0) + xBand.bandwidth() / 2 : xLin(d.y) + 6
4790
+ ).attr(
4791
+ "y",
4792
+ (d) => !isHorizontal ? yLin(d.y) - 6 : (yBand(d.x) ?? 0) + yBand.bandwidth() / 2 + 24
4793
+ ).text((d) => d.y),
4734
4794
  (exit) => exit.remove()
4735
4795
  );
4736
4796
  };
4737
4797
  useEffect9(() => {
4738
4798
  render();
4739
4799
  }, [data, height, margin, modeLabel, xDomain.toString(), yDomain.toString()]);
4740
- return /* @__PURE__ */ jsx46("div", { ref: containerRef, style: { width: "100%" }, children: /* @__PURE__ */ jsxs37("svg", { ref: svgRef, role: "img", "aria-label": "Bar chart", style: { display: "block", width: "100%", height }, children: [
4741
- /* @__PURE__ */ jsx46("g", { ref: gRef, transform: `translate(${margin.left},${margin.top})` }),
4742
- /* @__PURE__ */ jsx46("g", { ref: xAxisRef }),
4743
- /* @__PURE__ */ jsx46("g", { ref: yAxisRef })
4744
- ] }) });
4800
+ return /* @__PURE__ */ jsx46("div", { ref: containerRef, style: { width: "100%" }, children: /* @__PURE__ */ jsxs37(
4801
+ "svg",
4802
+ {
4803
+ ref: svgRef,
4804
+ role: "img",
4805
+ "aria-label": "Bar chart",
4806
+ style: { display: "block", width: "100%", height },
4807
+ children: [
4808
+ /* @__PURE__ */ jsx46("title", { children: "Bar chart" }),
4809
+ /* @__PURE__ */ jsx46("g", { ref: gRef, transform: `translate(${margin.left},${margin.top})` }),
4810
+ /* @__PURE__ */ jsx46("g", { ref: xAxisRef }),
4811
+ /* @__PURE__ */ jsx46("g", { ref: yAxisRef })
4812
+ ]
4813
+ }
4814
+ ) });
4745
4815
  };
4746
4816
 
4747
4817
  // src/Chart/PieChart/PieChart.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esic-lab/data-core-ui",
3
- "version": "0.0.72",
3
+ "version": "0.0.74",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",