Sincronização de Renderização e Ajustes na Biblioteca
A integração da biblioteca F2 da Alibaba em mini-programas DingTalk apresenta desafois específicos relacionados ao ciclo de vida assíncrono do setData. Problemas dimensionais inconsistentes entre diferentes gráficos ocorrem porque as operações de renderização não aguardam a conclusão da atualização de dados.
Para garantir consistência visual, é necessário estabelecer dimensões fixas antes da carga dos dados e somante executar a inicialização dos gráficos dentro do callback de setData. Além disso, modificações no módulo-fonte da F2 são requeridas para compatibilidade completa com o ambiente DingTalk.
Localize o arquivo de origem da biblioteca F2 no diretório node_modules e aplique as seguintes alterações na seção de gerenciamento de canvas:
// Modifique a função de redimensionamento para usar uniões de pixels específicas do DingTalk
_resizeCanvas: function() {
const query = dd.createSelectorQuery();
query.select(`#${this.canvasId}`).boundingClientRect();
query.exec((ret) => {
if (ret && ret[0]) {
const { width, height } = ret[0];
this.setData({
canvasWidth: width * this.pixelRatio,
canvasHeight: height * this.pixelRatio
}, () => {
this.chart.changeSize(width, height);
});
}
});
}
Exemplo Prático: Gráfico de Rosca e Gráfico de Barras Empilhadas
Componente JavaScript configurado com dois tipos de visualizações distintos:
Component({
data: {
dadosProporcao: [
{ tipo: 'Avanço', valorPercentual: 0.6, eixoX: '1' },
{ tipo: 'Montagem', valorPercentual: 0.4, eixoX: '1' },
{ tipo: 'Auxiliar', valorPercentual: 0.1, eixoX: '1' },
{ tipo: 'Falha', valorPercentual: 0.3, eixoX: '1' },
{ tipo: 'Outros', valorPercentual: 0.2, eixoX: '1' }
],
dadosComparativos: [
{ etapa: 'Escavação', faixa: '163', quantidade: 16 },
{ etapa: 'Escavação', faixa: '175', quantidade: 26 },
{ etapa: 'Parada', faixa: '163', quantidade: 16 },
{ etapa: 'Parada', faixa: '175', quantidade: 26 },
{ etapa: 'Anel', faixa: '163', quantidade: 36 },
{ etapa: 'Anel', faixa: '185', quantidade: 25 },
{ etapa: 'Parada', faixa: '185', quantidade: 25 },
{ etapa: 'Parada', faixa: '195', quantidade: 25 },
{ etapa: 'Anel', faixa: '195', quantidade: 25 },
{ etapa: 'Anel', faixa: '275', quantidade: 25 },
{ etapa: 'Anel', faixa: '275', quantidade: 25 },
{ etapa: 'Anel', faixa: '375', quantidade: 25 },
{ etapa: 'Anel', faixa: '375', quantidade: 25 },
{ etapa: 'Anel', faixa: '475', quantidade: 25 },
{ etapa: 'Parada', faixa: '475', quantidade: 25 }
],
legendaPercentuais: {
'Avanço': '60%',
'Montagem': '40%',
'Auxiliar': '10%',
'Falha': '30%',
'Outros': '20%'
}
},
methods: {
renderizarGraficoCircular(instancia) {
instancia.clear();
const dados = this.data.dadosProporcao;
const legendas = this.data.legendaPercentuais;
instancia.source(dados, {
valorPercentual: {
formatador: function(val) {
return (val * 100).toFixed(0) + '%';
}
}
});
instancia.legenda({
posicao: 'topo',
alinhamento: 'centro',
formatadorItem: function(val) {
return val + ' ' + legendas[val];
}
});
instancia.dicaFerramenta(false);
instancia.coordenada('polar', {
transposta: true,
raio: 1.9
});
instancia.eixo(false);
instancia.intervalo()
.posicao('eixoX*valorPercentual')
.cor('tipo', ['#61E2C4', '#52AAFE', '#A0AEFA', '#F38E68', '#868B96'])
.ajuste('empilhamento')
.estilo({
larguraLinha: 1,
traco: '#fff',
uniaoLinha: 'arredondada',
extremidadeLinha: 'arredondada'
})
.animacao({
aparecer: {
duracao: 1200,
suavizacao: 'bounceOut'
}
});
instancia.renderizar();
},
renderizarGraficoLinear(instancia) {
instancia.clear();
const dados = this.data.dadosComparativos;
instancia.escala({
faixa: {
alcance: [0.05, 1]
}
});
instancia.fonte(dados, {
etapa: {
minimo: 0,
formatador: function(val) {
return val;
}
}
});
instancia.intervalo()
.posicao('faixa*quantidade')
.cor('etapa')
.ajuste('empilhamento');
instancia.renderizar();
}
}
});
Implementação no template AXML:
<dd-charts idCanvas="grafico-circular" aoDesenhar="renderizarGraficoCircular"></dd-charts>
<dd-charts idCanvas="grafico-linear" aoDesenhar="renderizarGraficoLinear"></dd-charts>