D3. js нелинейная линейная шкала - PullRequest
0 голосов
/ 20 января 2020

Мне нужно создать линейную диаграмму, домен оси Y работает от 1.01 до 1000. В следующих точках на оси значение тика изменяется:

  • 1.01 до 2, tick = 0,01
  • 2 до 3, тик = 0,02
  • 3 до 4, тик = 0,05
  • 4 до 6, тик = 0,1
  • 6 до 10, тик = 0,2
  • от 10 до 20, тик = 0,5
  • от 20 до 30, тик = 1
  • от 30 до 50, тик = 2
  • 50 до 100, отметка = 5
  • 100-1000, отметка = 10

На изображении диаграммы все пути выше x = 4.0 в два раза длиннее, чем должны быть. Я исследовал нелинейные весы без особого успеха.


const svg = d3.select('#line_chart_svg');
const width = +svg.attr('width');
const height = +svg.attr('height');

const margin = { top: 20, bottom: 30, right: 20, left: 50 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;

const render = priceTimeData => {

const xValue = d => d.timeStamp;
const yValue = d => d.price;

const xScale = d3.scaleTime()
    .domain(d3.extent(priceTimeData, xValue))
    .range([0, innerWidth])
    .nice();

const yScale = d3.scaleLinear()
    .domain(d3.extent(priceTimeData, yValue))
    .range([innerHeight, 0]);
    console.log(yScale)

// Declare g and adjust size
const g = svg.append('g')
    .attr('transform', `translate(${margin.left}, ${margin.top})`);

// Setup xAxis 
const xAxis = d3.axisBottom(xScale);
const xAxisG = g.append('g').call(xAxis)
    .attr('transform', `translate(0, ${innerHeight})`);

// Setup yAxis
const yAxis = d3.axisLeft(yScale)
    .tickSize(-innerWidth);
const yAxisG = g.append('g').call(yAxis);

const lineGenerator = d3.line()
    .x(d => xScale(xValue(d)))
    .y(d => yScale(yValue(d)));

g.append('path')
.attr('class', 'line_path')
    .attr('d', lineGenerator(priceTimeData));

}

const priceTimeData = d3.csv('data/priceTime.csv').then(data => {
data.forEach(d => {
    d.price = +d.price
    d.timeStamp = new Date(d.timeStamp);
})
render(data)
});

Line Chart

1 Ответ

0 голосов
/ 21 января 2020

D3 не будет этого делать, если у вас нет разных шкал за период.

Я бы создал значения тиков вручную, например, так:

var tickValues = [
      {"lower": 1.01, "upper": 2, "interval": 0.01},
      {"lower": 2, "upper": 3, "interval": 0.02},
      {"lower": 3, "upper": 4, "interval": 0.05},
      {"lower": 4, "upper": 6, "interval": 0.1},
      {"lower": 6, "upper": 10, "interval": 0.2},
      {"lower": 10, "upper": 20, "interval": 0.5},
      {"lower": 20, "upper": 30, "interval": 1},
      {"lower": 30, "upper": 50, "interval": 2},
      {"lower": 50, "upper": 100, "interval": 5},
      {"lower": 100, "upper": 1000, "interval": 10}
    ]

    let tickArray = []
    let currentTickValue = 0

    tickValues.forEach(function(t){

      currentTickValue = t.lower

      for (var i = t.lower; i < t.upper; i = i + t.interval) {

        currentTickValue = currentTickValue + t.interval
        currentTickValue = (Math.floor(currentTickValue * 100))/100
        tickArray.push(currentTickValue)

      }
    })

    let yScale = d3.scaleLinear()
        //etc

    let yAxis = d3.axisRight(yScale)
        .tickValues(tickValues)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...