代码之家  ›  专栏  ›  技术社区  ›  Himani

线图和面积图之间的颜色不同

  •  0
  • Himani  · 技术社区  · 8 年前

    edit image 我使用的是d3 v4。我在其中创建了面积和折线图。数据形成是。 图表=>[1,4,5,2.4,6] 行=>[3,3,3,3,3]

    现在我的要求是在折线图下面,面积图应该有不同的颜色。

    如果有任何其他库可以这样做,那么也建议。 这是我画直线和面积图的函数。 所以如果 dailyConsValue>targetConsValue?“无颜色“:“显示颜色” dailydate是年【2017年1月-2017年12月】=>这是动态的。

    下面是我的代码:

    function drawGraph(drawData, highlightedData, first, last) {
    let margin, width, height, parseDate, xScale, yScale, area, 
    dailyConsumption, targetConsumption, svg;
    margin = {
      top: 10,
      right: 60,
      bottom: 10,
      left: 60
    },
    width = document.querySelector('#graph').clientWidth - margin.left - margin.right,
    height = document.querySelector('#graph').clientHeight - margin.top - margin.bottom;
    
    parseDate = d3.timeParse('%b %Y');
    // x axis
    xScale = d3.scaleTime().domain([parseDate(first), parseDate(last)]).range([0, width]);
    // y axis
    yScale = d3.scaleLinear().domain([-1, 2 + Math.max.apply(this, drawData.map(function(o){return o.dailyConsValue; }))])
    .range([height, 0]);
    
    area = d3.area()
    .x(function(d) { return xScale(d['dailyDate']); })
    .y0(function(d) { return yScale(d['targetConsValue']); })
    .y1(function(d) { return yScale(d['dailyConsValue']); });
    // define the line
    dailyConsumption = d3.line().x(function(d) {return xScale(d['dailyDate']); })
     .y(function(d) {return yScale(d['dailyConsValue']); });
    
    targetConsumption = d3.line().x(function(d) {return xScale(d['dailyDate']); })
        .y(function(d) {return yScale(d['targetConsValue']); });
    
    svg = d3.select('#graph').append('svg')
        .attr('width', width + margin.left + margin.right)
        .attr('height', height + margin.top + margin.bottom)
      .append('g')
        .attr('transform',
              'translate(' + margin.left + ',' + margin.top + ')');
    
     // add axis
     svg.append('g')
     .attr('transform', 'translate(0,0)').attr('class', 'Xaxis')
     .call(d3.axisTop(xScale).ticks(drawData.length).tickSize(-innerHeight).tickFormat(d3.timeFormat('%b %Y')));
     svg.append('g').attr('class', 'Yaxis')
     .call(d3.axisLeft(yScale).tickSize(0));
    
     // Prepare data
     drawData.forEach(function( d ) {
       d['dailyDate'] = parseDate( d['dailyDate'] );
       d['targetConsValue'] = d['targetConsValue'];
       d['dailyConsValue'] = d['dailyConsValue'];
     } );
    
     highlightedData.forEach(function( d ) {
       d['dailyDate'] = parseDate( d['dailyDate'] );
       d['dailyConsValue'] = d['dailyConsValue'];
       d['active'] = d['active'];
     } );
    
     // add the area
     svg.append('path').data([drawData]).attr('class', 'area')
     .attr('d', area)
      .transition().duration(2500).attrTween( 'd', this.tween( drawData, area ) );
    
     // add data for first line
     svg.append('path')
     .data([drawData])
     .attr('class', 'daily').attr('d', targetConsumption).transition()
     .duration(2500).delay(1500 / 2).attrTween( 'd', this.tween( drawData, targetConsumption ) );
    
    // add data for futureConsumption
     svg.append('path')
     .data([drawData])
     .attr('class', 'target').attr('data-legend', 'CST')
     .attr('d', dailyConsumption);
    
     createLengends(drawData);
     drawCircle(drawData, '10', '#037DA6');
     drawCircle(drawData, '5', '#003A54');
    
    
    /**
     * legends start
     * @param datalegendsData
     */
    function createLengends(datalegendsData) {
      let legend;
      legend = svg.selectAll('.legend').data([datalegendsData])
        .enter().append('g').attr('class', 'legend')
        .attr('transform', function(d, i) { return 'translate(0,' + i * 20 + ')'; });
      // making a line for legend
      legend.append('line')
          .attr('x1', width - 335).attr('x2', width - 305).attr('y1', height - 1)
          .attr('y2', height - 1).style('stroke', '5,5').style('stroke', '#4682B4');
    
      legend.append('text').attr('x', width - 300).attr('y', height - 1)
          .attr('dy', '.35em').style('text-anchor', 'start').text('IST Verbrauch WOB')
          .style('fill', '#666').style('font-weight', 'normal');
    
      legend.append('line').attr('x1', width - 130).attr('x2', width - 100)
          .attr('y1', height - 1).attr('y2', height - 1).style('stroke-dasharray', '5,5')
          .style('stroke', '#003A54');
    
      legend.append('text').attr('x', width - 96).attr('y', height - 1).attr('dy', '.35em')
          .style('text-anchor', 'start').text('CST Sollwert').style('fill', '#666')
          .style('font-weight', 'normal');
    }
    // legends end
    
    /**
     * highlighted data points start
     * @param data
     * @param r
     * @param color
     */
    function drawCircle(data, r, color) {
      let tooltip;
      tooltip = d3.select('#graph').append('div')
      .attr('class', 'tooltip').style('display', 'none');
      svg.selectAll('.dot').data(data).enter().append('circle') // Uses the enter().append() method
      .attr('class', 'circle_' + r).attr('cx', function(d) { return xScale(d['dailyDate']); })
      .attr('cy', function(d) {return yScale(d['dailyConsValue']); }).attr('r', r).attr('fill', color)
        .on( 'mouseover', function( d) {
          let arr, date;
          d3.select( this ).classed('circle circle__highlighted', true);
          d['active'] = true;
          tooltip.transition().duration(200).style('display', 'block');
          arr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
          date = arr[d['dailyDate'].getMonth()] + ', ' + d['dailyDate'].getFullYear();
          tooltip.html('Month ' + date + '<br/> Consumption- ' + d['dailyConsValue'] + ' unit')
          .style('left', (parseInt(this.getAttribute('cx'), 10) + 70) + 'px').style('top', (this.getAttribute('cy')) + 'px');
          /*tooltip.html('Month ' + date + '<br/> Consumption- ' + d['dailyConsValue'] + ' unit')
            .style('left', (d3.event.offsetX + 20) + 'px').style('top', (d3.event.offsetY - 28) + 'px');*/
      } ).on( 'mouseout', function( d ) {
            d3.selectAll('.circle').classed('circle', true).classed('circle__highlighted', false);
            d['active'] = false;
            tooltip.transition().duration(500).style('display', 'none');
      } );
    }
    // highlighted data points end
    }
    

    提前谢谢。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Aditya    8 年前

    在您的 style fill 只需创建一个函数并比较这两个值,然后根据如下条件返回颜色:

    svg.append('path')
       .data([drawData]).attr('class', 'area')
       .attr('d', area)
       .style('fill', function(d){
          for (i in d) {
            if (d[i]['dailyConsValue'] < d[i]['targetConsValue']) {
               return "green"
            } else {
               return "blue"
            }
       }
       })
       .transition().duration(2500)
       .attrTween( 'd', this.tween( drawData, area ) );
    

    这将仅基于数据的最后一个值。如果您希望根据您的情况在图表的每个点上使用不同的颜色,则必须创建 linearGradient 据我所知,有多个颜色停止(动态)。

    现在创建 线性渐变 ,我使用d3创建了一个线性比例,以计算颜色停止点的偏移,并根据您的条件指定颜色。动态创建 线性渐变 请参阅此 fiddle

    https://jsfiddle.net/aditya_kk29/gsy5dt8h/