D3非时间x轴的多系列折线图

时间:2018-12-06 09:54:40

标签: javascript d3.js axis linechart

我在应用程序中实现了多系列折线图。此处提供了示例代码https://jsfiddle.net/yasirunilan/hevdy5kp/3/

在该图表中,X轴值是月份名称。但是由于本地化问题,我需要将月份名称更改为其他语言。然后问题来了,就像xAsis是时间序列一样,它在图表中给出了错误。有没有一种方法可以将此图表x轴转换为非时间序列。这样我就可以将月份名称用作字符串,这样就可以对月份名称进行修改,而不必担心x轴格式。

    var data = [{
    name: "USA",
    values: [{
        date: "January",
        price: "100"
      },
      {
        date: "February",
        price: "110"
      },
      {
        date: "March",
        price: "145"
      },
      {
        date: "April",
        price: "241"
      },
      {
        date: "May",
        price: "101"
      },
      {
        date: "June",
        price: "90"
      },
      {
        date: "July",
        price: "120"
      },
      {
        date: "August",
        price: "135"
      },
      {
        date: "September",
        price: "99"
      },
      {
        date: "October",
        price: "105"
      },
      {
        date: "November",
        price: "101"
      },
      {
        date: "December",
        price: "106"
      }
    ]
  },
  {
    name: "UK",
    values: [{
        date: "January",
        price: "130"
      },
      {
        date: "February",
        price: "120"
      },
      {
        date: "March",
        price: "115"
      },
      {
        date: "April",
        price: "220"
      },
      {
        date: "May",
        price: "100"
      },
      {
        date: "June",
        price: "140"
      },
      {
        date: "July",
        price: "90"
      },
      {
        date: "August",
        price: "235"
      },
      {
        date: "September",
        price: "160"
      },
      {
        date: "October",
        price: "86"
      },
      {
        date: "November",
        price: "201"
      },
      {
        date: "December",
        price: "140"
      }
    ]
  }
];

const margin = 80;
const width = 1000 - 2 * margin;
const height = 550 - 2 * margin;

var duration = 250;

var lineOpacity = "0.25";
var lineOpacityHover = "0.85";
var otherLinesOpacityHover = "0.1";
var lineStroke = "1.5px";
var lineStrokeHover = "2.5px";

var circleOpacity = '0.85';
var circleOpacityOnLineHover = "0.25"
var circleRadius = 3;
var circleRadiusHover = 6;


/* Format Data */
var parseDate = d3.time.format("%B");
data.forEach(function(d) {
  d.values.forEach(function(d) {
    d.date = parseDate.parse(d.date);
    d.price = +d.price;
  });
});

/* Scale */
var xScale = d3.time.scale()
  .domain(d3.extent(data[0].values, d => d.date))
  .range([0, width - margin]);
var yScale = d3.scale.linear()
  .domain([0, d3.max(data[0].values, d => d.price)])
  .range([height - margin, 0]);

// var color = d3.scale.ordinal(d3.schemeCategory10);
var color = d3.scale.category10();

/* Add SVG */
var svg = d3.select("svg")
  .attr("width", (width + margin) + "px")
  .attr("height", (height + margin) + "px")
  .append('g')
  .attr("transform", `translate(${margin}, ${margin})`);


/* Add line into SVG */
var line = d3.svg.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.price));

let lines = svg.append('g')
  .attr('class', 'lines');

lines.selectAll('.line-group')
  .data(data).enter()
  .append('g')
  .attr('class', 'line-group')
  .on("mouseover", function(d, i) {
    svg.append("text")
      .attr("class", "title-text")
      .style("fill", color(i))
      .text(d.name)
      .attr("text-anchor", "middle")
      .attr("x", (width - margin) / 2)
      .attr("y", 5);
  })
  .on("mouseout", function(d) {
    svg.select(".title-text").remove();
  })
  .append('path')
  .attr('class', 'line')
  .attr('d', d => line(d.values))
  .style('stroke', (d, i) => color(i))
  .style('opacity', lineOpacity)
  .on("mouseover", function(d) {
    d3.selectAll('.line')
      .style('opacity', otherLinesOpacityHover);
    d3.selectAll('.circle')
      .style('opacity', circleOpacityOnLineHover);
    d3.select(this)
      .style('opacity', lineOpacityHover)
      .style("stroke-width", lineStrokeHover)
      .style("cursor", "pointer");
  })
  .on("mouseout", function(d) {
    d3.selectAll(".line")
      .style('opacity', lineOpacity);
    d3.selectAll('.circle')
      .style('opacity', circleOpacity);
    d3.select(this)
      .style("stroke-width", lineStroke)
      .style("cursor", "none");
  });


/* Add circles in the line */
lines.selectAll("circle-group")
  .data(data).enter()
  .append("g")
  .style("fill", (d, i) => color(i))
  .selectAll("circle")
  .data(d => d.values).enter()
  .append("g")
  .attr("class", "circle")
  .on("mouseover", function(d) {
    d3.select(this)
      .style("cursor", "pointer")
      .append("text")
      .attr("class", "text")
      .text(`${d.price}`)
      .attr("x", d => xScale(d.date) + 5)
      .attr("y", d => yScale(d.price) - 10);
  })
  .on("mouseout", function(d) {
    d3.select(this)
      .style("cursor", "none")
      .transition()
      .duration(duration)
      .selectAll(".text").remove();
  })
  .append("circle")
  .attr("cx", d => xScale(d.date))
  .attr("cy", d => yScale(d.price))
  .attr("r", circleRadius)
  .style('opacity', circleOpacity)
  .on("mouseover", function(d) {
    d3.select(this)
      .transition()
      .duration(duration)
      .attr("r", circleRadiusHover);
  })
  .on("mouseout", function(d) {
    d3.select(this)
      .transition()
      .duration(duration)
      .attr("r", circleRadius);
  });



var xAxis = d3.svg.axis().scale(xScale)
  .orient("bottom").tickFormat(d3.time.format("%B")).tickSize(1);

var yAxis = d3.svg.axis().scale(yScale)
  .orient("left").tickSize(1);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${height-margin})`)
  .call(xAxis.ticks(d3.time.months));

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .append('text')
  .attr("y", 15)
  .attr("transform", "rotate(-90)")
  .attr("fill", "#000")
  .attr('text-anchor', 'middle')
  .text("No. of Employees");

1 个答案:

答案 0 :(得分:0)

经过其他人建议的不同方法后找到了解决方案。 https://jsfiddle.net/yasirunilan/8y3f09xb/4/

var data = [{
    name: "USA",
    values: [{
        date: "January",
        price: "100"
      },
      {
        date: "February",
        price: "110"
      },
      {
        date: "March",
        price: "145"
      },
      {
        date: "April",
        price: "241"
      },
      {
        date: "May",
        price: "101"
      },
      {
        date: "June",
        price: "90"
      },
      {
        date: "July",
        price: "120"
      },
      {
        date: "August",
        price: "135"
      },
      {
        date: "September",
        price: "99"
      },
      {
        date: "October",
        price: "105"
      },
      {
        date: "November",
        price: "101"
      },
      {
        date: "December",
        price: "106"
      }
    ]
  },
  {
    name: "UK",
    values: [{
        date: "January",
        price: "130"
      },
      {
        date: "February",
        price: "120"
      },
      {
        date: "March",
        price: "115"
      },
      {
        date: "April",
        price: "220"
      },
      {
        date: "May",
        price: "100"
      },
      {
        date: "June",
        price: "140"
      },
      {
        date: "July",
        price: "90"
      },
      {
        date: "August",
        price: "235"
      },
      {
        date: "September",
        price: "160"
      },
      {
        date: "October",
        price: "86"
      },
      {
        date: "November",
        price: "201"
      },
      {
        date: "December",
        price: "140"
      }
    ]
  }
];

const margin = 80;
const width = 1000 - 2 * margin;
const height = 550 - 2 * margin;

var duration = 250;

var lineOpacity = "0.25";
var lineOpacityHover = "0.85";
var otherLinesOpacityHover = "0.1";
var lineStroke = "1.5px";
var lineStrokeHover = "2.5px";

var circleOpacity = '0.85';
var circleOpacityOnLineHover = "0.25"
var circleRadius = 3;
var circleRadiusHover = 6;


/* Format Data */
data.forEach(function(d) {
  d.values.forEach(function(d) {
    d.date = d.date;
    d.price = +d.price;
  });
});

/* Scale */
var xScale = d3.scale.ordinal()
 .domain(data[0].values.map(function(d) {
    return d.date;
  }))
  .rangePoints([0, width], 0.9);
var yScale = d3.scale.linear()
  .domain([0, d3.max(data[0].values, d => d.price)])
  .range([height - margin, 0]);

// var color = d3.scale.ordinal(d3.schemeCategory10);
var color = d3.scale.category10();

/* Add SVG */
var svg = d3.select("svg")
  .attr("width", (width + margin) + "px")
  .attr("height", (height + margin) + "px")
  .append('g')
  .attr("transform", `translate(${margin}, ${margin})`);


/* Add line into SVG */
var line = d3.svg.line()
  .x(d => xScale(d.date))
  .y(d => yScale(d.price));

let lines = svg.append('g')
  .attr('class', 'lines');

lines.selectAll('.line-group')
  .data(data).enter()
  .append('g')
  .attr('class', 'line-group')
  .on("mouseover", function(d, i) {
    svg.append("text")
      .attr("class", "title-text")
      .style("fill", color(i))
      .text(d.name)
      .attr("text-anchor", "middle")
      .attr("x", (width - margin) / 2)
      .attr("y", 5);
  })
  .on("mouseout", function(d) {
    svg.select(".title-text").remove();
  })
  .append('path')
  .attr('class', 'line')
  .attr('d', d => line(d.values))
  .style('stroke', (d, i) => color(i))
  .style('opacity', lineOpacity)
  .on("mouseover", function(d) {
    d3.selectAll('.line')
      .style('opacity', otherLinesOpacityHover);
    d3.selectAll('.circle')
      .style('opacity', circleOpacityOnLineHover);
    d3.select(this)
      .style('opacity', lineOpacityHover)
      .style("stroke-width", lineStrokeHover)
      .style("cursor", "pointer");
  })
  .on("mouseout", function(d) {
    d3.selectAll(".line")
      .style('opacity', lineOpacity);
    d3.selectAll('.circle')
      .style('opacity', circleOpacity);
    d3.select(this)
      .style("stroke-width", lineStroke)
      .style("cursor", "none");
  });


/* Add circles in the line */
lines.selectAll("circle-group")
  .data(data).enter()
  .append("g")
  .style("fill", (d, i) => color(i))
  .selectAll("circle")
  .data(d => d.values).enter()
  .append("g")
  .attr("class", "circle")
  .on("mouseover", function(d) {
    d3.select(this)
      .style("cursor", "pointer")
      .append("text")
      .attr("class", "text")
      .text(`${d.price}`)
      .attr("x", d => xScale(d.date) + 5)
      .attr("y", d => yScale(d.price) - 10);
  })
  .on("mouseout", function(d) {
    d3.select(this)
      .style("cursor", "none")
      .transition()
      .duration(duration)
      .selectAll(".text").remove();
  })
  .append("circle")
  .attr("cx", d => xScale(d.date))
  .attr("cy", d => yScale(d.price))
  .attr("r", circleRadius)
  .style('opacity', circleOpacity)
  .on("mouseover", function(d) {
    d3.select(this)
      .transition()
      .duration(duration)
      .attr("r", circleRadiusHover);
  })
  .on("mouseout", function(d) {
    d3.select(this)
      .transition()
      .duration(duration)
      .attr("r", circleRadius);
  });



var xAxis = d3.svg.axis().scale(xScale)
  .orient("bottom").tickSize(1);

var yAxis = d3.svg.axis().scale(yScale)
  .orient("left").tickSize(1);

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${height-margin})`)
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .append('text')
  .attr("y", 15)
  .attr("transform", "rotate(-90)")
  .attr("fill", "#000")
  .attr('text-anchor', 'middle')
  .text("No. of Employees");