tween 不更新 Vue/D3 中的文本标签格式
tween does not update text label format in Vue/ D3
我一直在尝试将在简单 D3 中完美运行的代码传递给 Vue。这部分代码应该更新条形图的标签文本,但不起作用。这是 data.csv:
country,population
China,2535
India,1654
United States,700
Indonesia,680
Brazil,1785
Total,1821
这是管理条形图的代码:
import formatCurrency from '../mixins/formatCurrency';
import formatTime from '../mixins/formatTime';
import {
select,
scaleLinear,
max,
scaleBand,
interpolate,
axisLeft,
axisBottom,
forceX,
csv,
filter
} from 'd3';
//..
data: () => ({
dataset: [],
dataFiltrada: [],
}),
//..
async mounted() {
let datos = await csv('/datasets/data.csv')
this.dataset = Object.freeze(datos)
//..
this.graph()
},
computed: {
//..
filtrarData() {
this.dataFiltrada = this.dataset.filter(d => { return d.country !=='Total'})},
},
methods: {
graph(){
//..
const numeros = g.selectAll(this.label).data(this.dataFiltrada)
numeros
.enter().append("text")
.attr("class", this.label)
.attr('x', this.xEtiqueta)
.attr('y', d => { return -yScale(d.country); })
.attr('dy', this.yEtiqueta)
.text(0)
.merge(numeros)
.transition().duration(this.time)
.tween(this.label, d => {
var i = interpolate(1, d.population);
if (d.population != 0)
return function(t) {
select(this).text(d => {
return (this.label === 'labelg1')
? this.formatCurrency(i(t))
: this.formatTime(i(t))
}
//..
mixins: [
formatCurrency,
formatTime,
],
}
转换正常,但格式没有更新。当我 console.log formatCurrency 的任何值都在 function(t) 之外时,没问题,但在 function(t) 的范围内不起作用。 formatCurrency 函数是这样的:
import { format } from 'd3';
export default {
methods: {
formatCurrency:(() => {
var cantNum;
var formatofinal;
var simbol = "$";
function digits_count(n) {
var count = 0;
if (n >= 1) ++count;
while (n / 10 >= 1) {
n /= 10;
++count;
}
return count;
};
function processCantNumAndFormatOfinal(n){
if (digits_count(n) === 0) {
cantNum = 0;
formatofinal ='r';
}
else if (digits_count(n) === 1) {
cantNum = 1;
formatofinal ='s';
}
else if (digits_count(n) === 2) {
cantNum = 2;
formatofinal ='s';
}
else if (digits_count(n) === 3) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 4) {
cantNum = 2;
formatofinal ='s';
}
else if (digits_count(n) === 5) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 6) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 7) {
cantNum = 2;
formatofinal ='s';
}
else if (digits_count(n) === 8) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 9) {
cantNum = 3;
formatofinal ='s';
}
else {
cantNum = 2;
formatofinal ='s';
};
}
function formatear(n) {
// Process cantNum and formatofinal here ... function call
processCantNumAndFormatOfinal(n);
const formato = simbol + format(",."+ cantNum +formatofinal)(n)
.replace('.', ',')
.replace('G', 'B');
return formato;
};
return function(n)
{
return formatear(n);
}
}
})()
}
我也试过箭头函数,但数据归零。
.merge(numeros)
.transition().duration(this.tiempo)
.tween(this.label, d => {
var i = interpolate(1, d.population);
if (d.population != 0)
return (t) => { //..}
已编辑:
现在我注意到两件事:
- this.label 在 function(t) 内部无法识别。当我转换它时:
(this.label === 'labelg1')
进入这个:
(this.label != 'labelg1')
条件已识别,但我现在收到的错误消息是:
Uncaught TypeError: _this3.formatCurrency is not a function
已编辑 2:
我已经更改了 formatCurrency 的方法,这是新结构:
import { format } from 'd3';
export default {
methods: {
formatCurrency(n) {
let count = digitsCount(n)
let numeros = processCantNumAndFormatOfinal(count)[0]
let formatoF = processCantNumAndFormatOfinal(count)[1]
let final = formatear(numeros, formatoF, n)
console.log(final)
return final
}
}
}
function digitsCount(n) {
let count = 0;
if (n >= 1) ++count;
while (n / 10 >= 1) {
n /= 10;
++count;
}
return count;
}
function processCantNumAndFormatOfinal(n) {
let cantNum;
let formatofinal;
if (n === 0) {
cantNum = 0;
formatofinal ='r';
}
else if (n === 1) {
cantNum = 1;
formatofinal ='s';
}
else if (n === 2) {
cantNum = 2;
formatofinal ='s';
}
else if (n === 3) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 4) {
cantNum = 2;
formatofinal ='s';
}
else if (n === 5) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 6) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 7) {
cantNum = 2;
formatofinal ='s';
}
else if (n === 8) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 9) {
cantNum = 3;
formatofinal ='s';
}
else {
cantNum = 2;
formatofinal ='s';
}
return [cantNum,formatofinal]
}
function formatear(cantNum, formatofinal, n) {
let formato = format(",."+ cantNum + formatofinal)(n)
return formato;
}
对于组件:
<template>
</template>
<script>
import formatCurrency from '../mixins/formatCurrency';
import formatTime from '../mixins/formatTime';
//...
async mounted() {
let datos = await csv('/datasets/data.csv')
this.dataset = Object.freeze(datos)
this.dataNumero
this.filtrarData
this.graph()
this.formatearData
},
//...
computed: {
//...
dataNumero() {
this.dataset.forEach( function(d) { return d.population = +d.population})
},
filtrarData() {
this.dataFiltrada = this.dataset.filter(function(d) { return d.country !== 'Total'})
},
formatearData() {
this.dataFiltrada.forEach( function(d) { return d.population = this.formatCurrency(d.population) })
},
methods: {
graph() {
//..
const numeros = g.selectAll(this.label).data(this.dataFiltrada)
numeros
.enter().append("text")
.attr("class", this.label)
/* esto les da posición a las etiquetas en x e y */
.attr('x', this.xEtiqueta)
.attr('y', d => { return -yScale(d.country); })
.attr('dy', this.yEtiqueta)
.text(0)
/* esto agrega las transiciones */
.merge(numeros)
.transition().duration(this.tiempo)
.tween(this.label, function(d) {
var i = interpolate(1, d.population);
if (d.population != 0)
return function(t) {
select(this).text(Math.round(i(t)))
};
})
//..
mixins: [
formatCurrency,
formatTime
],
使用 formatearData() {this.dataFiltrada.forEach(d => //..
中的箭头功能,控制台显示结果正常,但当我更改 formatearData()
时,图表显示所有高于 3 位数字的 NaN 值(?????)删除箭头函数 formatearData() {this.dataFiltrada.forEach(function(d) { d.population = //..
错误是:Error in mounted hook (Promise/async): "TypeError: Cannot read property 'formatCurrency' of undefined"
下面是供参考的图像。
已编辑 3:
好的,不起作用的函数是 d3 格式,问题是我试图用特殊格式格式化 d3 条形图的文本标签编号,但是当发生这种情况时,数字会转换为字符串并呈现NaN 值,所以相关的问题是:在补间转换或其他方法期间,是否有任何方法可以在 vue 中格式化 D3 条形图标签数字?,因为这段代码与简单的 javascript 和 webpack 完美配合,但在 vue 中是一个不同的故事。
避免arrow functions
使用this
keyword.Use作为:
select(this).text(function(d){
return (this.label === 'labelg1')
? this.formatCurrency(i(t))
: this.formatTime(i(t))
}
更多详情这个
我找到了这个库 numeral.js
,我的代码现在看起来像这样:
methods: {
graph() {
...
var numeral = require("numeral");
const sin = this;
...
const numeros = g.selectAll(this.label).data(this.dataFiltrada)
numeros
.enter().append("text")
.attr("class", this.label)
/* esto les da posición a las etiquetas en x e y */
.attr('x', this.xEtiqueta)
.attr('y', function(d) { return -yScale(d.Segmento); })
.attr('dy', this.yEtiqueta)
.text(0)
/* esto agrega las transiciones */
.merge(numeros)
.transition().duration(this.tiempo)
.tween(this.label, function(d) {
var i = interpolate(0, d.Valor);
if (d.Valor != 0)
return function(t) {
const formatoNum = sin.formatoNum;
select(this).text(numeral(i(t)).format(formatoNum))
}
});
另一个重要的事情是像这样在 Home.vue 中设置组件:
<template>
...
<graph id="graficoBarras1" v-bind='props1' :dataFiltrada="data1" v-if="data1.length" :key="gbKey"/>
...
data() {
return {
...
props1: {
...
formatoNum : '[=11=].0a'
},
...
data1 : [],
gbKey : 0,
...
methods: {
forceRerender() {
this.gbKey += 1;
},
有了这个,我的转换终于成功了。
我一直在尝试将在简单 D3 中完美运行的代码传递给 Vue。这部分代码应该更新条形图的标签文本,但不起作用。这是 data.csv:
country,population
China,2535
India,1654
United States,700
Indonesia,680
Brazil,1785
Total,1821
这是管理条形图的代码:
import formatCurrency from '../mixins/formatCurrency';
import formatTime from '../mixins/formatTime';
import {
select,
scaleLinear,
max,
scaleBand,
interpolate,
axisLeft,
axisBottom,
forceX,
csv,
filter
} from 'd3';
//..
data: () => ({
dataset: [],
dataFiltrada: [],
}),
//..
async mounted() {
let datos = await csv('/datasets/data.csv')
this.dataset = Object.freeze(datos)
//..
this.graph()
},
computed: {
//..
filtrarData() {
this.dataFiltrada = this.dataset.filter(d => { return d.country !=='Total'})},
},
methods: {
graph(){
//..
const numeros = g.selectAll(this.label).data(this.dataFiltrada)
numeros
.enter().append("text")
.attr("class", this.label)
.attr('x', this.xEtiqueta)
.attr('y', d => { return -yScale(d.country); })
.attr('dy', this.yEtiqueta)
.text(0)
.merge(numeros)
.transition().duration(this.time)
.tween(this.label, d => {
var i = interpolate(1, d.population);
if (d.population != 0)
return function(t) {
select(this).text(d => {
return (this.label === 'labelg1')
? this.formatCurrency(i(t))
: this.formatTime(i(t))
}
//..
mixins: [
formatCurrency,
formatTime,
],
}
转换正常,但格式没有更新。当我 console.log formatCurrency 的任何值都在 function(t) 之外时,没问题,但在 function(t) 的范围内不起作用。 formatCurrency 函数是这样的:
import { format } from 'd3';
export default {
methods: {
formatCurrency:(() => {
var cantNum;
var formatofinal;
var simbol = "$";
function digits_count(n) {
var count = 0;
if (n >= 1) ++count;
while (n / 10 >= 1) {
n /= 10;
++count;
}
return count;
};
function processCantNumAndFormatOfinal(n){
if (digits_count(n) === 0) {
cantNum = 0;
formatofinal ='r';
}
else if (digits_count(n) === 1) {
cantNum = 1;
formatofinal ='s';
}
else if (digits_count(n) === 2) {
cantNum = 2;
formatofinal ='s';
}
else if (digits_count(n) === 3) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 4) {
cantNum = 2;
formatofinal ='s';
}
else if (digits_count(n) === 5) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 6) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 7) {
cantNum = 2;
formatofinal ='s';
}
else if (digits_count(n) === 8) {
cantNum = 3;
formatofinal ='s';
}
else if (digits_count(n) === 9) {
cantNum = 3;
formatofinal ='s';
}
else {
cantNum = 2;
formatofinal ='s';
};
}
function formatear(n) {
// Process cantNum and formatofinal here ... function call
processCantNumAndFormatOfinal(n);
const formato = simbol + format(",."+ cantNum +formatofinal)(n)
.replace('.', ',')
.replace('G', 'B');
return formato;
};
return function(n)
{
return formatear(n);
}
}
})()
}
我也试过箭头函数,但数据归零。
.merge(numeros)
.transition().duration(this.tiempo)
.tween(this.label, d => {
var i = interpolate(1, d.population);
if (d.population != 0)
return (t) => { //..}
已编辑:
现在我注意到两件事:
- this.label 在 function(t) 内部无法识别。当我转换它时:
(this.label === 'labelg1')
进入这个:
(this.label != 'labelg1')
条件已识别,但我现在收到的错误消息是:
Uncaught TypeError: _this3.formatCurrency is not a function
已编辑 2:
我已经更改了 formatCurrency 的方法,这是新结构:
import { format } from 'd3';
export default {
methods: {
formatCurrency(n) {
let count = digitsCount(n)
let numeros = processCantNumAndFormatOfinal(count)[0]
let formatoF = processCantNumAndFormatOfinal(count)[1]
let final = formatear(numeros, formatoF, n)
console.log(final)
return final
}
}
}
function digitsCount(n) {
let count = 0;
if (n >= 1) ++count;
while (n / 10 >= 1) {
n /= 10;
++count;
}
return count;
}
function processCantNumAndFormatOfinal(n) {
let cantNum;
let formatofinal;
if (n === 0) {
cantNum = 0;
formatofinal ='r';
}
else if (n === 1) {
cantNum = 1;
formatofinal ='s';
}
else if (n === 2) {
cantNum = 2;
formatofinal ='s';
}
else if (n === 3) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 4) {
cantNum = 2;
formatofinal ='s';
}
else if (n === 5) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 6) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 7) {
cantNum = 2;
formatofinal ='s';
}
else if (n === 8) {
cantNum = 3;
formatofinal ='s';
}
else if (n === 9) {
cantNum = 3;
formatofinal ='s';
}
else {
cantNum = 2;
formatofinal ='s';
}
return [cantNum,formatofinal]
}
function formatear(cantNum, formatofinal, n) {
let formato = format(",."+ cantNum + formatofinal)(n)
return formato;
}
对于组件:
<template>
</template>
<script>
import formatCurrency from '../mixins/formatCurrency';
import formatTime from '../mixins/formatTime';
//...
async mounted() {
let datos = await csv('/datasets/data.csv')
this.dataset = Object.freeze(datos)
this.dataNumero
this.filtrarData
this.graph()
this.formatearData
},
//...
computed: {
//...
dataNumero() {
this.dataset.forEach( function(d) { return d.population = +d.population})
},
filtrarData() {
this.dataFiltrada = this.dataset.filter(function(d) { return d.country !== 'Total'})
},
formatearData() {
this.dataFiltrada.forEach( function(d) { return d.population = this.formatCurrency(d.population) })
},
methods: {
graph() {
//..
const numeros = g.selectAll(this.label).data(this.dataFiltrada)
numeros
.enter().append("text")
.attr("class", this.label)
/* esto les da posición a las etiquetas en x e y */
.attr('x', this.xEtiqueta)
.attr('y', d => { return -yScale(d.country); })
.attr('dy', this.yEtiqueta)
.text(0)
/* esto agrega las transiciones */
.merge(numeros)
.transition().duration(this.tiempo)
.tween(this.label, function(d) {
var i = interpolate(1, d.population);
if (d.population != 0)
return function(t) {
select(this).text(Math.round(i(t)))
};
})
//..
mixins: [
formatCurrency,
formatTime
],
使用 formatearData() {this.dataFiltrada.forEach(d => //..
中的箭头功能,控制台显示结果正常,但当我更改 formatearData()
时,图表显示所有高于 3 位数字的 NaN 值(?????)删除箭头函数 formatearData() {this.dataFiltrada.forEach(function(d) { d.population = //..
错误是:Error in mounted hook (Promise/async): "TypeError: Cannot read property 'formatCurrency' of undefined"
下面是供参考的图像。
已编辑 3:
好的,不起作用的函数是 d3 格式,问题是我试图用特殊格式格式化 d3 条形图的文本标签编号,但是当发生这种情况时,数字会转换为字符串并呈现NaN 值,所以相关的问题是:在补间转换或其他方法期间,是否有任何方法可以在 vue 中格式化 D3 条形图标签数字?,因为这段代码与简单的 javascript 和 webpack 完美配合,但在 vue 中是一个不同的故事。
避免arrow functions
使用this
keyword.Use作为:
select(this).text(function(d){
return (this.label === 'labelg1')
? this.formatCurrency(i(t))
: this.formatTime(i(t))
}
更多详情
我找到了这个库 numeral.js
,我的代码现在看起来像这样:
methods: {
graph() {
...
var numeral = require("numeral");
const sin = this;
...
const numeros = g.selectAll(this.label).data(this.dataFiltrada)
numeros
.enter().append("text")
.attr("class", this.label)
/* esto les da posición a las etiquetas en x e y */
.attr('x', this.xEtiqueta)
.attr('y', function(d) { return -yScale(d.Segmento); })
.attr('dy', this.yEtiqueta)
.text(0)
/* esto agrega las transiciones */
.merge(numeros)
.transition().duration(this.tiempo)
.tween(this.label, function(d) {
var i = interpolate(0, d.Valor);
if (d.Valor != 0)
return function(t) {
const formatoNum = sin.formatoNum;
select(this).text(numeral(i(t)).format(formatoNum))
}
});
另一个重要的事情是像这样在 Home.vue 中设置组件:
<template>
...
<graph id="graficoBarras1" v-bind='props1' :dataFiltrada="data1" v-if="data1.length" :key="gbKey"/>
...
data() {
return {
...
props1: {
...
formatoNum : '[=11=].0a'
},
...
data1 : [],
gbKey : 0,
...
methods: {
forceRerender() {
this.gbKey += 1;
},
有了这个,我的转换终于成功了。