LCOV - code coverage report
Current view: top level - src/utils - ssvg.js (source / functions) Hit Total Coverage
Test: lcov.info Lines: 28 62 45.2 %
Date: 2025-06-29 02:18:36 Functions: 13 15 86.7 %

          Line data    Source code
       1             : // @ts-check
       2             : import {
       3             :   clone, cloneDeep, find, get, identity, isNil, map, padStart,
       4             :   size, toNumber, toString
       5             : } from "lodash";
       6             : import { parser } from "@cern/ssvg-engine";
       7             : import { getAttribute } from "./element";
       8             : import { color, rgb } from "d3-color";
       9             : import { BaseLogger as logger } from "@cern/base-vue";
      10             : 
      11             : /**
      12             :  * @param  {Element|null} stateElement
      13             :  * @param  {string} name
      14             :  * @return {Element|null}
      15             :  */
      16             : export function getPropertyByName(stateElement, name) {
      17           1 :   return find(get(stateElement, "children"), (c) => {
      18           5 :     return (c.tagName === "property" || c.tagName === "computed") &&
      19             :       c.getAttribute("name") === name;
      20             :   }) || null;
      21             : }
      22             : 
      23             : /**
      24             :  * @param {Element|null} transformElement
      25             :  */
      26             : export function getTransformValues(transformElement) {
      27             :   // FIXME: support "by" and "to" without "from" ? (requires svg and selector access)
      28           0 :   try {
      29             :     /** @type {ssvg.$Transform[][]|null} */
      30           0 :     let transforms = [];
      31           0 :     const values = getAttribute(transformElement, "values");
      32           0 :     if (values) {
      33           0 :       transforms = parser.parseTTransformRange(values);
      34             :     }
      35             :     else {
      36           0 :       const from = getAttribute(transformElement, "from");
      37           0 :       if (from) {
      38           0 :         transforms.push(parser.parseTTransform(from) ?? []);
      39             :       }
      40           0 :       const to = getAttribute(transformElement, "to");
      41           0 :       if (to) {
      42           0 :         transforms.push(parser.parseTTransform(from) ?? []);
      43             :       }
      44             :     }
      45           0 :     return parser.normalizeTransform(transforms ?? []);
      46             :   }
      47             :   catch (err) {
      48             :     // logger.error(err);
      49           0 :     return null;
      50             :   }
      51             : }
      52             : 
      53             : /**
      54             :  * @param  {Element|null} relationElement
      55             :  */
      56             : export function getRelationValues(relationElement) {
      57           2 :   try {
      58           2 :     const values = getAttribute(relationElement, "values");
      59           2 :     if (!isNil(values)) {
      60           2 :       return parser.parseTRange(values);
      61             :     }
      62           0 :     const to = getAttribute(relationElement, "to");
      63           0 :     if (!isNil(to)) {
      64           0 :       const from = getAttribute(relationElement, "from");
      65           0 :       if (isNil(from)) {
      66             :         // FIXME get initial value from store
      67             :       }
      68           0 :       return parser.makeRange(
      69             :         parser.parseTValue(from), parser.parseTValue(to));
      70             :     }
      71             :     else {
      72           0 :       const by = getAttribute(relationElement, "by");
      73           0 :       if (!isNil(by)) {
      74           0 :         const current = parser.parseTValue(""); // FIXME get initial value from store
      75           0 :         const to = parser.parseTValue(getAttribute(relationElement, "by"));
      76             :         /* @ts-ignore */
      77           0 :         to.value += current?.value ?? 0;
      78           0 :         return parser.makeRange(current, to);
      79             :       }
      80             :     }
      81             :   }
      82             :   catch (err) {
      83           0 :     logger.error(err);
      84             :   }
      85           0 :   return null;
      86             : }
      87             : 
      88             : /**
      89             :  * @param {Element|null} relationElement relation or transform
      90             :  */
      91             : export function getKeyTimes(relationElement) {
      92           2 :   const keyTimes = getAttribute(relationElement, "key-times");
      93           2 :   if (!isNil(keyTimes)) {
      94           0 :     return parser.parseTRange(keyTimes)?.values ?? null;
      95             :   }
      96           2 :   return null;
      97             : }
      98             : 
      99           1 : const strRe = /([\\"'])/g;
     100             : /**
     101             :  * @param  {any} value
     102             :  * @param  {string} type
     103             :  */
     104             : export function tvalueToString(value, type) {
     105           6 :   const valueString = toString(value);
     106           6 :   if (type === "string") {
     107           6 :     return `"${valueString.replace(strRe, "\$1")}"`;
     108             :   }
     109           0 :   return valueString;
     110             : }
     111             : 
     112             : 
     113             : /**
     114             :  * @type {{ [from: string]: { [to: string]: (v: any) => any } }}
     115             :  */
     116           1 : const typeConverter = {
     117             :   string: {
     118           8 :     number: (v) => (toNumber(v.slice(1, -1)) || 0),
     119             :     color: (v) => {
     120           4 :       v = v.slice(1, -1);
     121           4 :       return color(v) ? (v) : ("#" + padStart((toNumber(v) || 0).toString(16), 6, "0"));
     122             :     }
     123             :   },
     124             :   number: {
     125           6 :     string: (v) => `"${v}"`,
     126           6 :     color: (v) => ("#" + padStart(toNumber(v).toString(16), 6, "0"))
     127             :   },
     128             :   color: {
     129           4 :     string: (v) => `"${(color(v) || rgb(0, 0, 0)).toString()}"`,
     130             :     number: (v) => {
     131           4 :       const c = (color(v) || rgb(0, 0, 0)).rgb();
     132           4 :       return c.b + (c.g << 8) + (c.r << 16);
     133             :     }
     134             :   }
     135             : };
     136             : 
     137             : /**
     138             :  * @brief convert a TRange to another type
     139             :  * @param  {ssvg.$TRange} tvalues
     140             :  * @param  {ssvg.$TTypeName} type
     141             :  * @return {ssvg.$TRange}
     142             :  */
     143             : export function trangeConvert(tvalues, type) {
     144           9 :   tvalues = cloneDeep(tvalues);
     145           9 :   const convert = get(typeConverter, [ tvalues.type, type ], identity);
     146          32 :   tvalues.values = map(tvalues.values, (v) => convert(v));
     147           9 :   delete tvalues.unit;
     148           9 :   tvalues.type = type;
     149           9 :   return tvalues;
     150             : }
     151             : 
     152             : /**
     153             :  * @param  {number[]} args
     154             :  * @param  {(string|null)[]} units
     155             :  * @return {string}
     156             :  */
     157             : export function transformArgsStr(args, units) {
     158             :   /** @type {any[]} */
     159           0 :   const ret = clone(args);
     160           0 :   if (!ret) { return ""; }
     161           0 :   for (let i = 0; i < size(units); ++i) {
     162           0 :     if (units[i]) {
     163           0 :       ret[i] = ret[i] + units[i];
     164             :     }
     165             :   }
     166           0 :   return ret.join(", ");
     167             : }

Generated by: LCOV version 1.16