Ir al contenido

Traducir la interfaz de usuario ​

Pivotick escribe su propio texto: el carril, los menús, la barra lateral, la tabla, el panel dinámico, la historia, los brindis y cada title información sobre herramientas y aria-label detrás de ellos. El i18n La opción lo pone todo en su idioma.

js
const graph = new Pivotick(container, data, {
    i18n: { locale: 'fr' }, 
})

El texto que entrega a la biblioteca se dibuja exactamente como se indica y nunca se busca: nodo y borde etiquetas, etiquetas de facetas y leyendas, nombres de pivotes, modos de ferrocarril, pestañas de acoplamiento, acciones de la barra superior y el filas que agrega a un menú contextual. Tradúcelos antes de pasarlos.

Idiomas incluidos ​

Cada compilación incluye traducciones completas de la interfaz de usuario integrada:

IdiomaLocalidadEjemplos de etiquetas regionales
Inglés (predeterminado)enen-GB, en-US
Chino simplificadozhzh-CN, zh-Hans
francésfrfr-FR, fr-CA
alemándede-DE, de-CH
portuguésptpt-BR, pt-PT
holandésnlnl-NL, nl-BE
japonésjaja-JP
árabearar-EG, ar-SA
españoleses-ES, es-MX

Establezca i18n.locale para seleccionar uno. Las etiquetas regionales utilizan el mismo catálogo de idiomas mientras conservando sus propias reglas de formato, clasificación y plural de números. El catálogo chino utiliza caracteres simplificados; no existe una traducción separada al chino tradicional. un lugar sin catálogo incluido utiliza inglés a menos que proporcione messages o translate. Omitir locale mantiene el inglés predeterminado existente; No se detecta el idioma del navegador.

Los catálogos se exportan como messagesEn, messagesZh, messagesFr, messagesDe, messagesPt, messagesNl, messagesJa, messagesAr, messagesEs y juntos como bundledMessages, también disponible en Pivotick en las versiones del navegador.

La opción ​

PropiedadTipoPredeterminadoDescripción
localestring'en'Una etiqueta BCP 47 como 'fr', 'de-CH' o 'pt-BR'. Selecciona las reglas del plural, cómo se escriben los números y cómo se ordenan las listas. Cuando se proporciona, también se establece como lang de la raíz del gráfico.
messagesPartial<Messages>{}Anulaciones por clave. Las claves que faltan utilizan el idioma incluido y luego el inglés.
translate(key, params, fallback) => string | undefinedUn puente a su propia biblioteca de traducción, solicitado por cada clave que messages no tiene.

El idioma se establece cuando se construye el gráfico. Para cambiarlo, llame a graph.destroy() y cree el gráfico nuevamente con las nuevas opciones.

Cómo se encuentra un mensaje ​

Cada fragmento de texto se busca en este orden y gana la primera respuesta:

  1. La opción propia de la característica, cuando tiene una: UI.emptyState.render, UI.busyIndicator.label, UI.simplify.typeLabel, o title y confirmLabel usted pasar a ctx.confirm(). Estos son más específicos que cualquier catálogo.
  2. messages, tu tabla de claves.
  3. translate, tu puente.
  4. El idioma incluido, seleccionado por locale.
  5. Inglés, cuando el idioma no tiene catálogo incluido.

Se admiten anulaciones parciales: cambie solo los términos que su aplicación necesita y el resto utiliza el idioma seleccionado. Los idiomas no admitidos pasan al inglés sin previo aviso.

Claves y mensajes ​

Cada mensaje tiene una clave de puntos estable que lleva el nombre del lugar donde aparece: 'contextMenu.node.pin', 'history.menu.empty', 'sidebar.neighbors.connections'. las llaves se escriben a partir del catálogo en inglés, por lo que en TypeScript una clave mal escrita no se compila y su editor completa el resto.

Un mensaje adopta una de tres formas.

Texto con marcadores de posición ​

Una cadena, con {name} donde va un valor:

js
messages: {
    'search.result.inGroup': 'dans {group}',
    'history.menu.count': '{count} sur {limit}',
}

Un número se escribe de la forma en que lo escribe la configuración regional antes de ingresar: 1,234 debajo de 'en', 1.234 debajo de 'de', 1 234 debajo de 'fr'. Una cadena entra tal como está escrita.

Formas plurales ​

Un mensaje que depende de un recuento es un objeto con una entrada por categoría plural. usos del lenguaje. La categoría se elige del parámetro count por el navegador Intl.PluralRules, por lo que las reglas son las que CLDR define para la configuración regional. other es requerido, ya que cada idioma lo tiene.

js
// English and French need two forms; French counts zero as one
'count.nodes': { one: '{count} nœud', other: '{count} nœuds' },

// Polish needs four: 1 węzeł, 3 węzły, 5 węzłów, 1,5 węzła
'count.nodes': { one: '{count} węzeł', few: '{count} węzły', many: '{count} węzłów', other: '{count} węzła' },

Las categorías son zero, one, two, few, many y other. Una forma que hace el lenguaje El no uso nunca se selecciona y el que falta vuelve a other.

El inglés alternativo mantiene las reglas del plural en inglés en cualquier ubicación. Por ejemplo, un sin soporte el lenguaje que trata el cero como singular aún obtiene "0 nodos" del respaldo en inglés.

una función ​

Para cualquier cosa que una plantilla no pueda decir, un mensaje puede ser una función de los parámetros sin formato y el gráficos I18n:

js
'simplify.typeLabel': ({ count, type }, i18n) =>
    `${i18n.formatNumber(Number(count))} ${type === 'ip' ? 'adresses IP' : type}`,

Cualquiera que sea su forma, un mensaje es texto. Se inserta como texto, nunca se analiza como HTML, por lo que <b> aparece como está escrito.

Editar archivos de traducción de PO ​

El directorio locales/ del repositorio contiene una plantilla gettext, pivotick.pot, y completa Archivos zh.po, fr.po, de.po, pt.po, nl.po, ja.po, ar.po y es.po. Estos archivos también se envían en el paquete npm. Abra un archivo .po en Poedit o cualquier editor de texto UTF-8. Cada msgctxt es la clave del mensaje estable; msgid es la fuente en inglés y msgstr es la traducción. Mantenga {placeholders} intacto. Para entradas en plural, traduzca cada espacio msgstr[n]: el chino y el japonés tienen other solamente; El árabe tiene zero, one, two, few, many, luego other; francés, alemán, El portugués, el holandés y el español tienen one y luego other. El tiempo de ejecución utiliza Intl.PluralRules, con las categorías faltantes volviendo a other, en lugar de evaluar el encabezado gettext como JavaScript.

Desde una fuente de pago con npm ci completado:

sh
# Refresh the template and merge English changes into the PO files
npm run i18n:extract

# Edit locales/*.po, finish empty entries and review any fuzzy translations

# Compile PO files into the TypeScript catalogues used by every build
npm run i18n:compile

# Check completeness, source text, placeholders, plurals and generated files
npm run i18n:check
npm run test:i18n

Confirme los archivos PO, la plantilla y los archivos src/i18n/locales/*.ts generados juntos. no editar los archivos generados directamente. La extracción conserva las traducciones y el traductor existentes. comentarios, marca el texto en inglés modificado como fuzzy y deja las nuevas entradas vacías. resolver esos entradas antes de compilar. Las claves eliminadas se eliminan del catálogo activo. npm run build se ejecuta i18n:check, por lo que una traducción incompleta o un catálogo generado desactualizado falla construir. Estos comandos utilizan dependencias de nodos existentes; no se necesita instalación de gettext del sistema.

Para agrupar otro idioma, agregue su configuración regional y su asignación de ranura plural a scripts/i18n.mjs, extraiga y traduzca el nuevo archivo PO, compílelo y luego exporte el catálogo generado desde src/i18n/locales/index.ts y agréguelo a bundledMessages. Para un lenguaje exclusivo de aplicación, pasando un catálogo como i18n.messages todavía funciona sin cambiar Pivotick.

Iniciar un catálogo desde messagesEn ​

El catálogo en inglés se exporta como messagesEn, desde la compilación ES y como Pivotick.messagesEn de las compilaciones del navegador. Contiene cada clave con su texto en inglés, y Son datos simples, por lo que pueden escribirse como el archivo desde el que comienzan sus traductores:

js
import { messagesEn } from 'pivotick'

console.log(JSON.stringify(messagesEn, null, 4))

Vuelva a cargar el archivo traducido como messages. En TypeScript, un catálogo declarado con satisfies Messages debe nombrar cada clave, de modo que una clave agregada en una versión posterior aparezca como un error de compilación en lugar de una cadena perdida en inglés:

ts
import type { Messages } from 'pivotick'

export const messagesFr = {
    'count.nodes': { one: '{count} nœud', other: '{count} nœuds' },
    // …every other key
} satisfies Messages

Utilice Partial<Messages> en su lugar para traducir sobre la marcha.

Uniendo su propia biblioteca de traducción ​

Si su aplicación ya se traduce a través de una biblioteca, translate mantiene una fuente de verdad y un cambio de idioma. Se llama para cada tecla que messages no tenga, con:

  • key: la clave del mensaje, como 'count.nodes';
  • params: los valores sin formato, con números sin formato, por lo que el plural y el número son propios de su biblioteca se aplican reglas;
  • fallback: el texto en inglés, ya completado.

Devuelve una cadena para usarlo, o undefined para usar el idioma incluido y luego el inglés. Aquí con i18next, cuyo parámetro count ya controla sus plurales:

js
const graph = new Pivotick(container, data, {
    i18n: {
        locale: i18next.language,
        translate: (key, params, fallback) => {
            const found = i18next.exists(`pivotick.${key}`)
            return found ? i18next.t(`pivotick.${key}`, params) : undefined
        },
    },
})

Luego, sus archivos de recursos escriben sus mensajes en la propia sintaxis de su biblioteca. ("{{count}} nœuds" en i18next), bajo las mismas claves.

Un translate que arroja es atrapado: la consola dice qué tecla y el idioma incluido (o inglés para un idioma no admitido). El gancho todavía recibe el inglés como idioma fallback argumento, preservando el contrato puente. Cuando messages y translate tienen una clave, messages gana y translate no se le pregunta.

Números, listas, clasificación y lang ​

locale cubre más que palabras. Debajo de él:

  • Counts se escriben con Intl.NumberFormat: "1,234 nodos" en inglés, "1.234 Knoten" en Alemán. El inglés alternativo también utiliza el formato numérico de la configuración regional seleccionada.
  • Las listas de nombres en una oración se unen con Intl.ListFormat: "a, byc", "a, b et c".
  • Ordena en la tabla, la lista de vecinos y el panel de clasificación dinámico usan Intl.Collator, entonces "Émile" aparece al lado de "Emma", el sueco pone "ä" después de la "z" y "elemento 10" viene después "elemento 9".

Cuando declaras un locale, el elemento raíz del gráfico se obtiene como lang, al igual que las partes. la biblioteca se monta fuera de la raíz (información sobre herramientas, menús desplegables, listas de sugerencias). Lectores de pantalla entonces Lea la interfaz con la voz correcta. Sin un locale, no se establece ningún lang: el de la biblioteca El texto es inglés, pero los datos dentro del gráfico están en el idioma de su página y el idioma de la página. El propio lang lo describe mejor.

No se admite el diseño de derecha a izquierda: no hay manejo de dir y la interfaz está configurada de izquierda a derecha en todos los idiomas.

Un idioma por gráfico ​

Cada gráfico tiene su propio lenguaje. Dos gráficos en una página pueden usar dos idiomas, y ninguno afecta al otro.

Un gráfico dentro de un gráfico habla de su padre: el subgrafo dibujado dentro de un grupo y el pequeño gráfico de vecinos en la barra lateral.

El texto que la biblioteca escribe en sus datos se escribe una vez, en el lenguaje del gráfico: un historial la etiqueta de la entrada ("Ocultar 3 nodos") y el cuerpo con el que comienza una nueva nota. Reconstruyendo el gráfico en otro idioma los deja como estaban.

En código: graph.i18n y complementos ​

graph.i18n es el lenguaje del gráfico, el mismo objeto con el que escribe la biblioteca:

Miembroque hace
localeLa etiqueta en uso: la tuya o 'en'.
t(key, params?)El texto de un mensaje integrado, a través de la búsqueda anterior.
formatNumber(value, options?)Un número en los dígitos de la localidad. Acepta Intl.NumberFormat opciones.
formatList(items, options?)Elementos unidos como una oración. Acepta Intl.ListFormat opciones.
compare(a, b)Un comparador en el orden local, seguro para pasar a sort tal como está.
collator(options?)El Intl.Collator detrás de compare, numérico por defecto.

Un plugin lee el mismo objeto que ctx.i18n. El texto que escribe el complemento es el complemento para traducir, tecleado en ctx.i18n.locale; formatear sus recuentos y ordenar sus Las listas hasta ctx.i18n las mantienen consistentes con el resto del gráfico.

js
const nodeCounter = {
    name: 'node-counter',
    install(ctx) {
        const words = { fr: 'Total', de: 'Gesamt' }
        const label = words[ctx.i18n.locale.split('-')[0]] ?? 'Total'
        const count = ctx.i18n.formatNumber(ctx.graph.getNodes().length)
        // …draw `${label}: ${count}`
    },
}

Lo que se queda como está ​

  • Tus datos. Las etiquetas de nodos y bordes, los nombres de propiedades y los valores se dibujan tal como están. un El nombre de la propiedad sin una etiqueta declarada está en mayúsculas y minúsculas a partir de su clave (first_seen lee "Visto por primera vez"); declarar nodePropertiesMap o edgePropertiesMap para nombrar en tu idioma. La fila id que las listas de propiedades agregan encima de sus propias claves se escribe como la clave que es.
  • Texto del desarrollador. Las advertencias de la consola y los errores arrojados permanecen en inglés.
  • Glifos clave. ⌃ ⇧ ⌥ ⌘ se muestran tal como están. Los nombres clave son mensajes. (keys.ctrlCombo, keys.escape), por lo que una interfaz alemana puede decir Strg+Z.
  • La insignia cuenta en el borde de un nodo (2k, 99+), que debe caber en tres caracteres.